代码之家  ›  专栏  ›  技术社区  ›  Shan-Desai askovpen

无法在Python中的自定义前导和telnetlib之间解压缩信息

  •  0
  • Shan-Desai askovpen  · 技术社区  · 6 年前

    我有一个工业传感器,它通过 telnet 越过港口 10001

    Data Format 详情如下:

    Table Data Format

    手册还包括:

    根据传感器的不同,所有测量值通过int32或uint32或float传输

    代码

    import telnetlib
    import struct
    import time
    
    # IP Address, Port, timeout for Telnet
    tn = telnetlib.Telnet("169.254.168.150", 10001, 10)
    
    
    while True:
        op = tn.read_eager() # currently read information limit this till preamble
        print(op[::-1]) # make little-endian
        if not len(op[::-1]) == 0: # initially an empty bit starts (b'')
            data = struct.unpack('!4c', op[::-1]) # unpacking `MEAS`
        time.sleep(0.1)
    

    1. 连接到传感器

    2. 读取数据

    3. 去小恩迪安

    b''
    b'MEAS\x85\x8c\x8c\x07\xa7\x9d\x01\x0c\x15\x04\xf6MEAS'
    b'\x04\xf6MEAS\x86\x8c\x8c\x07\xa7\x9e\x01\x0c\x15\x04\xf6'
    b'\x15\x04\xf6MEAS\x85\x8c\x8c\x07\xa7\x9f\x01\x0c\x15'
    b'\x15\x04\xf6MEAS\x87\x8c\x8c\x07\xa7\xa0\x01\x0c'
    b'\xa7\xa2\x01\x0c\x15\x04\xf6MEAS\x87\x8c\x8c\x07\xa7\xa1\x01\x0c'
    b'\x8c\x07\xa7\xa3\x01\x0c\x15\x04\xf6MEAS\x87\x8c\x8c\x07'
    b'\x88\x8c\x8c\x07\xa7\xa4\x01\x0c\x15\x04\xf6MEAS\x88\x8c'
    b'MEAS\x8b\x8c\x8c\x07\xa7\xa5\x01\x0c\x15\x04\xf6MEAS'
    b'\x04\xf6MEAS\x8b\x8c\x8c\x07\xa7\xa6\x01\x0c\x15\x04\xf6'
    b'\x15\x04\xf6MEAS\x8a\x8c\x8c\x07\xa7\xa7\x01\x0c\x15'
    b'\x15\x04\xf6MEAS\x88\x8c\x8c\x07\xa7\xa8\x01\x0c'
    b'\x01\x0c\x15\x04\xf6MEAS\x88\x8c\x8c\x07\xa7\xa9\x01\x0c'
    b'\x8c\x07\xa7\xab\x01\x0c\x15\x04\xf6MEAS\x8b\x8c\x8c\x07\xa7\xaa'
    b'\x8c\x8c\x07\xa7\xac\x01\x0c\x15\x04\xf6MEAS\x8c\x8c'
    b'AS\x89\x8c\x8c\x07\xa7\xad\x01\x0c\x15\x04\xf6MEAS\x8a'
    b'MEAS\x88\x8c\x8c\x07\xa7\xae\x01\x0c\x15\x04\xf6ME'
    b'\x15\x04\xf6MEAS\x87\x8c\x8c\x07\xa7\xaf\x01\x0c\x15\x04\xf6'
    b'\x15\x04\xf6MEAS\x8a\x8c\x8c\x07\xa7\xb0\x01\x0c'
    b'\x0c\x15\x04\xf6MEAS\x8a\x8c\x8c\x07\xa7\xb1\x01\x0c'
    b'\x07\xa7\xb3\x01\x0c\x15\x04\xf6MEAS\x89\x8c\x8c\x07\xa7\xb2\x01'
    b'\x8c\x8c\x07\xa7\xb4\x01\x0c\x15\x04\xf6MEAS\x89\x8c\x8c'
    b'\x85\x8c\x8c\x07\xa7\xb5\x01\x0c\x15\x04\xf6MEAS\x84'
    b'MEAS\x87\x8c\x8c\x07\xa7\xb6\x01\x0c\x15\x04\xf6MEAS'
    b'\x04\xf6MEAS\x8b\x8c\x8c\x07\xa7\xb7\x01\x0c\x15\x04\xf6'
    b'\x15\x04\xf6MEAS\x8b\x8c\x8c\x07\xa7\xb8\x01\x0c\x15'
    b'\x15\x04\xf6MEAS\x8a\x8c\x8c\x07\xa7\xb9\x01\x0c'
    b'\xa7\xbb\x01\x0c\x15\x04\xf6MEAS\x87\x8c\x8c\x07\xa7\xba\x01\x0c'
    

    我如何阅读这样的信息 Article number , Serial number , Channel , Status , Measuring Value

    这里的有效负载大小似乎固定为22字节(通过Wireshark)

    Wireshark Picture

    2 回复  |  直到 6 年前
        1
  •  1
  •   J_H    6 年前

    解析反向缓冲区只是简单的 奇怪的 struct 她对Endianness的支持。使用big-endian“!”在一个小小的endian上下文中,这也很奇怪。

    请给我那些。

    之后,使用 struct.unpack 'IIQI' . 到目前为止,您的方法还可以正常工作,因为所有字段都消耗4个字节或一对4个字节。但是找到帧M的长度是美中不足的,因为它只有2个字节,所以用 'H' 'IIQIH' . 在这之后,您只需要前进那么多字节,然后在用完该组度量值后,期望另一个“MEAS”文本常量。

        2
  •  0
  •   Shan-Desai askovpen    6 年前

    我设法避免了 TelnetLib tcp 客户端使用 python3 显然,模块发送两个不同的22字节有效负载

    1. 第一个(帧)有效负载具有 preamble , serial , article , channel 信息
    2. bytes per frame , measuring value counter , measuring value Channel 1 measuring value Channel 2 measuring value Channel 3

    信息是在 int32

    代码

    import socket
    import time
    import struct
    
    DRANGEMIN = 3261
    DRANGEMAX = 15853
    MEASRANGE = 50
    OFFSET = 35
    
    # Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server_address = ('169.254.168.150', 10001)
    print('connecting to %s port %s' % server_address)
    sock.connect(server_address)
    
    
    def value_mm(raw_val):
    
        return (((raw_val - DRANGEMIN) * MEASRANGE) / (DRANGEMAX - DRANGEMIN) + OFFSET)
    
    
    if __name__ == '__main__':
        while True:
            Laser_Value = 0
            data = sock.recv(22)
            preamble, article, serial, x1, x2 = struct.unpack('<4sIIQH', data)
            if not preamble == b'SAEM':
                status, bpf, mValCounter, CH1, CH2, CH3 = struct.unpack('<hIIIII',data)
                #print(CH1, CH2, CH3)
                Laser_Value = CH3
                print(str(value_mm(Laser_Value)) + " mm")
    
            #print('RAW: ' + str(len(data)))
            print('\n')
            #time.sleep(0.1)