X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=unpack.pl;h=1e04e2dd7b7a88bf3b502ffb44acb8947edc50d3;hb=2d02ea94587bfb1be0a3d5c7b8b592f52dbcd124;hp=51a37864c327c6dc3d0fb4068cd3edd33c8273fa;hpb=a3e902ae6a6d0a39beb01c77701932bb508cfa6d;p=zc diff --git a/unpack.pl b/unpack.pl index 51a3786..1e04e2d 100755 --- a/unpack.pl +++ b/unpack.pl @@ -4,6 +4,8 @@ use strict; use Data::Dump qw(dump); +my $debug = $ENV{DEBUG}; + # Table of CRC values for high order byte use constant CRC_HI => [ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, @@ -73,6 +75,7 @@ sub modbus_crc16 { my $protocol; while() { chomp; + next if m{^\s*$}; # skip empty lines my @a = split(/\s*\t\s*/, $_,7); my $id = hex( $a[0] ); my $pack_fmt = $a[2]; $pack_fmt =~ s/\s+.*$//; @@ -87,49 +90,26 @@ while() { }; } -warn "## protocol = ",dump( $protocol ); - - -my @raw; +warn "## protocol = ",dump( $protocol ) if $debug; -#Publish/at-most-once,retain Inclinometer/ZCT330Ex_SWP_N_YK/869858035167585/up -push @raw, qq{ - 5a 0c 08 29 00 01 04 55 79 fb 71 02 01 10 03 04 Z..)...Uy.q..... - 00 00 df c1 04 04 75 93 6c c1 0c 02 49 0a 0d 02 ......u.l...I... - 61 01 11 01 01 17 01 12 18 01 01 19 01 03 48 5d a.............H] -}; - -#Publish/at-most-once,retain Inclinometer/ZCT330Ex_SWP_N_YK/869858031634109/up -push @raw, qq{ - 5a 0c 07 29 00 01 04 00 00 00 00 02 01 10 03 04 Z..)............ - df 4f ad 3f 04 04 d1 22 4b c0 0c 02 c2 14 0d 02 .O.?..."K....... - 41 01 11 01 01 17 01 16 18 01 01 19 01 00 a8 b9 A............... -}; -#Publish/at-most-once,retain Inclinometer/ZCT330Ex_SWP_N_YK/864823041482779/up -push @raw, qq| - 5a 0c 08 29 00 01 04 00 00 00 00 02 01 10 03 04 Z..)............ - db f9 3e 3f 04 04 b2 9d 6f be 0c 02 b7 10 0d 02 ..>?....o....... - 48 01 11 01 01 17 01 1a 18 01 01 19 01 03 7d 2c H.............}, -|; -#Publish/at-most-once,retain Inclinometer/ZCT330Ex_SWP_N_YK/864823041482498/up -push @raw, qq{ - 5a 0c 08 29 00 01 04 e3 b1 a0 77 02 01 10 03 04 Z..)......w..... - 02 2b 87 be 04 04 27 31 e8 c1 0c 02 bd 0b 0d 02 .+....'1........ - 45 01 11 01 01 17 01 16 18 01 01 19 01 02 2a 69 E.............*i -}; +my $pkg_nr = 0; -my $raw_nr = shift @ARGV || 0; -my $raw = $raw[$raw_nr]; -$raw =~ s/ \S{16}\n//gs; -$raw =~ s/^\s+//; -my $up_down = 'up'; +sub protocol_decode { + my ( $up_down, $hex ) = @_; -warn "up/down: $up_down raw = ",dump($raw); +warn "up/down: $up_down hex = ",dump($hex); -my $bin = join('', map { chr(hex($_)) } split(/\s+/,$raw)); +my $bin = join('', map { chr(hex($_)) } split(/\s+/,$hex)); warn "bin = ", dump($bin); +if ( $debug ) { + open(my $dump, '>', "/dev/shm/zc.$pkg_nr.$up_down"); + print $dump $bin; + close($dump); + $pkg_nr++; +} + my $cksum = substr($bin, -2, 2); if ( my $crc = modbus_crc16( substr($bin,0,-2) ) ) { @@ -173,13 +153,21 @@ while ( $data ) { warn "XXX data = $hex\n"; my $data_id = unpack( 'C', substr($data,0,1) ); - my $data_id_desc = $protocol->{$data_id}->{description} || die "can't find description for data_id $data_id"; + my $data_id_desc = $protocol->{$data_id}->{description}; + if ( ! $data_id_desc ) { + warn "ERROR: no description for data_id $data_id SKIPPING!"; + $data = substr($data,1); + next; + } my $pack_fmt = $protocol->{$data_id}->{pack_fmt} || die "can't find pack_fmt for data_id $data_id"; my $data_range; if ( $data_id == 0x00 ) { - warn "FIXME seq number?"; + # sequence number + + $data_range = substr($data,2,4); + $data = substr($data,6); } elsif ( $up_down eq 'down' && $function_code == 0x03 ) { # type A @@ -224,9 +212,46 @@ while ( $data ) { } my $description = $protocol->{$data_id}->{description} || die "can't find description for data_id $data_id"; - print "$up_down | $data_id | $description | hex:", unpack('H*', $data_range), " fmt:$pack_fmt [v=$v] range:",$protocol->{$data_id}->{range}, " remark:", $protocol->{$data_id}->{remark},"\n"; + print "$up_down | $data_id | $description | v=$v | hex:", unpack('H*', $data_range), " fmt:$pack_fmt | range:",$protocol->{$data_id}->{range}, " | remark:", $protocol->{$data_id}->{remark},"\n"; } + +} # protocol_decode + +my $raw; +my ( $timestamp, $sensor, $imei, $up_down ); +my $stat; +while(<>) { + chomp; + + if ( m{^(\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d).*Inclinometer/([^/]+)/([^/]+)/(\w+)} ) { + if ( $raw ) { + $raw =~ s{^\s+}{}; # strip leading spaces + print "## $timestamp $sensor $imei $up_down $raw\n"; + protocol_decode( $up_down, $raw ); + $raw = ''; + } + ( $timestamp, $sensor, $imei, $up_down ) = ( $1, $2, $3, $4 ); + $stat->{$sensor}->{$imei}->{$up_down}++; + } elsif ( m{^\s+} ) { + s/\s\s\S\S\S+//g; # remove ascii + s/^\s+/ /; + $raw .= $_; + warn "++ $_\n"; + } else { + warn "IGNORE: $_\n"; + } + +} + +if ( $raw ) { + $raw =~ s{^\s+}{}; # strip leading spaces + print "## $timestamp $sensor $imei $up_down $raw\n"; + protocol_decode( $up_down, $raw ); +} + +print "stat = ",dump($stat), "\n"; + # 6. Protocol Format # Valid data ID and parameter range supported by the product # DATA ID ID Description Data Type( Data Length) R/W Range Default Remark