##################################################################################################### ##################################################################################################### # helper functions for wp_monitor backend in common use # (c) 2009 alexander.philipp.lintenhofer # ##################################################################################################### # fetchFrameData(): # - isolates raw data from frame # frame format: 'FF' DLE STX DLE ETX 'FF' # DATA ::= # READ ::= '00 17' XX..XX - bytes # - checks crc16 sub fetchFrameData { my @frame = @_; my $crc1 = sprintf("%02x%02x",@frame[(scalar(@frame)-3)],@frame[(scalar(@frame)-2)]); my $crc2 = sprintf("%04x",GetCRC16(@frame)); if ($crc1 eq $crc2) { my $headerbytes = 5; # strip 'FF' DLE STX '00 17' my $trailerbytes = 5; # strip DLE ETX 'FF' my @data; for(my $i=0,my $offset=$headerbytes;$offset<(scalar(@frame)-$trailerbytes);$offset++,$i++) { if (($frame[$offset]==16)&&($frame[$offset+1]==16)) { $offset++; } $data[$i] = $frame[$offset]; } return @data; } else { print STDERR (localtime().": checksum error (frame:0x".$crc1.", calculated:0x".$crc2."): "); foreach (@frame) { printf(STDERR "%02x ",$_); } print STDERR "\n"; return (); } } ##################################################################################################### # createXML() # - formats %yield to XML-structure # - in this file since early declaration for the prototype check is needed # sub createXML() { my @dateVal = split('-',$yield{'05.01'}{'val'}); my @timeVal = split(':',$yield{'05.00'}{'val'}); my $tsp = mktime($timeVal[2],$timeVal[1],$timeVal[0],$dateVal[2],($dateVal[1]-1),($dateVal[0]+100),0,0,-1); my $xml = "\n"; $xml .= "\t".$tsp."\n"; foreach (sort keys %yield) { my $menuentry = $_; my $name = $yield{$_}{'desc'}; $name =~ s/\/>\;/; $menuentry =~ s/(\d\d)(\.)(\d\d)/m_$1$3/; $xml .= "\t<".$menuentry." name='".$name."'>".$yield{$_}{'val'}.'\n"; } $xml .= "\n\n"; return $xml; } ##################################################################################################### # hex2float() sub hex2float1 { my $h = $_[0]; $h = substr($h,6,2).substr($h,4,2).substr($h,2,2).substr($h,0,2); return sprintf("%0.1f",unpack("f", pack("I", hex($h)))); } sub hex2float3 { my $h = $_[0]; $h = substr($h,6,2).substr($h,4,2).substr($h,2,2).substr($h,0,2); return sprintf("%0.3f",unpack("f", pack("I", hex($h)))); } ##################################################################################################### # float2hex() sub float2hex { my $f = $_[0]; return unpack("H8",pack("f",$f)); } ##################################################################################################### # hex2bytearray(): returns array with bytes from given hexword sub hex2bytearray { my $word = $_[0]; my $bytes = $_[1]; my @arr; # shift right... for($i=0;$i<$bytes;$i++,$word>>=8) { @arr[($bytes-$i-1)] = $word & 0xFF;} return @arr; } ##################################################################################################### # GetCRC16(): calculate crc16 sub GetCRC16 { # strip header ('FF' DLE STX)... # and trailer (DLE ETX 'FF') my @data = @_[3..(scalar(@_)-6)]; # fill checksum-fields with 0x00 $data[++$#data] = 0x00; $data[++$#data] = 0x00; my $CRCinit = 0x0000; my $CRCpoly = 0x8005; my $CRCreg = $CRCinit << 8; my $PLYreg = $CRCpoly << 8; for (my $i=0; $i < scalar(@data); $i++) { $CRCreg |= $data[$i]; for (my $bp=0; $bp<8; $bp++) { $CRCreg <<= 1; if ($CRCreg & 0x1000000) { $CRCreg ^= $PLYreg; } $CRCreg &= 0xffffff; } } return $CRCreg >> 8; } 1;