2025-02-18 11:28:24 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
'''
|
|
|
|
|
# @Time : 2025/2/18 10:08
|
|
|
|
|
# @Author : hjw
|
|
|
|
|
# @File : Network.py
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
import threading
|
|
|
|
|
import socket
|
|
|
|
|
import logging
|
|
|
|
|
import json
|
|
|
|
|
from queue import Queue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 配置日志系统
|
|
|
|
|
logging.basicConfig(
|
|
|
|
|
level=logging.INFO,
|
|
|
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
|
|
|
handlers=[
|
|
|
|
|
logging.FileHandler('controller.log'),
|
|
|
|
|
logging.StreamHandler()
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NetworkHandler:
|
|
|
|
|
def __init__(self, config):
|
|
|
|
|
self.host = config['network']['host']
|
|
|
|
|
self.port = config['network']['port']
|
|
|
|
|
self.sock = None
|
|
|
|
|
self.command_queue = Queue()
|
|
|
|
|
self.status = {
|
|
|
|
|
'measuring': False,
|
|
|
|
|
'error': None,
|
|
|
|
|
'current_weight': 0,
|
|
|
|
|
'target_weight': 0,
|
|
|
|
|
'algorithm': 'pid',
|
|
|
|
|
'set_tare': False,
|
|
|
|
|
'set_tare_num_time': 0,
|
|
|
|
|
'get_weight': False,
|
|
|
|
|
'set_vibrate': False,
|
2025-02-19 16:18:41 +08:00
|
|
|
'set_vibrate_time': 0,
|
|
|
|
|
'direction_control': False,
|
|
|
|
|
'start_weighting': False,
|
|
|
|
|
'weighting_isok': False,
|
|
|
|
|
'vibrate_isok': False
|
2025-02-18 11:28:24 +08:00
|
|
|
}
|
|
|
|
|
self.lock = threading.Lock()
|
|
|
|
|
self.running = True
|
|
|
|
|
|
|
|
|
|
def start_server(self):
|
|
|
|
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
|
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
|
try:
|
|
|
|
|
self.sock.bind((self.host, self.port))
|
|
|
|
|
self.sock.listen(5)
|
|
|
|
|
logger.info(f"网络服务启动于 {self.host}:{self.port}")
|
|
|
|
|
|
|
|
|
|
while self.running:
|
|
|
|
|
conn, addr = self.sock.accept()
|
|
|
|
|
threading.Thread(target=self._handle_client, args=(conn, addr), daemon=True).start()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"网络服务异常: {str(e)}")
|
|
|
|
|
finally:
|
|
|
|
|
self.sock.close()
|
|
|
|
|
|
|
|
|
|
def _handle_client(self, conn, addr):
|
|
|
|
|
try:
|
|
|
|
|
data = conn.recv(1024)
|
|
|
|
|
if data:
|
|
|
|
|
cmd = json.loads(data.decode())
|
|
|
|
|
self._process_command(cmd)
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
# 返回当前状态
|
2025-02-19 16:18:41 +08:00
|
|
|
if self.status['start_weighting'] == True :
|
|
|
|
|
while True:
|
|
|
|
|
if self.status['start_weighting'] == False:
|
|
|
|
|
with self.lock:
|
|
|
|
|
response = json.dumps(self.status)
|
|
|
|
|
conn.send(response.encode())
|
|
|
|
|
break
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
elif self.status['set_vibrate'] == True:
|
|
|
|
|
while True:
|
|
|
|
|
if self.status['set_vibrate'] == False:
|
|
|
|
|
with self.lock:
|
|
|
|
|
response = json.dumps(self.status)
|
|
|
|
|
conn.send(response.encode())
|
|
|
|
|
break
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
else:
|
2025-02-18 11:28:24 +08:00
|
|
|
with self.lock:
|
|
|
|
|
response = json.dumps(self.status)
|
|
|
|
|
conn.send(response.encode())
|
|
|
|
|
except json.JSONDecodeError:
|
|
|
|
|
logger.warning("收到无效的JSON指令")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"客户端处理异常: {str(e)}")
|
|
|
|
|
finally:
|
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
def _process_command(self, cmd):
|
|
|
|
|
with self.lock:
|
|
|
|
|
if cmd.get('command') == 'set_target':
|
|
|
|
|
|
|
|
|
|
self.status['target_weight'] = cmd['payload']['target_weight']
|
|
|
|
|
self.status['algorithm'] = cmd['payload'].get('algorithm', 'pid')
|
2025-02-19 16:18:41 +08:00
|
|
|
self.status['direction_control'] = cmd['payload']['direction_control']
|
2025-02-18 11:28:24 +08:00
|
|
|
self.status['measuring'] = True
|
2025-02-19 16:18:41 +08:00
|
|
|
self.status['start_weighting'] = True
|
|
|
|
|
self.status['weighting_isok'] = False
|
2025-02-18 11:28:24 +08:00
|
|
|
print("收到指令set_target:", self.status['target_weight'])
|
|
|
|
|
elif cmd.get('command') == 'stop':
|
|
|
|
|
self.status['measuring'] = False
|
2025-02-19 16:18:41 +08:00
|
|
|
self.status['start_weighting'] = False
|
2025-02-18 11:28:24 +08:00
|
|
|
|
|
|
|
|
elif cmd.get('command') == 'set_zero':
|
|
|
|
|
self.status['set_tare'] = True
|
|
|
|
|
|
|
|
|
|
elif cmd.get('command') == 'get_weight':
|
|
|
|
|
self.status['get_weight'] = True
|
|
|
|
|
|
|
|
|
|
elif cmd.get('command') == 'set_vibrate':
|
|
|
|
|
self.status['set_vibrate'] = True
|
2025-02-19 16:18:41 +08:00
|
|
|
self.status['set_vibrate_time'] = cmd['payload']['time']
|
|
|
|
|
self.status['vibrate_isok'] = False
|