Telnet クライアントから継続的な情報を抽出する

Telnet クライアントから継続的な情報を抽出する

インターフェースモジュールを介して生の値を提供する工業用センサーがありますtelnet

接続するには、次の手順に従ってください。

  telnet 169.254.168.150 10001

私はそれからゴミの値だけを見ることができます。

情報

私が持っている情報は、インターフェイスモジュールのデータシートからのものです。

センサーはアナログセンサーなので、Statusフラグは関係ありません。

データ型

私は、センサー情報を可視化することができる同社独自のソフトウェアを持っています。このソフトウェアは、上記のTelnetプロトコルを使用して情報を取得します。 WireSharkでクロスチェックしました。パケットサイズは、リトルエンディアンの順序で22バイトです。

Wireshark ダンプ

私の情報をプログラムで取得することはできません。SEクエリ値を得たいです。渡された値をどこか(データベースまたはファイル)に直接保存できます。

コマンドラインからこの情報を抽出する方法はありますか?

答え1

Pastebinから抽出された:

00000050  2e 0a 53 41 45 4d 00 00  00 00 f6 04 00 00 15 00  |..SAEM..........|
00000060  00 00 00 00 00 00 00 00  00 00 0c 00 01 00 fa 94  |................|
00000070  00 00 8c 00 00 00 8c 00  00 00 0a 23 00 00 53 41  |...........#..SA|
00000080  45 4d 00 00 00 00 f6 04  00 00 15 00 00 00 00 00  |EM..............|

したがって、これはすべての情報があり、リトルエンディアンなので、読んで解析するだけでよいことを示しています。あなたに慣れているどんなツールでも、Cプログラム、perlプログラムなど、あなたが望むすべてを行うことができます。telnet前の出力をスキップするか、代わりに別の出力を使用する必要があるかもしれませんtelnet(例えばnc、、、netcatsocat

デモンストレーションしてperlパケットをデコードするには、次の操作を行います。

cat ... | perl -nle "print join(':',unpack 'a4 (L2 Q L S2 l4)<')"

ダンプ内のパケットのコマンドラインから出力を取得します。

SAEM:0:1270:21:0:12:1:38138:140:140

これは、指定された数のチャネルに対してのみ機能します。マスクは、4つの測定のうちの1つがあってはならないことを示しますが、値があります。その部分を理解していません。

さまざまな情報に基づいてさまざまな数のチャネルを取得する場合は、よりスマートな解析が必要です。

答え2

だから私は明らかにその逆だと思います。 Wiresharkはデータをキャプチャしているので、すべてのパケットは(セッション開始情報)で、tcp最初の数個のパケットしかありません。telnet

私はPythonを使ってソケットを作成し、tcp22バイトのデータを読み取ることにしました(Wireshark Dumpで利用可能なサイズ)。

struct情報を取得するためにモジュールを使用してくださいunpack。有用なセンサ情報が常に代替TCPペイロードとして提供されるという事実は興味深い。つまり、最初のパケットには次の情報のみが含まれます。ヘッダー記事IDシリアル番号待って、次のペイロードにはすべての情報が含まれていますCounterチャンネル1の値チャンネル2の値チャンネル3の値

ここで得られた情報は、int32モジュールのマニュアルに記載されている式を使用して適切な値に変換する必要があります。

パスワード

import socket
import struct

# CONSTANTS for Formula
# ....

# 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):
""" Formula for conversion """
    return (((raw_val - DRANGEMIN) * MEASRANGE) / (DRANGEMAX - DRANGEMIN) + OFFSET)


if __name__ == '__main__':
    while True:
        Laser_Value = 0
        data = sock.recv(22)
        # First frame
        preamble, article, serial, x1, x2 = struct.unpack('<4sIIQH', data)

        # if this payload is not the preamble, it must be information payload
        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('\n')

関連情報