1
This commit is contained in:
54
templates/crond_tcp.py.tpl
Normal file
54
templates/crond_tcp.py.tpl
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
# Device: {device_name} ({device_id})
|
||||
|
||||
import time
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
# ====== 配置参数(从配置文件读取)======
|
||||
TARGET_IP = '{tms_server_ip}'
|
||||
TARGET_PORT = {listen_port}
|
||||
LOG_FILE = '{base_dir}/log/crond-{device_id}.log'
|
||||
RESTART_COMMAND = "{python_path} {base_dir}/bin/{device_id}.py &"
|
||||
DEVICE_ID = '{device_id}'
|
||||
# =========================
|
||||
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
||||
|
||||
|
||||
def is_port_open(ip, port):
|
||||
"""检查指定IP和端口是否可达"""
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.settimeout(1)
|
||||
try:
|
||||
logging.debug(f"尝试连接到 {{ip}}:{{port}}...")
|
||||
s.connect((ip, int(port)))
|
||||
s.shutdown(socket.SHUT_RDWR)
|
||||
print(f"[{{DEVICE_ID}}] 端口 {{port}} is open")
|
||||
logging.info(f"端口 {{port}} is open")
|
||||
return True
|
||||
except (OSError, socket.timeout) as e:
|
||||
print(f"[{{DEVICE_ID}}] 端口 {{port}} is down")
|
||||
logging.warning(f"端口 {{port}} 检查失败: {{e}},尝试重启程序")
|
||||
logging.info(f"执行重启命令: {{RESTART_COMMAND}}")
|
||||
os.system(RESTART_COMMAND)
|
||||
return False
|
||||
except ValueError:
|
||||
print(f"错误: 端口 '{{port}}' 不是有效的数字。")
|
||||
logging.error(f"端口 '{{port}}' 不是有效的数字。")
|
||||
return False
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.info(f"[{{DEVICE_ID}}] 启动端口检查程序,检查 {{TARGET_IP}}:{{TARGET_PORT}}")
|
||||
print(f"[{{DEVICE_ID}}] 启动端口检查程序,检查 {{TARGET_IP}}:{{TARGET_PORT}}")
|
||||
is_port_open(TARGET_IP, TARGET_PORT)
|
||||
85
templates/crond_udp.py.tpl
Normal file
85
templates/crond_udp.py.tpl
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
# Device: {device_name} ({device_id}) - UDP Protocol
|
||||
|
||||
import time
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# ====== 配置参数(从配置文件读取)======
|
||||
TARGET_IP = '{tms_server_ip}'
|
||||
TARGET_PORT = {listen_port}
|
||||
LOG_FILE = '{base_dir}/log/crond-{device_id}.log'
|
||||
RESTART_COMMAND = "{python_path} {base_dir}/bin/{device_id}.py &"
|
||||
DEVICE_ID = '{device_id}'
|
||||
# =========================
|
||||
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
||||
|
||||
|
||||
def is_udp_port_open(ip, port):
|
||||
"""
|
||||
检查UDP端口是否可用。
|
||||
UDP是无连接的,这里通过检查端口是否被占用或发送测试数据来判断。
|
||||
"""
|
||||
try:
|
||||
# 尝试绑定到该端口,如果成功说明端口未被占用(服务未启动)
|
||||
# 如果失败说明端口已被占用(服务正在运行)
|
||||
test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
test_sock.settimeout(1)
|
||||
test_sock.bind((ip, int(port)))
|
||||
test_sock.close()
|
||||
|
||||
# 如果绑定成功,说明服务未启动
|
||||
print(f"[{{DEVICE_ID}}] UDP端口 {{port}} 未被占用,服务可能未运行")
|
||||
logging.warning(f"UDP端口 {{port}} 未被占用,服务可能未运行,尝试重启程序")
|
||||
logging.info(f"执行重启命令: {{RESTART_COMMAND}}")
|
||||
os.system(RESTART_COMMAND)
|
||||
return False
|
||||
except OSError as e:
|
||||
# 绑定失败,说明端口已被占用,服务正在运行
|
||||
if "Address already in use" in str(e) or "98" in str(e):
|
||||
print(f"[{{DEVICE_ID}}] UDP端口 {{port}} is open (已被占用,服务运行中)")
|
||||
logging.info(f"UDP端口 {{port}} is open (服务运行中)")
|
||||
return True
|
||||
else:
|
||||
print(f"[{{DEVICE_ID}}] 检查UDP端口 {{port}} 时发生错误: {{e}}")
|
||||
logging.error(f"检查UDP端口 {{port}} 时发生错误: {{e}}")
|
||||
return False
|
||||
|
||||
|
||||
def check_process_running():
|
||||
"""通过进程名检查服务是否正在运行"""
|
||||
try:
|
||||
# 检查是否有对应设备的Python进程在运行
|
||||
cmd = f"ps aux | grep '{{DEVICE_ID}}.py' | grep -v grep"
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
print(f"[{{DEVICE_ID}}] 进程检查: 服务正在运行")
|
||||
logging.info(f"进程检查: 服务正在运行")
|
||||
return True
|
||||
else:
|
||||
print(f"[{{DEVICE_ID}}] 进程检查: 服务未运行")
|
||||
logging.warning(f"进程检查: 服务未运行,尝试重启")
|
||||
logging.info(f"执行重启命令: {{RESTART_COMMAND}}")
|
||||
os.system(RESTART_COMMAND)
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"[{{DEVICE_ID}}] 进程检查失败: {{e}}")
|
||||
logging.error(f"进程检查失败: {{e}}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.info(f"[{{DEVICE_ID}}] 启动UDP端口检查程序,检查 {{TARGET_IP}}:{{TARGET_PORT}}")
|
||||
print(f"[{{DEVICE_ID}}] 启动UDP端口检查程序,检查 {{TARGET_IP}}:{{TARGET_PORT}}")
|
||||
|
||||
# 对于UDP,优先使用进程检查方式
|
||||
check_process_running()
|
||||
104
templates/listener_tcp.py.tpl
Normal file
104
templates/listener_tcp.py.tpl
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
# Device: {device_name} ({device_id})
|
||||
|
||||
import socket
|
||||
import os
|
||||
import time
|
||||
import logging
|
||||
import sys
|
||||
|
||||
# ====== 配置参数(从配置文件读取)======
|
||||
TMS_SERVER_IP = '{tms_server_ip}'
|
||||
TMS_PORT = {listen_port}
|
||||
UPC_DEV_IP = '{upc_ip}'
|
||||
UPC_DEV_PORT = '{upc_port}'
|
||||
SENDER_FILE = '{base_dir}/bin/sender_tcp.py'
|
||||
LOG_FILE = '{base_dir}/log/{device_id}.log'
|
||||
PYTHON_PATH = '{python_path}'
|
||||
DEVICE_ID = '{device_id}'
|
||||
# =========================
|
||||
|
||||
BUFSIZE = 1024
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
# 命令映射表
|
||||
COMMAND_MAPPINGS = {command_mappings}
|
||||
|
||||
|
||||
def process_command(buf):
|
||||
"""处理接收到的命令,返回对应的操作指令"""
|
||||
buf = buf.strip()
|
||||
if buf in COMMAND_MAPPINGS:
|
||||
return COMMAND_MAPPINGS[buf]
|
||||
return "nodata"
|
||||
|
||||
|
||||
def main():
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
sock.bind((TMS_SERVER_IP, int(TMS_PORT)))
|
||||
sock.listen(500)
|
||||
except OSError as e:
|
||||
logstr = "!!!!!ERROR!!!!!" + time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) + \
|
||||
" 无法绑定端口 %s:%s - %s" % (TMS_SERVER_IP, TMS_PORT, e)
|
||||
logging.error(logstr)
|
||||
print(logstr)
|
||||
sys.exit(1)
|
||||
|
||||
logging.info("服务启动,监听 %s:%s" % (TMS_SERVER_IP, TMS_PORT))
|
||||
print(f"[{{DEVICE_ID}}] 服务启动,监听 {{TMS_SERVER_IP}}:{{TMS_PORT}}")
|
||||
|
||||
while True:
|
||||
connection, address = sock.accept()
|
||||
try:
|
||||
connection.settimeout(5)
|
||||
buf_bytes = connection.recv(BUFSIZE)
|
||||
buf = buf_bytes.decode('utf-8').strip()
|
||||
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = "===" + datetime_str + " 收到客户端 " + address[0] + ":" + str(address[1]) + \
|
||||
" 发送的指令: '" + str(buf) + "'"
|
||||
logging.info(logstr)
|
||||
print(logstr)
|
||||
|
||||
operation = process_command(buf)
|
||||
|
||||
if operation == "nodata":
|
||||
logstr = "===" + datetime_str + " 未知指令: '" + str(buf) + "'"
|
||||
logging.warning(logstr)
|
||||
print(logstr)
|
||||
connection.send(('Unknown command: %s' % buf).encode('utf-8'))
|
||||
else:
|
||||
logstr = "===" + datetime_str + " 映射到内部指令: '" + str(operation) + "'"
|
||||
logging.info(logstr)
|
||||
print(logstr)
|
||||
|
||||
os_command = str(PYTHON_PATH) + " " + SENDER_FILE + " " + \
|
||||
str(UPC_DEV_IP) + " " + str(UPC_DEV_PORT) + " " + \
|
||||
str(operation) + " " + str(LOG_FILE)
|
||||
logging.info("执行外部命令: %s" % os_command)
|
||||
os.system(os_command)
|
||||
connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8'))
|
||||
except socket.timeout:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = "===" + datetime_str + " 客户端连接超时: " + address[0] + ":" + str(address[1]) + "==="
|
||||
logging.warning(logstr)
|
||||
print('time out')
|
||||
except Exception as e:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = "===" + datetime_str + " 处理客户端 " + address[0] + ":" + str(address[1]) + \
|
||||
" 请求时发生错误: " + str(e) + "==="
|
||||
logging.error(logstr, exc_info=True)
|
||||
print("Error processing request:", e)
|
||||
connection.send(('Error processing command: %s' % str(e)).encode('utf-8'))
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
98
templates/listener_udp.py.tpl
Normal file
98
templates/listener_udp.py.tpl
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
# Device: {device_name} ({device_id}) - UDP Protocol
|
||||
|
||||
import socket
|
||||
import os
|
||||
import time
|
||||
import logging
|
||||
import sys
|
||||
|
||||
# ====== 配置参数(从配置文件读取)======
|
||||
TMS_SERVER_IP = '{tms_server_ip}'
|
||||
TMS_PORT = {listen_port}
|
||||
UPC_DEV_IP = '{upc_ip}'
|
||||
UPC_DEV_PORT = {upc_port}
|
||||
SENDER_FILE = '{base_dir}/bin/sender_udp.py'
|
||||
LOG_FILE = '{base_dir}/log/{device_id}.log'
|
||||
PYTHON_PATH = '{python_path}'
|
||||
DEVICE_ID = '{device_id}'
|
||||
# =========================
|
||||
|
||||
BUFSIZE = 1024
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
# 命令映射表
|
||||
COMMAND_MAPPINGS = {command_mappings}
|
||||
|
||||
|
||||
def process_command(buf):
|
||||
"""处理接收到的命令,返回对应的操作指令"""
|
||||
buf = buf.strip()
|
||||
if buf in COMMAND_MAPPINGS:
|
||||
return COMMAND_MAPPINGS[buf]
|
||||
return "nodata"
|
||||
|
||||
|
||||
def main():
|
||||
# 创建 UDP socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
try:
|
||||
sock.bind((TMS_SERVER_IP, int(TMS_PORT)))
|
||||
except OSError as e:
|
||||
logstr = "!!!!!ERROR!!!!!" + time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) + \
|
||||
" 无法绑定UDP端口 %s:%s - %s" % (TMS_SERVER_IP, TMS_PORT, e)
|
||||
logging.error(logstr)
|
||||
print(logstr)
|
||||
sys.exit(1)
|
||||
|
||||
logging.info("UDP服务启动,监听 %s:%s" % (TMS_SERVER_IP, TMS_PORT))
|
||||
print(f"[{{DEVICE_ID}}] UDP服务启动,监听 {{TMS_SERVER_IP}}:{{TMS_PORT}}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
# UDP 使用 recvfrom 接收数据,同时获取客户端地址
|
||||
buf_bytes, client_addr = sock.recvfrom(BUFSIZE)
|
||||
buf = buf_bytes.decode('utf-8').strip()
|
||||
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = "===" + datetime_str + " 收到UDP客户端 " + client_addr[0] + ":" + str(client_addr[1]) + \
|
||||
" 发送的指令: '" + str(buf) + "'"
|
||||
logging.info(logstr)
|
||||
print(logstr)
|
||||
|
||||
operation = process_command(buf)
|
||||
|
||||
if operation == "nodata":
|
||||
logstr = "===" + datetime_str + " 未知指令: '" + str(buf) + "'"
|
||||
logging.warning(logstr)
|
||||
print(logstr)
|
||||
# 发送UDP响应
|
||||
sock.sendto(('Unknown command: %s' % buf).encode('utf-8'), client_addr)
|
||||
else:
|
||||
logstr = "===" + datetime_str + " 映射到内部指令: '" + str(operation) + "'"
|
||||
logging.info(logstr)
|
||||
print(logstr)
|
||||
|
||||
# 执行发送指令的脚本
|
||||
os_command = str(PYTHON_PATH) + " " + SENDER_FILE + " " + \
|
||||
str(UPC_DEV_IP) + " " + str(UPC_DEV_PORT) + " " + \
|
||||
str(operation) + " " + str(LOG_FILE)
|
||||
logging.info("执行外部命令: %s" % os_command)
|
||||
os.system(os_command)
|
||||
|
||||
# 发送UDP响应
|
||||
sock.sendto(('Command %s processed as %s' % (buf, operation)).encode('utf-8'), client_addr)
|
||||
except Exception as e:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = "===" + datetime_str + " 处理UDP请求时发生错误: " + str(e) + "==="
|
||||
logging.error(logstr, exc_info=True)
|
||||
print("Error processing UDP request:", e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
119
templates/sender_tcp.py.tpl
Normal file
119
templates/sender_tcp.py.tpl
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import time
|
||||
import logging
|
||||
import telnetlib
|
||||
|
||||
|
||||
def tcp_command_send(upc_addr, upc_command, data):
|
||||
"""负责发送数据和接收一次响应"""
|
||||
timeout = 2
|
||||
socket.setdefaulttimeout(timeout)
|
||||
try:
|
||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
logging.debug(f"尝试连接到 {{upc_addr[0]}}:{{upc_addr[1]}}...")
|
||||
client.connect(upc_addr)
|
||||
logging.debug(f"成功连接到 {{upc_addr[0]}}:{{upc_addr[1]}}。")
|
||||
|
||||
logging.info(f"正在发送命令 '{{upc_command}}' 到 {{upc_addr}}: {{data!r}} (原始字节)")
|
||||
client.send(data)
|
||||
logging.debug(f"数据发送完成。")
|
||||
|
||||
recv_buffer_size = 1024
|
||||
response_bytes = b''
|
||||
try:
|
||||
logging.debug(f"尝试从 {{upc_addr}} 接收响应数据...")
|
||||
response_bytes = client.recv(recv_buffer_size)
|
||||
if response_bytes:
|
||||
logging.info(f"从 {{upc_addr}} 收到原始响应字节: {{response_bytes!r}}")
|
||||
try:
|
||||
response_str = response_bytes.decode('utf-8', errors='ignore')
|
||||
logging.info(f"从 {{upc_addr}} 收到解码响应字符串: '{{response_str}}'")
|
||||
except Exception as decode_e:
|
||||
logging.warning(f"解码从 {{upc_addr}} 收到的响应时发生错误: {{decode_e}}")
|
||||
else:
|
||||
logging.info(f"从 {{upc_addr}} 未收到响应数据 (连接可能已关闭或设备未发送)。")
|
||||
except socket.timeout:
|
||||
logging.warning(f"从 {{upc_addr}} 接收响应超时。")
|
||||
except OSError as recv_e:
|
||||
logging.error(f"从 {{upc_addr}} 接收响应时发生网络错误: {{recv_e}}")
|
||||
|
||||
client.close()
|
||||
logging.debug(f"连接关闭。")
|
||||
return True
|
||||
except OSError as e:
|
||||
logging.error(f"命令 '{{upc_command}}' 发送至 {{upc_addr}} 失败: {{e}}")
|
||||
return False
|
||||
|
||||
|
||||
# 指令定义表(从配置文件读取)
|
||||
COMMAND_DEFINITIONS = {command_definitions}
|
||||
|
||||
|
||||
def upc_send_command(upc_addr, upc_command, log_file):
|
||||
"""将命令发送给终端设备"""
|
||||
data = None
|
||||
|
||||
# 查找指令定义
|
||||
if upc_command in COMMAND_DEFINITIONS:
|
||||
hex_str = COMMAND_DEFINITIONS[upc_command]
|
||||
data = bytes.fromhex(hex_str)
|
||||
|
||||
if data is None:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} 未知命令: {{upc_command}},没有对应的数据可发送。"
|
||||
logging.warning(logstr)
|
||||
print(logstr)
|
||||
else:
|
||||
i = 1
|
||||
while i <= 3: # 尝试发送3次
|
||||
if tcp_command_send(upc_addr, upc_command, data):
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令第{{i}}次发送成功"
|
||||
logging.info(logstr)
|
||||
return
|
||||
else:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令第{{i}}次发送失败,3秒后进行第{{i+1}}次尝试"
|
||||
logging.warning(logstr)
|
||||
time.sleep(3)
|
||||
i = i + 1
|
||||
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令在3次尝试后发送均失败!"
|
||||
logging.error(logstr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
UPC_DEV_IP = sys.argv[1]
|
||||
UPC_DEV_PORT = sys.argv[2]
|
||||
upc_command = sys.argv[3]
|
||||
LOG_FILE = sys.argv[4]
|
||||
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
||||
UPC_ADDR = (UPC_DEV_IP, int(UPC_DEV_PORT))
|
||||
|
||||
# 验证端口是否能Telnet通
|
||||
try:
|
||||
logging.debug(f"尝试通过 Telnet 检查端口 {{UPC_ADDR[0]}}:{{UPC_ADDR[1]}} 可访问性...")
|
||||
tn = telnetlib.Telnet(UPC_DEV_IP, UPC_DEV_PORT)
|
||||
tn.close()
|
||||
logging.debug(f"端口 {{UPC_ADDR[0]}}:{{UPC_ADDR[1]}} Telnet 检查通过。")
|
||||
except OSError as e:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"!!!!!ERROR!!!!!{{datetime_str}} {{UPC_ADDR}} 端口无法访问,请检查设备或网络连接: {{e}}!!!!!"
|
||||
logging.error(logstr)
|
||||
print(logstr)
|
||||
except Exception as e:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"!!!!!ERROR!!!!!{{datetime_str}} {{UPC_ADDR}} Telnet检查时发生未知错误: {{e}}!!!!!"
|
||||
logging.error(logstr, exc_info=True)
|
||||
print(logstr)
|
||||
else:
|
||||
upc_send_command(UPC_ADDR, upc_command, LOG_FILE)
|
||||
107
templates/sender_udp.py.tpl
Normal file
107
templates/sender_udp.py.tpl
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import time
|
||||
import logging
|
||||
|
||||
|
||||
def udp_command_send(upc_addr, upc_command, data, timeout=2):
|
||||
"""通过UDP发送数据并接收响应"""
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.settimeout(timeout)
|
||||
|
||||
try:
|
||||
logging.debug(f"尝试发送UDP数据到 {{upc_addr[0]}}:{{upc_addr[1]}}...")
|
||||
|
||||
logging.info(f"正在发送UDP命令 '{{upc_command}}' 到 {{upc_addr}}: {{data!r}} (原始字节)")
|
||||
sock.sendto(data, upc_addr)
|
||||
logging.debug(f"UDP数据发送完成。")
|
||||
|
||||
# 尝试接收响应
|
||||
recv_buffer_size = 1024
|
||||
try:
|
||||
logging.debug(f"等待从 {{upc_addr}} 接收UDP响应...")
|
||||
response_bytes, addr = sock.recvfrom(recv_buffer_size)
|
||||
if response_bytes:
|
||||
logging.info(f"从 {{addr}} 收到UDP原始响应字节: {{response_bytes!r}}")
|
||||
try:
|
||||
response_str = response_bytes.decode('utf-8', errors='ignore')
|
||||
logging.info(f"从 {{addr}} 收到UDP解码响应字符串: '{{response_str}}'")
|
||||
except Exception as decode_e:
|
||||
logging.warning(f"解码UDP响应时发生错误: {{decode_e}}")
|
||||
else:
|
||||
logging.info(f"未收到UDP响应数据。")
|
||||
except socket.timeout:
|
||||
logging.warning(f"接收UDP响应超时(设备可能不返回响应,这通常是正常的)。")
|
||||
except OSError as recv_e:
|
||||
logging.error(f"接收UDP响应时发生网络错误: {{recv_e}}")
|
||||
|
||||
sock.close()
|
||||
logging.debug(f"UDP socket关闭。")
|
||||
return True
|
||||
except OSError as e:
|
||||
logging.error(f"UDP命令 '{{upc_command}}' 发送至 {{upc_addr}} 失败: {{e}}")
|
||||
return False
|
||||
finally:
|
||||
try:
|
||||
sock.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# 指令定义表(从配置文件读取)
|
||||
COMMAND_DEFINITIONS = {command_definitions}
|
||||
|
||||
|
||||
def upc_send_command(upc_addr, upc_command, log_file):
|
||||
"""将命令发送给终端设备"""
|
||||
data = None
|
||||
|
||||
# 查找指令定义
|
||||
if upc_command in COMMAND_DEFINITIONS:
|
||||
hex_str = COMMAND_DEFINITIONS[upc_command]
|
||||
data = bytes.fromhex(hex_str)
|
||||
|
||||
if data is None:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} 未知命令: {{upc_command}},没有对应的数据可发送。"
|
||||
logging.warning(logstr)
|
||||
print(logstr)
|
||||
else:
|
||||
i = 1
|
||||
while i <= 3: # 尝试发送3次
|
||||
if udp_command_send(upc_addr, upc_command, data):
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令第{{i}}次发送成功"
|
||||
logging.info(logstr)
|
||||
return
|
||||
else:
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令第{{i}}次发送失败,3秒后进行第{{i+1}}次尝试"
|
||||
logging.warning(logstr)
|
||||
time.sleep(3)
|
||||
i = i + 1
|
||||
|
||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
||||
logstr = f"{{datetime_str}} {{upc_command}}命令在3次尝试后发送均失败!"
|
||||
logging.error(logstr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
||||
|
||||
UPC_DEV_IP = sys.argv[1]
|
||||
UPC_DEV_PORT = int(sys.argv[2])
|
||||
upc_command = sys.argv[3]
|
||||
LOG_FILE = sys.argv[4]
|
||||
|
||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
||||
UPC_ADDR = (UPC_DEV_IP, UPC_DEV_PORT)
|
||||
|
||||
# UDP 是无连接的,无需像TCP那样预先检查端口连通性
|
||||
# 直接发送数据
|
||||
logging.info(f"UDP模式:准备发送命令到 {{UPC_ADDR}}")
|
||||
upc_send_command(UPC_ADDR, upc_command, LOG_FILE)
|
||||
Reference in New Issue
Block a user