#!/usr/bin/perl # simple write operation against waterkotte with control 'resümat cd4 (8126)' # (c) 2009 alexander.philipp.lintenhofer # use strict; use Device::SerialPort; use POSIX qw(floor); ##################################################################################################### if ($#ARGV != 1) { die "Usage: $0 (special case: $0 Zeit sync)\n"; } my $changeAttr = $ARGV[0]; my $changeVal = $ARGV[1]; use constant TYPE_UNDEF => 0; use constant TYPE_DATE => 1; use constant TYPE_TIME => 2; use constant TYPE_DATETIME => 3; use constant TYPE_DEC => 4; use constant TYPE_FLOAT1 => 5; use constant TYPE_FLOAT3 => 6; use constant TYPE_BIN => 7; use constant TYPE_BOOL => 8; use constant TYPE_SPECI => 9; use constant DLE => 0x10; use constant STX => 0x02; use constant ETX => 0x03; my @frame; our %wp_memory; ##################################################################################################### require('WPmemaddr.inc.pl'); require('WPhelperfunctions.inc.pl'); my $logfile = 'logs/wp_setval.log'; my $getValScript = 'WPgetVal.pl'; ##################################################################################################### open(STDOUT, ">>$logfile") || die "failed to re-open STDOUT to $logfile"; open(STDERR, ">&STDOUT") || die "failed to re-open STDERR to STDOUT"; ##################################################################################################### ##################################################################################################### # main # @frame = buildFrame($changeAttr,$changeVal); if ((scalar(@frame) > 10)) { for (my $attempt=0; $attempt<5;$attempt++) { if (my $serial = Device::SerialPort->new("/dev/ttyr00",0,'/tmp/wp_op.lock')) { $serial->baudrate(9600); $serial->parity("none"); $serial->databits(8); $serial->stopbits(1); $serial->write_settings || undef $serial; my $exitVal = 1; # frame contains bytes, but for serial-> write we need a string if (($serial->write(pack("C*",@frame)))==scalar(@frame)) { my @comdump; sleep 1; # expect FF 10 02 00 11 00 10 03 66 00 FF my ($count,$retVal) = $serial->read(11); if ($count > 0) { # we are sure that no 0xff appears in data section of frame for(my $i=0, my $currByte = ord(substr($retVal,0,1)); (($currByte == 255) || ($i < length($retVal))); $i++,$currByte = ord(substr($retVal,$i,1))) { $comdump[$i] = $currByte; } my @retVal = fetchFrameData(@comdump); if ((@retVal)&&(scalar(@retVal)==1)&&($retVal[0]==0)) { $exitVal = 0; } # success not sure... else { $serial->close() || print STDERR (localtime().": Close failed\n"); my $newVal = `$getValScript $changeAttr`; if ($changeVal == $newVal) { $exitVal = 0; } } if ($exitVal == 0) { print STDOUT (localtime().": $changeAttr = $changeVal\n"); } } else { print STDERR (localtime().": Received invalid frame\n"); } } else { print STDERR (localtime().": Error writing to rs232\n"); } $serial->close() || print STDERR (localtime().": tty already closed\n"); exit $exitVal; } sleep 4; } print STDERR (localtime().": Open of device failed\n"); exit 1; } else { print STDERR (" ".$changeAttr." not set to ".$changeVal."\n"); exit 1; } ##################################################################################################### ##################################################################################################### # functions # ##################################################################################################### ##################################################################################################### # buildFrame() # - builds command-frame according to selected attribute and value # sub buildFrame { my $changeAttr = $_[0]; my $changeVal = $_[1]; my @writeCmd = ($changeVal eq 'sync')?(0x01,0x14):(0x01,0x13); if ((defined($wp_memory{$changeAttr}))&&($wp_memory{$changeAttr}{acl} eq 'rw')) { ########################################################################################### # 1.) frame header, delimiter, start text @frame = (0xff,DLE,STX); ########################################################################################### # 2.) push(@frame,@writeCmd); ########################################################################################### # 3.) push(@frame,(hex2bytearray($wp_memory{$changeAttr}{addr},2))); ########################################################################################### # 4.) my @bytes; my $datatype = $wp_memory{$changeAttr}{type}; my $seize = $wp_memory{$changeAttr}{bytes}; my $minVal = (defined($wp_memory{$changeAttr}{minVal}))?$wp_memory{$changeAttr}{minVal}:0; my $maxVal = (defined($wp_memory{$changeAttr}{maxVal}))?$wp_memory{$changeAttr}{maxVal}:0; # special case: time sync # set $changeVal with results of localtime() if($changeVal eq 'sync') { my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time); if ($changeAttr eq 'Zeit') { $changeVal = sprintf("%02d",$day).'.'.sprintf("%02d",($month+1)).'.'.sprintf("%02d",($year-100)).','; $changeVal.= sprintf("%02d",$hour).':'.sprintf("%02d",$min).':'.sprintf("%02d",$sec); } else { print STDERR (localtime().": Sync only time (date and time)."); return 0; } } if ($datatype == TYPE_BOOL) { @bytes = ((int($changeVal)>0?1:0)); } elsif ($datatype == TYPE_DEC) { $changeVal = int($changeVal); if (($changeVal>=$minVal)&&($changeVal<=$maxVal)) { @bytes = ($changeVal); } else { print STDERR (localtime().": Value out of range [".$minVal."-".$maxVal."]."); return 0; } } elsif ($datatype == TYPE_FLOAT1) { $changeVal = sprintf("%0.1f", $changeVal); if (($changeVal>=$minVal)&&($changeVal<=$maxVal)) { @bytes = (hex2bytearray(hex(float2hex($changeVal)),$seize)); } else { print STDERR (localtime().": Value out of range [".$minVal."-".$maxVal."]."); return 0; } } elsif ($datatype == TYPE_DATETIME) { if ($changeVal =~ /^[0-3][0-9]\.[0,1][0-9]\.[0,1][0-9]\,[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/) { @bytes = (int(substr($changeVal,15,2)),int(substr($changeVal,12,2)),int(substr($changeVal,9,2))%24, int(substr($changeVal,0,2))%31,int(substr($changeVal,3,2)),int(substr($changeVal,6,2))); } else { print STDERR (localtime().": No valid format (dd.mm.yy,hh:mm:ss)."); return 0; } } else { print STDERR (localtime().": Missing type definition."); return 0; } # byte stuffing... my @stuffedBytes; for (my $i=0, my $j=0; $i=0;$i--) { $val += @$bytes[scalar(@$bytes)-1-$i]*(256**$i)." "; }; print hex2float1(sprintf("%08x", $val))."\n"; } print "[ "; foreach (@$frame) { printf("%02x ",$_) }; print "]\n"; }