use Protocol.pm
authorDobrica Pavlinusic <dpavlin@rot13.org>
Mon, 21 Sep 2020 09:15:46 +0000 (11:15 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Mon, 21 Sep 2020 09:15:46 +0000 (11:15 +0200)
Protocol.pm
unpack.pl

index 1b378cc..fd162f6 100644 (file)
@@ -76,7 +76,7 @@ sub modbus_crc16 {
        return $trlr;
 }
 
-my $protocol;
+our $protocol;
 while(<DATA>) {
        chomp;
        next if m{^\s*$}; # skip empty lines
@@ -94,8 +94,6 @@ while(<DATA>) {
        };
 }
 
-warn "## protocol = ",dump( $protocol ) if $debug;
-
 sub read_parameter_frame {
        my $params = join('', @_);
 
index 9d9b622..2b93800 100755 (executable)
--- a/unpack.pl
+++ b/unpack.pl
@@ -4,91 +4,10 @@ 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,
-    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
-    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
-    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
-    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
-    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
-    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
-    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
-    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
-    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
-    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
-    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
-    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
-    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
-    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
-    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
-    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
-    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
-    0x00, 0xC1, 0x81, 0x40
-];
-# Table of CRC values for low order byte
-use constant CRC_LO => [
-    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5,
-    0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B,
-    0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,
-    0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
-    0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
-    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
-    0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8,
-    0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
-    0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21,
-    0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
-    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A,
-    0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
-    0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7,
-    0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51,
-    0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
-    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
-    0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D,
-    0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
-    0x41, 0x81, 0x80, 0x40
-];
-
-sub modbus_crc16 {
-       my ($msg) = @_;
-
-       my $crcl  = 0xFF;
-       my $crch  = 0xFF;
-       my @bytes = split(//, $msg);
-       for (@bytes) {
-               my $data = unpack('C*', $_);
-               my $crcIdx = $crcl ^ $data;
-               $crcl = $crch ^ &CRC_HI->[$crcIdx];
-               $crch = &CRC_LO->[$crcIdx];
-       }
-       # Pack the trailer - CRC has low byte first
-       my $trlr = pack('CC', $crcl, $crch);
-
-       return $trlr;
-}
-
+use lib '.';
+use Protocol;
 
-my $protocol;
-while(<DATA>) {
-       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+.*$//;
-       $protocol->{$id} = {
-               description => $a[1],
-               pack_fmt => $pack_fmt,
-               r_w => $a[3],
-               range => $a[4],
-               default => $a[5],
-               remark => $a[6],
-               line => [ @a ],
-       };
-}
+my $debug = $ENV{DEBUG};
 
 warn "## protocol = ",dump( $protocol ) if $debug;
 
@@ -153,13 +72,13 @@ while ( $data ) {
        warn "XXX data = $hex\n";
 
        my $data_id = unpack( 'C', substr($data,0,1) );
-       my $data_id_desc = $protocol->{$data_id}->{description};
-       if ( ! $data_id_desc ) {
+       if ( ! exists( $protocol->{$data_id}->{description} ) ) {
                my $len = unpack('C', substr($data,1,1));
                printf "ERROR: no description for data_id %d 0x%2x len %d SKIPPING!\n", $data_id, $data_id, $len;
                $data = substr($data,2 + $len);
                next;
        }
+       my $data_id_desc = $protocol->{$data_id}->{description};
        my $pack_fmt = $protocol->{$data_id}->{pack_fmt} || die "can't find pack_fmt for data_id $data_id";
 
        my $data_range;
@@ -253,43 +172,3 @@ if ( $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 
-
-__DATA__
-0x00   Seq #                           l DWord(4)      R       /               0       The platform can carry the ID when the platform downstream reads and sets the device parameters, and the device returns the same data. Please refer to the example for use.Each seq # refer to one command and its response. 
-0x01   PN                              l DWord(4)      R       /                /      / 
-0x02   Model                           C Byte(1)       R       32              32      Inner number:32 
-0x03   X axis angle                    f Float(4)      R        ‐90°~90°   /       X axis angle 
-0x04   Y axis angle                    f Float(4)      R       ‐90°~90°    /       Y axis angle 
-0x09   X axis relative angle           f Float(4)      R       ‐90°~90°    0       Return the X angle value according to the set relative zero 
-0x0A   Y axis relative angle           f Float(4)      R       ‐90°~90°    0       Return the Y angle value according to the set relative zero 
-0x0C   Sensor temperature              s Word(2)       R       ‐32768~32767  /       signed,sensor temperature =Data/100, unit ℃ 
-0x0D   Power source voltage            S Word(2)       R       0~65535         /       Voltage= Data/100, unit V 
-0x11   Arming/disarming                C Byte(1)       R/W     0~255           1       0 means disarming, non‐zero means arming 
-0x12   Alarm delay time                C Byte(1)       R/W     3~255           20       The unit is 0.1 second, which means that the product responds to the alarm only after the alarm has exceeded the alarm angle for a certain period of time. 
-
-0x13   Restore factory setting         C Byte(1)       R/W     0~255           0       0: Do nothing Non‐zero: Restore the non‐network‐related parameters of the sensor. 
-0x14   Server IP&port                  CCCCs 4*Byte(1)+Word(2) R/W             /       CTIOT:117.60.157.137,5683 MQTT:0.0.0.0,0        The server address should be IP, not the domain name; using the domain name may cause the connection server to be unstable and cause data loss.
-0x17   Signal strength                 C Byte(1)       R       10~34           /       A larger value indicates a stronger signal 
-0x18   Sensor operating mode           C Byte(1)       R/W     0               0       The sensor can only work in absolute measurement mode 
-0x19   Alarm axis                      C Byte(1)       R       0~3             /       0: no alarm; 1: X‐axis alarm 2: Y axis alarm; 3: X/Y axis alarm at the same time 
-0x1A   SIM card ID                     Q QWord(8)      R       0~18446744073709551615  /       Take the first 19 digits, the last digit is discarded 
-0x21   Heartbeat interval              l DWord(4)      R/W     60~131071       86400   Interval at which the device periodically uploads data to the server 
-0x22   IMEI number of the device       Q QWord(8)       R      0~18446744073709551615  /       Refers to the IMEI of the NB‐IOT network module in the product. 
-0x23   Backup server IP&port           CCCCs 4*Byte(1)+Word(2) R/W     /       CTIOT:117.60.157.137,5683 MQTT:0.0.0.0,0        / 
-0x24   Backup server enable            C Byte(1)       R/W     0~255   0       0 means off, non‐zero means on 
-0x33   DNS IP address                  CCCC 4*Byte(1)  R/W     /       208.67.222.222  / 
-0x34   Domain name and port            a* 64*Byte(1)   R/W     /       mqtt.zc‐sensor.com,1883       Supports CTIOT and MQTT protocols. Priority IP in the case of IP (ID number 0x14); domain name and port should be separated with comma, length <=64 
-0x35   MQTT‐ClientID                         a* 32*Byte(1)   R/W      /      IMEI number of the device       Length <=32, subject to MQTT related specifications 
-0x36   MQTT‐Username                         a* 32*Byte(1)   R/W     /       empty           Length <=32, subject to MQTT related specifications 
-
-0x37   MQTT‐Password                         a* 32*Byte(1)   R/W     /       empty           Length <=32, subject to MQTT related specifications 
-0x38   MQTT‐published topic name     a* 128*Byte(1)  R/W     /       Inclinometer/ZCT330Mx_SWP_N_YK/IMEI/up  Length <=128, subject to MQTT related specifications 
-0x39   MQTT‐subscribed topic name    a* 128*Byte(1)  R/W     /       Inclinometer/ZCT330Mx_SWP_N_YK/IMEI/down        Length <=128, subject to MQTT related specifications 
-0x3A   Set relative zero command       C Byte(1)       R/W     0~255   0               0: absolute angle mode 1: Set the current position to zero, relative angle mode (0x09, 0x0A content will be set to the current angle), Other values are invalid. 
-0x3B   Backup server domain name and port      a* 64*Byte(1)   R/W     /       mqtt.zc‐sensor.com,1883       Supports CTIOT and MQTT protocols. In the case of backup IP, the IP is preferentially backed up; the domain name and port are distinguished by commas, and the length is <=64. 
-0x3D   Protocol type                   C Byte(1)       R/W     0~255   CTIOT   0:CTIOT 1:MQTT Other values are invalid. 
-0x44   Alarm angle                     f Float(4)      R/W     ‐90°~90°    3°     X/Y axis alarm angle is consistent 
-