658 lines
20 KiB
Python
658 lines
20 KiB
Python
|
#!/usr/bin/env python
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
|
|||
|
"""
|
|||
|
简化的VDA5050设备处理器快速入门示例
|
|||
|
默认使用VDA5050协议,支持VDA5050和TCP两种协议类型
|
|||
|
展示如何使用VWED.device模块进行基于VDA5050标准的设备处理
|
|||
|
"""
|
|||
|
|
|||
|
def boot():
|
|||
|
"""脚本启动函数 - 所有注册都在这里进行"""
|
|||
|
|
|||
|
VWED.log.sync_info("=== 开始注册VDA5050设备处理器 ===")
|
|||
|
|
|||
|
# 1. 注册VDA5050小车处理器
|
|||
|
register_vda5050_vehicles()
|
|||
|
|
|||
|
# 2. 注册其他设备处理器(基于VDA5050即时动作)
|
|||
|
register_other_devices()
|
|||
|
|
|||
|
# 3. 注册TCP协议设备
|
|||
|
register_tcp_devices()
|
|||
|
|
|||
|
VWED.log.sync_info("=== VDA5050设备处理器注册完成 ===")
|
|||
|
|
|||
|
|
|||
|
def register_vda5050_vehicles():
|
|||
|
"""注册VDA5050小车处理器"""
|
|||
|
|
|||
|
# 华睿VDA5050小车(默认VDA5050协议)
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="huarui_agv_001",
|
|||
|
device_type="vehicle",
|
|||
|
device_brand="huarui",
|
|||
|
protocol_type="vda5050", # VDA5050协议(默认)
|
|||
|
listen_topics=["vda5050/huarui_agv_001/state", "vda5050/huarui_agv_001/factsheet"],
|
|||
|
forward_topics=["fleet/huarui_agv_001/status"],
|
|||
|
handler=vda5050_vehicle_handler,
|
|||
|
description="华睿VDA5050小车处理器"
|
|||
|
)
|
|||
|
|
|||
|
# 仙工VDA5050小车
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="seer_agv_001",
|
|||
|
device_type="vehicle",
|
|||
|
device_brand="seer",
|
|||
|
protocol_type="vda5050",
|
|||
|
listen_topics=["vda5050/seer_agv_001/state"],
|
|||
|
forward_topics=["fleet/seer_agv_001/status"],
|
|||
|
handler=vda5050_vehicle_handler,
|
|||
|
description="仙工VDA5050小车处理器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
def register_other_devices():
|
|||
|
"""注册其他设备处理器(基于VDA5050即时动作)"""
|
|||
|
|
|||
|
# 门设备(VDA5050即时动作)
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="door_001",
|
|||
|
device_type="door",
|
|||
|
# device_brand和protocol_type使用默认值(standard, vda5050)
|
|||
|
listen_topics=["vda5050/door_001/status"],
|
|||
|
forward_topics=["facility/door_001/events"],
|
|||
|
handler=door_instant_action_handler,
|
|||
|
description="门设备VDA5050处理器"
|
|||
|
)
|
|||
|
|
|||
|
# 传感器设备(VDA5050即时动作)
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="sensor_001",
|
|||
|
device_type="sensor",
|
|||
|
listen_topics=["vda5050/sensor_001/data"],
|
|||
|
forward_topics=["monitoring/sensor_001/alerts"],
|
|||
|
handler=sensor_instant_action_handler,
|
|||
|
description="传感器VDA5050处理器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
def register_tcp_devices():
|
|||
|
"""注册TCP协议设备(VDA5050通过TCP传输)"""
|
|||
|
|
|||
|
# TCP协议小车(VDA5050通过TCP)
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="tcp_agv_001",
|
|||
|
device_type="vehicle",
|
|||
|
device_brand="quicktron",
|
|||
|
protocol_type="tcp", # TCP协议(VDA5050包装)
|
|||
|
listen_topics=["tcp/quicktron_agv_001/data"],
|
|||
|
forward_topics=["fleet/tcp_agv_001/status"],
|
|||
|
handler=tcp_vehicle_handler,
|
|||
|
description="快仓TCP协议小车处理器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
def register_door_handler():
|
|||
|
"""注册门禁处理器"""
|
|||
|
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="door_demo_main",
|
|||
|
device_type="door",
|
|||
|
listen_topics=["demo/door/access_request"],
|
|||
|
forward_topics=["demo/door/control"],
|
|||
|
handler=door_access_controller,
|
|||
|
description="演示门禁访问控制器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
def register_caller_handler():
|
|||
|
"""注册呼叫器处理器"""
|
|||
|
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="caller_demo_lobby",
|
|||
|
device_type="caller",
|
|||
|
listen_topics=["demo/caller/signal"],
|
|||
|
forward_topics=["demo/caller/response"],
|
|||
|
handler=caller_signal_processor,
|
|||
|
description="演示呼叫器信号处理器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
def register_sensor_handler():
|
|||
|
"""注册传感器处理器"""
|
|||
|
|
|||
|
VWED.device.register_and_run(
|
|||
|
device_id="sensor_demo_env",
|
|||
|
device_type="sensor",
|
|||
|
listen_topics=["demo/sensor/data"],
|
|||
|
forward_topics=["demo/hvac/control"],
|
|||
|
handler=environmental_processor,
|
|||
|
description="演示环境传感器处理器"
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
# ==================== 设备处理函数 ====================
|
|||
|
|
|||
|
def agv_command_processor(message):
|
|||
|
"""AGV命令处理函数 - MQTT消息到达时自动执行"""
|
|||
|
|
|||
|
VWED.log.sync_info(f"AGV收到命令: {message.payload}")
|
|||
|
|
|||
|
command = message.payload.get("command")
|
|||
|
|
|||
|
if command == "move":
|
|||
|
# 移动命令 - 添加安全检查
|
|||
|
x = message.payload.get("x", 0)
|
|||
|
y = message.payload.get("y", 0)
|
|||
|
speed = message.payload.get("speed", 100)
|
|||
|
|
|||
|
# 限制最大速度为50
|
|||
|
safe_speed = min(speed, 50)
|
|||
|
|
|||
|
# 构建安全移动命令
|
|||
|
safe_command = {
|
|||
|
"command": "move_safe",
|
|||
|
"x": x,
|
|||
|
"y": y,
|
|||
|
"speed": safe_speed,
|
|||
|
"safety_check": True,
|
|||
|
"original_speed": speed,
|
|||
|
"processed_by": "agv_demo_001",
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
if speed != safe_speed:
|
|||
|
VWED.log.sync_warning(f"AGV速度已限制: {speed} -> {safe_speed}")
|
|||
|
|
|||
|
VWED.log.sync_info(f"AGV安全命令生成: {safe_command}")
|
|||
|
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": safe_command
|
|||
|
}
|
|||
|
|
|||
|
elif command == "stop":
|
|||
|
# 停止命令 - 直接转发
|
|||
|
stop_command = {
|
|||
|
"command": "emergency_stop",
|
|||
|
"reason": message.payload.get("reason", "manual"),
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
VWED.log.sync_info("AGV紧急停止命令")
|
|||
|
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": stop_command
|
|||
|
}
|
|||
|
|
|||
|
else:
|
|||
|
# 未知命令
|
|||
|
VWED.log.sync_warning(f"AGV未知命令: {command}")
|
|||
|
|
|||
|
return {
|
|||
|
"forward": False,
|
|||
|
"response": {
|
|||
|
"status": "error",
|
|||
|
"message": f"不支持的命令: {command}"
|
|||
|
},
|
|||
|
"response_topic": "demo/agv/response"
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
def huarui_agv_processor(message):
|
|||
|
"""华睿AGV处理函数 - 支持华睿协议自动编码/解码"""
|
|||
|
|
|||
|
VWED.log.sync_info(f"华睿AGV收到消息: {message.payload}")
|
|||
|
|
|||
|
# 由于启用了auto_encode=True,华睿协议已自动解码message.payload
|
|||
|
# 这里收到的是标准格式的数据
|
|||
|
|
|||
|
action = message.payload.get("action")
|
|||
|
|
|||
|
if action == "status_update":
|
|||
|
# 状态更新 - 添加业务逻辑处理
|
|||
|
status = message.payload.get("status")
|
|||
|
position = message.payload.get("position", {})
|
|||
|
battery = message.payload.get("battery", 0)
|
|||
|
|
|||
|
VWED.log.sync_info(f"华睿AGV状态: {status}, 位置: {position}, 电量: {battery}%")
|
|||
|
|
|||
|
# 低电量预警
|
|||
|
if battery < 20:
|
|||
|
VWED.log.sync_warning(f"华睿AGV电量不足: {battery}%")
|
|||
|
|
|||
|
# 发送充电指令(会自动编码为华睿协议格式)
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": {
|
|||
|
"action": "move",
|
|||
|
"x": 0, # 充电桩位置
|
|||
|
"y": 0,
|
|||
|
"speed": 30,
|
|||
|
"task_id": f"charge_{VWED.util.timestamp()}"
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
# 正常状态,无需特殊处理
|
|||
|
return {"forward": False}
|
|||
|
|
|||
|
else:
|
|||
|
VWED.log.sync_info(f"华睿AGV消息已处理: {action}")
|
|||
|
return {"forward": False}
|
|||
|
|
|||
|
|
|||
|
def seer_agv_processor(message):
|
|||
|
"""仙工AGV处理函数 - 支持仙工协议自动编码/解码"""
|
|||
|
|
|||
|
VWED.log.sync_info(f"仙工AGV收到消息: {message.payload}")
|
|||
|
|
|||
|
# 仙工协议已自动解码,这里处理标准格式数据
|
|||
|
|
|||
|
action = message.payload.get("action")
|
|||
|
|
|||
|
if action == "status_update":
|
|||
|
status = message.payload.get("status")
|
|||
|
position = message.payload.get("position", {})
|
|||
|
velocity = message.payload.get("velocity", 0)
|
|||
|
|
|||
|
VWED.log.sync_info(f"仙工AGV状态: {status}, 位置: {position}, 速度: {velocity}")
|
|||
|
|
|||
|
# 仙工特定的逻辑处理
|
|||
|
if status == "error":
|
|||
|
VWED.log.sync_error("仙工AGV出现错误,发送重启指令")
|
|||
|
|
|||
|
# 发送重启指令(会自动编码为仙工协议格式)
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": {
|
|||
|
"action": "stop",
|
|||
|
"reason": "error_recovery"
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return {"forward": False}
|
|||
|
|
|||
|
else:
|
|||
|
VWED.log.sync_info(f"仙工AGV消息已处理: {action}")
|
|||
|
return {"forward": False}
|
|||
|
|
|||
|
|
|||
|
def door_access_controller(message):
|
|||
|
"""门禁访问控制函数"""
|
|||
|
|
|||
|
card_id = message.payload.get("card_id")
|
|||
|
door_id = message.payload.get("door_id", "main")
|
|||
|
|
|||
|
VWED.log.sync_info(f"门禁访问请求: 卡号={card_id}, 门={door_id}")
|
|||
|
|
|||
|
# 简单的白名单验证
|
|||
|
whitelist = ["DEMO001", "DEMO002", "DEMO003"]
|
|||
|
|
|||
|
if card_id in whitelist:
|
|||
|
# 授权开门
|
|||
|
open_command = {
|
|||
|
"action": "open",
|
|||
|
"door_id": door_id,
|
|||
|
"card_id": card_id,
|
|||
|
"authorized": True,
|
|||
|
"open_duration": 5, # 5秒
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
VWED.log.sync_info(f"门禁访问已授权: {card_id}")
|
|||
|
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": open_command
|
|||
|
}
|
|||
|
else:
|
|||
|
# 拒绝访问
|
|||
|
VWED.log.sync_warning(f"门禁访问被拒绝: {card_id}")
|
|||
|
|
|||
|
return {
|
|||
|
"forward": False,
|
|||
|
"response": {
|
|||
|
"status": "denied",
|
|||
|
"card_id": card_id,
|
|||
|
"reason": "unauthorized",
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
},
|
|||
|
"response_topic": "demo/door/response"
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
def caller_signal_processor(message):
|
|||
|
"""呼叫器信号处理函数"""
|
|||
|
|
|||
|
caller_id = message.payload.get("caller_id")
|
|||
|
signal_type = message.payload.get("signal_type", "service")
|
|||
|
location = message.payload.get("location", "unknown")
|
|||
|
|
|||
|
VWED.log.sync_info(f"呼叫信号: {caller_id} - {signal_type} @ {location}")
|
|||
|
|
|||
|
if signal_type == "emergency":
|
|||
|
# 紧急呼叫
|
|||
|
response = {
|
|||
|
"type": "emergency_response",
|
|||
|
"caller_id": caller_id,
|
|||
|
"location": location,
|
|||
|
"status": "received",
|
|||
|
"response_team": "security",
|
|||
|
"estimated_time": "2 minutes",
|
|||
|
"message": "紧急响应团队已派遣",
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
VWED.log.sync_error(f"紧急呼叫处理: {caller_id}")
|
|||
|
|
|||
|
elif signal_type == "service":
|
|||
|
# 服务请求
|
|||
|
response = {
|
|||
|
"type": "service_response",
|
|||
|
"caller_id": caller_id,
|
|||
|
"location": location,
|
|||
|
"status": "queued",
|
|||
|
"queue_position": 1,
|
|||
|
"estimated_time": "5 minutes",
|
|||
|
"message": "服务请求已接收",
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
VWED.log.sync_info(f"服务请求处理: {caller_id}")
|
|||
|
|
|||
|
else:
|
|||
|
# 其他类型
|
|||
|
response = {
|
|||
|
"type": "info_response",
|
|||
|
"caller_id": caller_id,
|
|||
|
"status": "received",
|
|||
|
"message": "请求已收到",
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": response
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
def environmental_processor(message):
|
|||
|
"""环境传感器处理函数"""
|
|||
|
|
|||
|
sensor_id = message.payload.get("sensor_id")
|
|||
|
temperature = message.payload.get("temperature")
|
|||
|
humidity = message.payload.get("humidity")
|
|||
|
|
|||
|
VWED.log.sync_info(f"环境数据: 传感器={sensor_id}, 温度={temperature}°C, 湿度={humidity}%")
|
|||
|
|
|||
|
control_commands = []
|
|||
|
|
|||
|
# 温度控制逻辑
|
|||
|
if temperature is not None:
|
|||
|
if temperature > 26:
|
|||
|
control_commands.append({
|
|||
|
"device": "ac",
|
|||
|
"action": "cool",
|
|||
|
"target_temp": 24,
|
|||
|
"reason": f"温度过高: {temperature}°C"
|
|||
|
})
|
|||
|
VWED.log.sync_info(f"启动制冷: 目标温度24°C")
|
|||
|
|
|||
|
elif temperature < 20:
|
|||
|
control_commands.append({
|
|||
|
"device": "heater",
|
|||
|
"action": "heat",
|
|||
|
"target_temp": 22,
|
|||
|
"reason": f"温度过低: {temperature}°C"
|
|||
|
})
|
|||
|
VWED.log.sync_info(f"启动加热: 目标温度22°C")
|
|||
|
|
|||
|
# 湿度控制逻辑
|
|||
|
if humidity is not None and humidity > 70:
|
|||
|
control_commands.append({
|
|||
|
"device": "dehumidifier",
|
|||
|
"action": "on",
|
|||
|
"target_humidity": 60,
|
|||
|
"reason": f"湿度过高: {humidity}%"
|
|||
|
})
|
|||
|
VWED.log.sync_info(f"启动除湿: 目标湿度60%")
|
|||
|
|
|||
|
if control_commands:
|
|||
|
# 有控制指令需要发送
|
|||
|
hvac_control = {
|
|||
|
"sensor_id": sensor_id,
|
|||
|
"controls": control_commands,
|
|||
|
"timestamp": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
return {
|
|||
|
"forward": True,
|
|||
|
"payload": hvac_control
|
|||
|
}
|
|||
|
else:
|
|||
|
# 环境正常,不需要控制
|
|||
|
VWED.log.sync_info("环境参数正常,无需调整")
|
|||
|
return {"forward": False}
|
|||
|
|
|||
|
|
|||
|
# ==================== 测试和管理函数 ====================
|
|||
|
|
|||
|
def test_device_handlers():
|
|||
|
"""测试设备处理器功能"""
|
|||
|
|
|||
|
VWED.log.sync_info("开始测试设备处理器...")
|
|||
|
|
|||
|
# 测试AGV
|
|||
|
VWED.device.sync_publish_message(
|
|||
|
topic="demo/agv/command",
|
|||
|
payload={
|
|||
|
"command": "move",
|
|||
|
"x": 100,
|
|||
|
"y": 200,
|
|||
|
"speed": 80
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
# 测试门禁
|
|||
|
VWED.device.sync_publish_message(
|
|||
|
topic="demo/door/access_request",
|
|||
|
payload={
|
|||
|
"card_id": "DEMO001",
|
|||
|
"door_id": "main_entrance"
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
# 测试呼叫器
|
|||
|
VWED.device.sync_publish_message(
|
|||
|
topic="demo/caller/signal",
|
|||
|
payload={
|
|||
|
"caller_id": "LOBBY_01",
|
|||
|
"signal_type": "service",
|
|||
|
"location": "main_lobby"
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
# 测试传感器
|
|||
|
VWED.device.sync_publish_message(
|
|||
|
topic="demo/sensor/data",
|
|||
|
payload={
|
|||
|
"sensor_id": "ENV_001",
|
|||
|
"temperature": 28,
|
|||
|
"humidity": 75
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
VWED.log.sync_info("设备处理器测试完成")
|
|||
|
|
|||
|
|
|||
|
def get_device_status():
|
|||
|
"""获取所有设备处理器状态"""
|
|||
|
|
|||
|
handlers = VWED.device.get_running_handlers()
|
|||
|
|
|||
|
VWED.log.sync_info("=== 设备处理器状态 ===")
|
|||
|
VWED.log.sync_info(f"设备总数: {handlers.get('device_count', 0)}")
|
|||
|
VWED.log.sync_info(f"运行中: {handlers.get('running_devices', 0)}")
|
|||
|
|
|||
|
devices = handlers.get("devices", {})
|
|||
|
for device_id, status in devices.items():
|
|||
|
VWED.log.sync_info(f"设备 {device_id}: 消息处理 {status.get('total_messages', 0)} 条")
|
|||
|
|
|||
|
return handlers
|
|||
|
|
|||
|
|
|||
|
# ==================== 工具函数 ====================
|
|||
|
|
|||
|
def stop_all_handlers():
|
|||
|
"""停止所有设备处理器(用于测试)"""
|
|||
|
|
|||
|
handlers = ["agv_demo_001", "door_demo_main", "caller_demo_lobby", "sensor_demo_env"]
|
|||
|
|
|||
|
for device_id in handlers:
|
|||
|
try:
|
|||
|
VWED.device.stop_handler(device_id)
|
|||
|
VWED.log.sync_info(f"已停止设备处理器: {device_id}")
|
|||
|
except Exception as e:
|
|||
|
VWED.log.sync_warning(f"停止设备处理器失败 {device_id}: {e}")
|
|||
|
|
|||
|
|
|||
|
def show_device_types():
|
|||
|
"""显示支持的设备类型"""
|
|||
|
|
|||
|
device_types = VWED.device.get_device_types()
|
|||
|
VWED.log.sync_info(f"支持的设备类型: {', '.join(device_types)}")
|
|||
|
|
|||
|
return device_types
|
|||
|
|
|||
|
|
|||
|
def show_device_brands():
|
|||
|
"""显示支持的设备品牌"""
|
|||
|
|
|||
|
device_brands = VWED.device.get_device_brands()
|
|||
|
VWED.log.sync_info(f"支持的设备品牌: {', '.join(device_brands)}")
|
|||
|
|
|||
|
return device_brands
|
|||
|
|
|||
|
|
|||
|
def show_available_protocols():
|
|||
|
"""显示所有可用的协议"""
|
|||
|
|
|||
|
protocols = VWED.device.get_protocols()
|
|||
|
|
|||
|
VWED.log.sync_info("=== 可用的设备协议 ===")
|
|||
|
for protocol_key, protocol_info in protocols.items():
|
|||
|
brand = protocol_info.get("brand", "unknown")
|
|||
|
device_type = protocol_info.get("device_type", "unknown")
|
|||
|
commands = protocol_info.get("supported_commands", [])
|
|||
|
|
|||
|
VWED.log.sync_info(f"协议: {protocol_key}")
|
|||
|
VWED.log.sync_info(f" 品牌: {brand}")
|
|||
|
VWED.log.sync_info(f" 设备类型: {device_type}")
|
|||
|
VWED.log.sync_info(f" 支持指令: {', '.join(commands)}")
|
|||
|
VWED.log.sync_info("")
|
|||
|
|
|||
|
return protocols
|
|||
|
|
|||
|
|
|||
|
def test_protocol_encoding():
|
|||
|
"""测试协议编码功能"""
|
|||
|
|
|||
|
VWED.log.sync_info("=== 测试协议编码功能 ===")
|
|||
|
|
|||
|
# 测试华睿协议编码
|
|||
|
huarui_test = VWED.device.test_protocol_encoding(
|
|||
|
protocol_key="huarui_vehicle",
|
|||
|
test_command={
|
|||
|
"action": "move",
|
|||
|
"x": 100,
|
|||
|
"y": 200,
|
|||
|
"speed": 50,
|
|||
|
"task_id": "test_001"
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
if huarui_test["success"]:
|
|||
|
VWED.log.sync_info("华睿协议编码测试成功:")
|
|||
|
VWED.log.sync_info(f" 原始指令: {huarui_test['original']}")
|
|||
|
VWED.log.sync_info(f" 编码后: {huarui_test['encoded']}")
|
|||
|
else:
|
|||
|
VWED.log.sync_error(f"华睿协议编码测试失败: {huarui_test['error']}")
|
|||
|
|
|||
|
# 测试仙工协议编码
|
|||
|
seer_test = VWED.device.test_protocol_encoding(
|
|||
|
protocol_key="seer_vehicle",
|
|||
|
test_command={
|
|||
|
"action": "move",
|
|||
|
"x": 150,
|
|||
|
"y": 250,
|
|||
|
"speed": 1500, # 仙工使用mm/s
|
|||
|
"task_id": "test_002"
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
if seer_test["success"]:
|
|||
|
VWED.log.sync_info("仙工协议编码测试成功:")
|
|||
|
VWED.log.sync_info(f" 原始指令: {seer_test['original']}")
|
|||
|
VWED.log.sync_info(f" 编码后: {seer_test['encoded']}")
|
|||
|
else:
|
|||
|
VWED.log.sync_error(f"仙工协议编码测试失败: {seer_test['error']}")
|
|||
|
|
|||
|
return {"huarui": huarui_test, "seer": seer_test}
|
|||
|
|
|||
|
|
|||
|
def register_custom_protocol_example():
|
|||
|
"""注册自定义协议示例"""
|
|||
|
|
|||
|
def my_encode(command):
|
|||
|
"""自定义编码函数"""
|
|||
|
return {
|
|||
|
"header": {
|
|||
|
"version": "1.0",
|
|||
|
"timestamp": VWED.util.timestamp()
|
|||
|
},
|
|||
|
"body": {
|
|||
|
"cmd_type": command.get("action", "unknown"),
|
|||
|
"params": command
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
def my_decode(response):
|
|||
|
"""自定义解码函数"""
|
|||
|
body = response.get("body", {})
|
|||
|
return {
|
|||
|
"action": "status_update",
|
|||
|
"data": body,
|
|||
|
"decoded_at": VWED.util.now()
|
|||
|
}
|
|||
|
|
|||
|
# 注册自定义协议
|
|||
|
VWED.device.register_custom_protocol(
|
|||
|
protocol_key="my_custom_agv",
|
|||
|
brand="my_brand",
|
|||
|
device_type="vehicle",
|
|||
|
encode_func=my_encode,
|
|||
|
decode_func=my_decode,
|
|||
|
supported_commands=["move", "stop", "pause", "status"]
|
|||
|
)
|
|||
|
|
|||
|
VWED.log.sync_info("自定义协议注册完成")
|
|||
|
|
|||
|
# 测试自定义协议
|
|||
|
test_result = VWED.device.test_protocol_encoding(
|
|||
|
protocol_key="my_custom_agv",
|
|||
|
test_command={
|
|||
|
"action": "move",
|
|||
|
"x": 300,
|
|||
|
"y": 400
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
if test_result["success"]:
|
|||
|
VWED.log.sync_info("自定义协议测试成功:")
|
|||
|
VWED.log.sync_info(f" 编码结果: {test_result['encoded']}")
|
|||
|
else:
|
|||
|
VWED.log.sync_error(f"自定义协议测试失败: {test_result['error']}")
|
|||
|
|
|||
|
return test_result
|