Compare commits
5 Commits
11f1c4f55b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3580f89552 | ||
|
|
25aafd57c8 | ||
|
|
cdddfac609 | ||
|
|
944870496a | ||
|
|
c875cf383b |
16
src/dg430.py
16
src/dg430.py
@@ -280,12 +280,16 @@ def decode_fault_info(fault: int) -> str:
|
||||
|
||||
|
||||
def decode_relay_info(relay: int) -> str:
|
||||
"""解码继电器 bitmask"""
|
||||
items = []
|
||||
for bit, desc in RELAY_BITS.items():
|
||||
if relay & (1 << bit):
|
||||
items.append(desc)
|
||||
return "; ".join(items) if items else "无输出"
|
||||
"""解码继电器输出状态为可读字符串
|
||||
|
||||
0xB2 继电器输出状态原始值 x 的解析规则:
|
||||
- x & 0x01 为真 → "存在继电器有输出",否则 "存在继电器无输出"
|
||||
- x & 0x02 为真 → "脉冲继电器有输出",否则 "脉冲继电器无输出"
|
||||
汇总格式: "存在继电器有输出,脉冲继电器有输出"
|
||||
"""
|
||||
exist = "存在继电器有输出" if (relay & 0x01) else "存在继电器无输出"
|
||||
pulse = "脉冲继电器有输出" if (relay & 0x02) else "脉冲继电器无输出"
|
||||
return f"{exist},{pulse}"
|
||||
|
||||
|
||||
# ─── 0x4A 获取设备版本号响应 ──────────────────────────────────────
|
||||
|
||||
@@ -187,21 +187,11 @@ async def handle_heartbeat(data: dict) -> str | None:
|
||||
|
||||
|
||||
def handle_timestamp(data: dict) -> str:
|
||||
"""处理时间同步请求
|
||||
|
||||
TimeStamp 请求格式:
|
||||
{
|
||||
"Method": "TimeStamp",
|
||||
"Params": {
|
||||
"Device_id": "2345",
|
||||
"TimeZone": "Asia/Shanghai"
|
||||
}
|
||||
}
|
||||
|
||||
返回格式参考 PGLC 协议 3.5 节。
|
||||
"""
|
||||
"""处理时间同步请求(也是设备交互)"""
|
||||
params = data.get("Params", {})
|
||||
device_id = params.get("Device_id", "")
|
||||
if device_id:
|
||||
record_interaction(device_id)
|
||||
return make_timestamp_response(device_id, int(time.time()))
|
||||
|
||||
|
||||
@@ -397,6 +387,7 @@ async def parse_loop():
|
||||
dpg430_addr=wave.addr,
|
||||
remain_count=wave.remain_count,
|
||||
relay_code=wave.relay_out,
|
||||
relay_out=relay_info,
|
||||
work_freq=wave.work_freq,
|
||||
curr_dist=wave.curr_dist,
|
||||
speed=wave.speed,
|
||||
|
||||
@@ -152,7 +152,7 @@ async def _create_tables(pool: aiomysql.Pool):
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`username` VARCHAR(45) UNIQUE NOT NULL,
|
||||
`password_hash` VARCHAR(256) NOT NULL,
|
||||
`role` VARCHAR(20) DEFAULT 'operator' COMMENT 'admin/operator',
|
||||
`role` VARCHAR(20) DEFAULT 'operator' COMMENT 'admin/manager/operator/analyst',
|
||||
`is_active` TINYINT DEFAULT 1,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||
@@ -344,6 +344,15 @@ async def _create_tables(pool: aiomysql.Pool):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# V2.3.0 迁移:tb_user 角色增加 manager
|
||||
try:
|
||||
await cur.execute(
|
||||
"ALTER TABLE tb_user MODIFY COLUMN `role` VARCHAR(20) DEFAULT 'operator' "
|
||||
"COMMENT 'admin/manager/operator/analyst'"
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
logger.info("数据库表初始化完成")
|
||||
|
||||
|
||||
@@ -522,7 +531,8 @@ async def insert_wave_data(dnt_id: int, dpg430_addr: int,
|
||||
remain_count: int, relay_code: int,
|
||||
work_freq: float, curr_dist: int, speed: int,
|
||||
near_dist: int, far_dist: int,
|
||||
enter_dist: int, leave_dist: int):
|
||||
enter_dist: int, leave_dist: int,
|
||||
relay_out: str = ""):
|
||||
"""插入 0xB4 波动测试上报数据到 tb_state_tst"""
|
||||
coil_id, simulate_car_id = await get_fixture_coil_car_ids(dnt_id)
|
||||
dev_type = await get_fixture_dev_type(dnt_id)
|
||||
@@ -542,7 +552,7 @@ async def insert_wave_data(dnt_id: int, dpg430_addr: int,
|
||||
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
|
||||
(dnt_id, dpg430_addr, dev_type, str_type,
|
||||
1, "B4",
|
||||
"", relay_code,
|
||||
relay_out, relay_code,
|
||||
remain_count, work_freq, curr_dist, speed,
|
||||
near_dist, far_dist, enter_dist, leave_dist,
|
||||
coil_id, simulate_car_id),
|
||||
|
||||
@@ -37,6 +37,7 @@ from src.handlers import (
|
||||
device_status_monitor,
|
||||
set_udp_sender,
|
||||
)
|
||||
from src.models import insert_device_log
|
||||
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, LOG_LEVEL),
|
||||
@@ -75,6 +76,7 @@ class EDCProtocol:
|
||||
logger.info(f"UDP {msg} from {addr}")
|
||||
|
||||
method = msg.get("Method", "")
|
||||
method_lower = method.lower()
|
||||
logger.debug(f"UDP {method} from {addr}")
|
||||
|
||||
try:
|
||||
@@ -82,11 +84,11 @@ class EDCProtocol:
|
||||
if method == "Count_Off":
|
||||
# 设备登录上报,只处理不回复
|
||||
await handle_count_off(msg, addr)
|
||||
elif method == "Heartbeat":
|
||||
elif method_lower == "heartbeat":
|
||||
response = await handle_heartbeat(msg)
|
||||
elif method == "TSReport":
|
||||
elif method_lower == "tsreport":
|
||||
response = await handle_tsreport(msg)
|
||||
elif method == "SerialNet":
|
||||
elif method_lower == "serialnet":
|
||||
response = await handle_serial_net(msg)
|
||||
|
||||
if response and self.transport:
|
||||
@@ -105,24 +107,36 @@ async def handle_tcp_client(reader: asyncio.StreamReader,
|
||||
- 紧凑 JSON (无换行)
|
||||
"""
|
||||
addr = writer.get_extra_info("peername")
|
||||
addr_ip = addr[0] if addr else ""
|
||||
logger.info(f"TCP 连接: {addr}")
|
||||
|
||||
# TCP 连接事件日志
|
||||
try:
|
||||
asyncio.ensure_future(insert_device_log(
|
||||
serial="", ip=addr_ip,
|
||||
event_type="tcp_connect",
|
||||
content=f"TCP 连接: {addr}",
|
||||
))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
buffer = b""
|
||||
|
||||
async def process_message(msg: dict):
|
||||
"""处理单条消息并返回响应文本"""
|
||||
logger.info(f"TCP get_rcv {msg} from {addr}")
|
||||
method = msg.get("Method", "")
|
||||
method_lower = method.lower()
|
||||
logger.debug(f"TCP {method} from {addr}")
|
||||
|
||||
try:
|
||||
if method == "TimeStamp":
|
||||
if method_lower == "timestamp":
|
||||
return handle_timestamp(msg)
|
||||
elif method == "TSReport":
|
||||
elif method_lower == "tsreport":
|
||||
return await handle_tsreport(msg)
|
||||
elif method == "SerialNet":
|
||||
elif method_lower == "serialnet":
|
||||
return await handle_serial_net(msg)
|
||||
elif method == "Heartbeat":
|
||||
elif method_lower == "heartbeat":
|
||||
return await handle_heartbeat(msg)
|
||||
else:
|
||||
logger.debug(f"TCP 未知方法: {method}")
|
||||
@@ -176,6 +190,15 @@ async def handle_tcp_client(reader: asyncio.StreamReader,
|
||||
pass
|
||||
finally:
|
||||
logger.info(f"TCP 断开: {addr}")
|
||||
# TCP 断开事件日志
|
||||
try:
|
||||
asyncio.ensure_future(insert_device_log(
|
||||
serial="", ip=addr_ip,
|
||||
event_type="tcp_disconnect",
|
||||
content=f"TCP 断开: {addr}",
|
||||
))
|
||||
except Exception:
|
||||
pass
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user