120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
|
|
#!/usr/bin/env python
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
'''
|
|||
|
|
# @Time : 2026/1/9 10:45
|
|||
|
|
# @Author : reenrr
|
|||
|
|
# @File : RK1106_server.py
|
|||
|
|
# @Desc : RK1106服务端,等待工控机调用
|
|||
|
|
'''
|
|||
|
|
import socket
|
|||
|
|
import logging
|
|||
|
|
import sys
|
|||
|
|
from test import motor_demo
|
|||
|
|
|
|||
|
|
|
|||
|
|
# --------日志配置(终端+文件双输出)--------------
|
|||
|
|
logging.basicConfig(
|
|||
|
|
level=logging.INFO,
|
|||
|
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
|||
|
|
# 核心新增:日志文件配置
|
|||
|
|
handlers=[
|
|||
|
|
# 1. 文件处理器:保存到.log文件
|
|||
|
|
logging.FileHandler(
|
|||
|
|
"RK1106_server.log", # Buildroot推荐路径,临时测试可改/tmp/1106_server.log
|
|||
|
|
mode='a', # 追加模式(不会覆盖历史日志)
|
|||
|
|
encoding='utf-8' # 防止中文乱码(必加)
|
|||
|
|
),
|
|||
|
|
# 2. 终端处理器:输出到控制台
|
|||
|
|
logging.StreamHandler(sys.stdout)
|
|||
|
|
]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# --------配置TCP服务端----------
|
|||
|
|
HOST = "127.0.0.1"
|
|||
|
|
PORT = 8888
|
|||
|
|
|
|||
|
|
# 程序映射表(指令表示 -> 执行函数)
|
|||
|
|
PROG_MAP = {
|
|||
|
|
# "STEPPER_TEST": motor_test_demo,
|
|||
|
|
"test": motor_demo
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def parse_command(cmd_str: str) ->tuple[str, dict]:
|
|||
|
|
"""
|
|||
|
|
解析工控机发送的指令字符串
|
|||
|
|
:param cmd_str: 指令字符串
|
|||
|
|
:return: 指令名称,参数字典
|
|||
|
|
"""
|
|||
|
|
# 空指令处理
|
|||
|
|
if not cmd_str or cmd_str.strip() == "":
|
|||
|
|
return "", {}
|
|||
|
|
|
|||
|
|
# 分割指令标识和参数
|
|||
|
|
cmd_parts = cmd_str.strip().split("|", 1)
|
|||
|
|
prog_id = cmd_parts[0].strip()
|
|||
|
|
params = {}
|
|||
|
|
|
|||
|
|
# 解析参数(格式:param1=val1¶m2=val2)
|
|||
|
|
if len(cmd_parts) > 1 and cmd_parts[1].strip() != "":
|
|||
|
|
param_str = cmd_parts[1].strip()
|
|||
|
|
param_pairs = param_str.split("&")
|
|||
|
|
for pair in param_pairs:
|
|||
|
|
if "=" in pair:
|
|||
|
|
key, value = pair.split("=", 1) # 处理值中含=的情况
|
|||
|
|
# 类型自动转换(数字/字符串)
|
|||
|
|
try:
|
|||
|
|
params[key.strip()] = int(value.strip())
|
|||
|
|
except ValueError:
|
|||
|
|
try:
|
|||
|
|
params[key.strip()] = float(value.strip())
|
|||
|
|
except ValueError:
|
|||
|
|
params[key.strip()] = value.strip()
|
|||
|
|
|
|||
|
|
return prog_id, params
|
|||
|
|
|
|||
|
|
# ----------对外接口----------
|
|||
|
|
def server():
|
|||
|
|
# 创建TCP socket
|
|||
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
|||
|
|
# 允许端口复用
|
|||
|
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|||
|
|
server_socket.bind((HOST, PORT))
|
|||
|
|
server_socket.listen(1) # 只允许1个工控机连接
|
|||
|
|
logging.info(f"[1106] 服务已启动,监听端口:{PORT},等待工控机连接...")
|
|||
|
|
|
|||
|
|
# 等待工控机连接
|
|||
|
|
conn, addr = server_socket.accept()
|
|||
|
|
with conn:
|
|||
|
|
logging.info(f"[1106] 工控机已连接:{addr}")
|
|||
|
|
# 循环接收指令
|
|||
|
|
while True:
|
|||
|
|
# 接收指令(最大1024字节)
|
|||
|
|
data = conn.recv(1024).decode()
|
|||
|
|
logging.info(f"\n[1106] 收到工控机指令:{data}")
|
|||
|
|
# 解析指令
|
|||
|
|
prog_id, params = parse_command(data)
|
|||
|
|
logging.info(f"[1106] 解析结果 - 指令:{prog_id},参数:{params}")
|
|||
|
|
|
|||
|
|
# 执行对应程序
|
|||
|
|
responses = ""
|
|||
|
|
if prog_id in PROG_MAP:
|
|||
|
|
try:
|
|||
|
|
result = PROG_MAP[prog_id](**params)
|
|||
|
|
response = f"SUCCESS|步进电机测试执行完成,结果:{result}"
|
|||
|
|
logging.info(f"[1106] {response}")
|
|||
|
|
except Exception as e:
|
|||
|
|
response = f"FAIL|步进电机测试执行失败:{str(e)}"
|
|||
|
|
logging.error(f"[1106] {response}", exc_info=True)
|
|||
|
|
else:
|
|||
|
|
response = f"FAIL|未知指令:{prog_id},支持指令:{list(PROG_MAP.keys())}"
|
|||
|
|
logging.warning(f"[1106] {response}")
|
|||
|
|
|
|||
|
|
# 发送响应给工控机
|
|||
|
|
conn.sendall(response.encode("utf-8"))
|
|||
|
|
logging.info(f"[1106] 已发送响应:{response}")
|
|||
|
|
|
|||
|
|
# ----------测试接口----------
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
server()
|
|||
|
|
|