인터페이스 모듈을 통해 원시 값을 제공하는 산업용 센서가 있습니다 telnet
.
연결하려면 다음 단계를 따르세요.
telnet 169.254.168.150 10001
나는 그것에서 쓰레기 값만 볼 수 있습니다.
정보
내가 가지고 있는 정보는 인터페이스 모듈의 데이터시트에서 나온 것입니다.
센서는 아날로그 센서이므로 Status
플래그는 관련이 없습니다.
저는 센서 정보를 시각화할 수 있는 이 회사의 독점 소프트웨어를 가지고 있습니다. 이 소프트웨어는 위에서 언급한 텔넷 프로토콜을 사용하여 정보를 얻습니다. WireShark를 통해 교차 확인했습니다. 패킷 크기는 리틀 엔디안 순서로 22바이트입니다.
내 정보를 프로그래밍 방식으로 가져올 수 없습니다.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
: , netcat
, socat
).
시연하고 perl
패킷을 디코딩하려면 다음과 같은 작업을 수행합니다.
cat ... | perl -nle "print join(':',unpack 'a4 (L2 Q L S2 l4)<')"
덤프에 있는 패킷의 명령줄에서 출력을 얻습니다.
SAEM:0:1270:21:0:12:1:38138:140:140
이는 지정된 수의 채널에 대해서만 작동합니다. 마스크는 4개 측정 중 하나가 없어야 함을 나타내지만 값이 있습니다. 해당 부분을 이해하지 못합니다.
다른 정보를 기반으로 다양한 수의 채널을 얻는 경우 더 스마트한 구문 분석이 필요합니다.
답변2
그래서 나는 분명히 그 반대라고 생각합니다. Wireshark에서 데이터를 캡처하고 있으므로 모든 패킷은 (세션 시작 정보) tcp
이고 처음 몇 개의 패킷만 있습니다.telnet
나는 Python을 사용하여 소켓을 만들고 tcp
22바이트의 데이터를 읽기로 결정했습니다(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')