You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
4.1 KiB

2 months ago
import asyncio
import serial
import websocket
import websockets
import json
import sys
import time
from eventlet.green.http.client import responses
import modscan
async def handle_connection(websocket):
"""处理 WebSocket 连接"""
client_ip = websocket.remote_address[0]
print(f"客户端连接成功: {client_ip}")
async for message in websocket:
try:
data=json.loads(message)
port = data.get('port').strip()
baudrate = data.get('baudrate').strip()
register_address = int(data.get('registerAddress').strip())
timeout = float(data.get('timeout').strip())
retries = int(data.get('retries').strip())
send_interval = float(data.get('sendInterval').strip())
func_input = data.get('functionCode').strip()
function_code = modscan.get_function_code(func_input) if func_input else 0x03
# 数据位配置
bytesize_input = data.get('bytesize').strip()
if bytesize_input == '5':
bytesize = serial.FIVEBITS
elif bytesize_input == '6':
bytesize = serial.SIXBITS
elif bytesize_input == '7':
bytesize = serial.SEVENBITS
else:
bytesize = serial.EIGHTBITS # 默认
# 校验位配置
parity_input = data.get('parity').strip().upper()
if parity_input == 'E':
parity = serial.PARITY_EVEN
elif parity_input == 'O':
parity = serial.PARITY_ODD
elif parity_input == 'M':
parity = serial.PARITY_MARK
elif parity_input == 'S':
parity = serial.PARITY_SPACE
else:
parity = serial.PARITY_NONE # 默认
# 停止位配置
stopbits_input = data.get('stopbits').strip()
if stopbits_input == '1.5':
stopbits = serial.STOPBITS_ONE_POINT_FIVE
elif stopbits_input == '2':
stopbits = serial.STOPBITS_TWO
else:
stopbits = serial.STOPBITS_ONE # 默认
if (data.get('type')=='sole'):
addr = int(data.get('current_addr'))
status = modscan.scan_modbus_devices(port, baudrate, addr, timeout, retries, send_interval, register_address, bytesize,
parity, stopbits, function_code)
print(data)
await websocket.send(json.dumps(status))
print(status)
elif(data.get('type')=='list'):
startaddr=int(data.get('startAddr'))
endaddr=int(data.get('endAddr'))
for addr in range(startaddr,endaddr+1):
status = modscan.scan_modbus_devices(port, baudrate, addr, timeout, retries, send_interval,
register_address, bytesize,
parity, stopbits, function_code)
print(data)
await websocket.send(json.dumps(status))
print(status)
time.sleep(send_interval)
except json.JSONDecodeError:
await websocket.send(json.dumps({
"status": "error",
"message": "无效的JSON格式"
}))
async def main():
"""主异步函数"""
print("启动 WebSocket 服务器...")
# 正确创建服务器实例
server = await websockets.serve(
handle_connection,
"localhost",
8765
)
print(f"WebSocket 服务器已启动: ws://localhost:8765")
print(f"监听地址: {server.sockets[0].getsockname()}")
# 永久运行
await server.wait_closed()
if __name__ == "__main__":
# 设置 Windows 事件循环策略
if sys.platform == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
# 运行主程序
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\n服务器已停止")