| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- # $Id: 44_S7_Client.pm 14257 2017-05-12 16:39:44Z charlie71 $
- ##############################################
- use strict;
- use warnings;
- require Exporter;
- use Config;
- use AutoLoader;
- #todo fix timeout in ms
- our @ISA = qw(Exporter);
- our %EXPORT_TAGS = (
- 'all' => [
- qw(
- S7AreaPE
- S7AreaPA
- S7AreaMK
- S7AreaDB
- S7AreaCT
- S7AreaTM
- )
- ]
- );
- our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
- our @EXPORT = qw(
- S7AreaPE
- S7AreaPA
- S7AreaMK
- S7AreaDB
- S7AreaCT
- S7AreaTM
- );
- #Base class for S7 and S5 Connections
- package S7ClientBase;
- # S7 ID Area (Area that we want to read/write)
- use constant S7AreaPE => 0x81;
- use constant S7AreaPA => 0x82;
- use constant S7AreaMK => 0x83;
- use constant S7AreaDB => 0x84;
- use constant S7AreaCT => 0x1C;
- use constant S7AreaTM => 0x1D;
- sub new {
- my $class = shift;
- my $self = {
- Connected => 0, # = false
- PDULength => 0,
- MaxReadLength => 0,
- RecvTimeout => 500, # 500 ms
- };
- return bless $self, $class;
- }
- #-----------------------------------------------------------------------------
- sub DESTROY {
- my $self = shift;
- $self->Disconnect();
- }
- #-----------------------------------------------------------------------------
- sub Connect {
- my ($self) = @_;
- return 0;
- }
- #-----------------------------------------------------------------------------
- sub Disconnect {
- my ($self) = @_;
- if ( $self->{Connected} ) {
- $self->{Connected} = 0;
- $self->{PDULength} = 0;
- $self->{MaxReadLength} = 0;
- $self->{LastError} = 0;
- }
- }
- #-----------------------------------------------------------------------------
- sub ReadArea () {
- }
- #-----------------------------------------------------------------------------
- sub WriteArea {
- }
- #-----------------------------------------------------------------------------
- sub getPLCDateTime() {
- }
- #-----------------------------------------------------------------------------
- sub BitAt {
- my ( $self, $Buffer, $ByteIndex, $BitIndex ) = @_;
- return 0 if ( $BitIndex > 7 );
- my @mask = ( 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 );
- my @myBuffer = unpack( "C" x $ByteIndex + 1, $Buffer );
- return 1 if ( ( $myBuffer[$ByteIndex] & $mask[$BitIndex] ) != 0 );
- return 0;
- }
- #-----------------------------------------------------------------------------
- sub ByteAt {
- my @myBuffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $myBuffer[$index];
- }
- #-----------------------------------------------------------------------------
- sub WordAt {
- my @myBuffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- my $hi = $myBuffer[$index] << 8;
- return ( $hi + $myBuffer[ $index + 1 ] );
- }
- #-----------------------------------------------------------------------------
- sub DWordAt {
- my @myBuffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- my $dw1;
- $dw1 = $myBuffer[$index] << 8;
- $dw1 = ( $dw1 + $myBuffer[ $index + 1 ] ) << 8;
- $dw1 = ( $dw1 + $myBuffer[ $index + 2 ] ) << 8;
- $dw1 = ( $dw1 + $myBuffer[ $index + 3 ] );
- return $dw1;
- }
- #-----------------------------------------------------------------------------
- sub FloatAt {
- my @myBuffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- my @bytes = (
- $myBuffer[$index],
- $myBuffer[ $index + 1 ],
- $myBuffer[ $index + 2 ],
- $myBuffer[ $index + 3 ]
- );
- if ( $Config::Config{byteorder} =~ /^1/ )
- { #take care of the machines byte order
- return unpack( 'f', pack( 'C4', reverse @bytes ) );
- }
- return unpack( 'f', pack( 'C4', @bytes ) );
- }
- #-----------------------------------------------------------------------------
- sub ShortAt {
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- # my ( $self, $Buffer, $index ) = @_;
- my $b = $self->ByteAt( \@Buffer, $index );
- if ( ( $b & 0x80 ) != 0 ) {
- return -( ( ~$b & 0xff ) + 1 );
- }
- return $b;
- }
- #-----------------------------------------------------------------------------
- sub IntegerAt {
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- # my ( $self, $Buffer, $index ) = @_;
- # my $w = $self->WordAt( $Buffer, $index );
- my $w = $self->WordAt( \@Buffer, $index );
- return ( $w & 0x8000 ) ? -( ( ( ~$w ) & 0xffff ) + 1 ) : $w;
- }
- #-----------------------------------------------------------------------------
- sub DintAt {
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- my $dw = $self->DWordAt( \@Buffer, $index );
- # my ( $self, $Buffer, $index ) = @_;
- # my $dw = $self->DWordAt( $Buffer, $index );
- return ( $dw & 0x80000000 ) ? -( ( ~$dw & 0xffffffff ) + 1 ) : $dw;
- }
- #-----------------------------------------------------------------------------
- sub GetU8from {
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->ByteAt( \@Buffer, $index );
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->ByteAt( $Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetS8from {
- # my ( $self, $Buffer, $index ) = @_;
- # return ShortAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->ShortAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetU16from {
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->WordAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->WordAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetS16from {
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->IntegerAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->IntegerAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetU32from {
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->DWordAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->DWordAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetS32from {
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->DintAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->DintAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub GetFloatfrom {
- # my ( $self, $Buffer, $index ) = @_;
- # return $self->FloatAt( $Buffer, $index );
- my $self = $_[0];
- my @Buffer = @{ $_[1] }; # ersten Parameter dereferenzieren
- my $index = $_[2];
- return $self->FloatAt( \@Buffer, $index );
- }
- #-----------------------------------------------------------------------------
- sub setByteAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- my @myBuffer = unpack( "C" x length($Buffer), $Buffer );
- $myBuffer[$index] = $value % 256;
- return pack( "C" x length($Buffer), @myBuffer );
- }
- #-----------------------------------------------------------------------------
- sub setWordAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- my @myBuffer = unpack( "C" x length($Buffer), $Buffer );
- $myBuffer[$index] = $value >> 8;
- $myBuffer[ $index + 1 ] = $value % 256;
- return pack( "C" x length($Buffer), @myBuffer );
- }
- #-----------------------------------------------------------------------------
- sub setDWordAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- my @myBuffer = unpack( "C" x length($Buffer), $Buffer );
- $myBuffer[ $index + 3 ] = $value % 256;
- $value = $value >> 8;
- $myBuffer[ $index + 2 ] = $value % 256;
- $value = $value >> 8;
- $myBuffer[ $index + 1 ] = $value % 256;
- $value = $value >> 8;
- $myBuffer[$index] = $value % 256;
- return pack( "C" x length($Buffer), @myBuffer );
- }
- #-----------------------------------------------------------------------------
- sub setFloatAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- my @myBuffer = unpack( "C" x length($Buffer), $Buffer );
- my @bytes = unpack( 'C4', pack( 'f', $value ) );
- if ( $Config::Config{byteorder} =~ /^1/ )
- { #take care of the machines byte order
- $myBuffer[$index] = $bytes[3];
- $myBuffer[ $index + 1 ] = $bytes[2];
- $myBuffer[ $index + 2 ] = $bytes[1];
- $myBuffer[ $index + 3 ] = $bytes[0];
- }
- else {
- $myBuffer[$index] = $bytes[0];
- $myBuffer[ $index + 1 ] = $bytes[1];
- $myBuffer[ $index + 2 ] = $bytes[2];
- $myBuffer[ $index + 3 ] = $bytes[3];
- }
- return pack( "C" x length($Buffer), @myBuffer );
- }
- #-----------------------------------------------------------------------------
- sub setShortAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- $value = ( ( ~( -$value ) ) & 0xff ) + 1 if ( $value < 0 );
- return $self->setByteAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub setIntegerAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- $value = ( ( ~( -$value ) ) & 0xffff ) + 1 if ( $value < 0 );
- return $self->setWordAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub setDintAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- $value = ( ( ~( -$value ) ) & 0xffffffff ) + 1 if ( $value < 0 );
- return $self->setDWordAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub Put8At {
- my ( $self, $Buffer, $index, $value ) = @_;
- return $self->setByteAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub Put16At {
- my ( $self, $Buffer, $index, $value ) = @_;
- return $self->setIntegerAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub Put32At {
- my ( $self, $Buffer, $index, $value ) = @_;
- return $self->setDintAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub PutFloatAt {
- my ( $self, $Buffer, $index, $value ) = @_;
- return $self->setFloatAt( $Buffer, $index, $value );
- }
- #-----------------------------------------------------------------------------
- sub setRecvTimeout {
- my ( $self, $newRecvTimeout ) = @_;
-
- $self->{RecvTimeout} = $newRecvTimeout;
- }
- #-----------------------------------------------------------------------------
- sub version {
- return "1.1";
- }
- #-----------------------------------------------------------------------------
- sub getErrorStr {
- }
- 1;
- =pod
- =item summary abstract interface layer S7 / S5
- =item summary_DE abstract interface layer S7 / S5
- =begin html
- <p><a name="S7_Client"></a></p>
- <h3>S7_Client</h3>
- <ul>
- <ul>abstract interface layer S7 / S5</ul>
- </ul>
- =end html
- =begin html_DE
- <p><a name="S7_Client"></a></p>
- <h3>S7_Client</h3>
- <ul>
- <ul>abstract interface layer S7 / S5</ul>
- </ul>
- =end html_DE
- =cut
|