我想使用 socat 将串行命令通过以太网定向到以太网串行转换器(静态 IP 地址)。我想知道启动 socat 的好方法是什么。
据我了解,systemd 将允许我确保 socat 始终运行 – 或者在发生故障时尝试重新启动。 .service 文件如下所示:
[Service]
Type=simple
Restart=always
RestartSec=5
[Unit]
Description=my socat test
User=me
Group=me
ExecStart=/bin/bash -c '~/my_socat.sh'
[Install]
WantedBy=multi-user.target
该脚本如下所示:
#!/bin/bash
socat PTY,link=/home/me/dev/valve1 TCP:192.168.11.101:5001 & socat PTY,link=/home/me/dev/valve2 TCP:192.168.11.101:5002
这种方法能达到我想要的效果吗?如果 socat 由于某种原因死掉了,它会重新启动吗?如果启动 socat 时以太网连接不可用,会发生什么情况?在没有网络连接的情况下从 shell 运行它不起作用,并且该命令失败并显示错误消息“网络无法访问”。
在执行我的(Python)脚本之前,我应该如何确保 socat 正在运行?我应该从 Python 中启动 socat 吗?
答案1
要了解如何通过脚本设置 socat,请参阅这篇文章和要点:
https://gist.github.com/krzyklo/e60793b27400be7a330042aa6bdf388a
socat -x -d -d pty,raw,echo=0,link=/tmp/cryocon_simulator pty,raw,echo=0,link=/tmp/cryocon
下面的脚本来自链接,将所有内容集中在一处:
my-serial.py
import sys
import serial
DEFAULT_ADDR = '/home/krzys/myserial'
DEFAULT_CMD = 'R5'
args = len(sys.argv) - 1
if args == 0:
addr, cmd = DEFAULT_ADDR, DEFAULT_CMD
elif args == 1:
addr, cmd = DEFAULT_ADDR, sys.argv[1]
else:
addr, cmd = sys.argv[1:3]
cmd += '\r\n'
s = serial.Serial("/home/krzys/myserial",9600,timeout=0.5)
s.write(cmd.encode())
print(s.readline())
客户端.py
import sys
import serial
DEFAULT_ADDR = '/tmp/cryocon'
DEFAULT_CMD = '*IDN?'
args = len(sys.argv) - 1
if args == 0:
addr, cmd = DEFAULT_ADDR, DEFAULT_CMD
elif args == 1:
addr, cmd = DEFAULT_ADDR, sys.argv[1]
else:
addr, cmd = sys.argv[1:3]
cmd += '\n'
s = serial.serial_for_url(addr)
s.write(cmd.encode())
print(s.readline())
模拟器.py
import sys
import logging
import serial
DEFAULT_ADDR = '/tmp/cryocon_simulator'
logging.basicConfig(level=logging.INFO)
addr = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_ADDR
conn = serial.serial_for_url(addr)
logging.info(f'Ready to receive requests on {addr}')
while True:
request = conn.readline()
logging.info('REQ: %r', request)
request = request.strip().decode().lower()
reply = 'Cryo-con,24C,305682,1.05A\n' if request == '*idn?' else 'NACK\n'
reply = reply.encode()
logging.info('REP: %r', reply)
conn.write(reply)