修复部分识别error

This commit is contained in:
Xuwznln
2025-06-28 10:52:34 +08:00
parent 817e88cfc4
commit 9be6e1069a
7 changed files with 66 additions and 70 deletions

View File

@@ -13,17 +13,17 @@ def register_devices_and_resources(mqtt_client, lab_registry):
"""
logger.info("[UniLab Register] 开始注册设备和资源...")
# # 注册设备信息
# for device_info in lab_registry.obtain_registry_device_info():
# mqtt_client.publish_registry(device_info["id"], device_info, False)
# logger.debug(f"[UniLab Register] 注册设备: {device_info['id']}")
#
# # 注册资源信息
# for resource_info in lab_registry.obtain_registry_resource_info():
# mqtt_client.publish_registry(resource_info["id"], resource_info, False)
# logger.debug(f"[UniLab Register] 注册资源: {resource_info['id']}")
#
# time.sleep(10)
# 注册设备信息
for device_info in lab_registry.obtain_registry_device_info():
mqtt_client.publish_registry(device_info["id"], device_info, False)
logger.debug(f"[UniLab Register] 注册设备: {device_info['id']}")
# 注册资源信息
for resource_info in lab_registry.obtain_registry_resource_info():
mqtt_client.publish_registry(resource_info["id"], resource_info, False)
logger.debug(f"[UniLab Register] 注册资源: {resource_info['id']}")
time.sleep(10)
logger.info("[UniLab Register] 设备和资源注册完成.")

View File

@@ -40,7 +40,6 @@ class HTTPClient:
Returns:
Response: API响应对象
"""
return True
response = requests.post(
f"{self.remote_addr}/lab/resource/edge/batch_create/?database_process_later={1 if database_process_later else 0}",
json=resources,
@@ -61,7 +60,6 @@ class HTTPClient:
Returns:
Response: API响应对象
"""
return True
response = requests.post(
f"{self.remote_addr}/lab/resource/?database_process_later={1 if database_process_later else 0}",
json=resources,

View File

@@ -7,6 +7,7 @@ Web页面模块
import json
import os
import sys
import traceback
from pathlib import Path
from typing import Dict
@@ -17,7 +18,7 @@ from jinja2 import Environment, FileSystemLoader
from unilabos.config.config import BasicConfig
from unilabos.registry.registry import lab_registry
from unilabos.ros.msgs.message_converter import msg_converter_manager
from unilabos.utils.log import error
from unilabos.utils.log import error, debug
from unilabos.utils.type_check import TypeEncoder
from unilabos.app.web.utils.device_utils import get_registry_info
from unilabos.app.web.utils.host_utils import get_host_node_info
@@ -123,6 +124,7 @@ def setup_web_pages(router: APIRouter) -> None:
return html
except Exception as e:
debug(traceback.format_exc())
error(f"生成状态页面时出错: {str(e)}")
raise HTTPException(status_code=500, detail=f"Error generating status page: {str(e)}")

View File

@@ -4899,7 +4899,7 @@ liquid_handler.biomek:
none_keys:
default: []
description: '参数: none_keys'
type: string
type: array
protocol_author:
description: '参数: protocol_author'
type: string
@@ -5287,7 +5287,7 @@ liquid_handler.biomek:
none_keys:
default: []
description: '参数: none_keys'
type: string
type: array
offsets:
description: '参数: offsets'
type: string

View File

@@ -402,7 +402,7 @@ virtual_column:
properties:
config:
description: '参数: config'
type: string
type: object
device_id:
description: '参数: device_id'
type: string
@@ -1370,7 +1370,7 @@ virtual_heatchill:
properties:
config:
description: '参数: config'
type: string
type: object
device_id:
description: '参数: device_id'
type: string
@@ -1893,7 +1893,7 @@ virtual_multiway_valve:
module: unilabos.devices.virtual.virtual_multiway_valve:VirtualMultiwayValve
status_types:
current_position: int
get_available_ports: typing:Dict
get_available_ports: dict
get_available_positions: list
get_current_port: str
get_current_position: int
@@ -2372,7 +2372,7 @@ virtual_pump:
properties:
config:
description: '参数: config'
type: string
type: object
device_id:
description: '参数: device_id'
type: string
@@ -3026,8 +3026,7 @@ virtual_solenoid_valve:
auto-close:
feedback: {}
goal: {}
goal_default:
kwargs: null
goal_default: {}
handles: []
result: {}
schema:
@@ -3036,12 +3035,8 @@ virtual_solenoid_valve:
feedback: {}
goal:
description: UniLabJsonCommand close 的参数schema
properties:
kwargs:
description: '参数: kwargs'
type: string
required:
- kwargs
properties: {}
required: []
type: object
result: {}
required:
@@ -3136,8 +3131,7 @@ virtual_solenoid_valve:
auto-open:
feedback: {}
goal: {}
goal_default:
kwargs: null
goal_default: {}
handles: []
result: {}
schema:
@@ -3146,12 +3140,8 @@ virtual_solenoid_valve:
feedback: {}
goal:
description: UniLabJsonCommand open 的参数schema
properties:
kwargs:
description: '参数: kwargs'
type: string
required:
- kwargs
properties: {}
required: []
type: object
result: {}
required:
@@ -3185,7 +3175,6 @@ virtual_solenoid_valve:
goal: {}
goal_default:
command: null
kwargs: null
handles: []
result: {}
schema:
@@ -3198,12 +3187,8 @@ virtual_solenoid_valve:
command:
description: '参数: command'
type: string
kwargs:
description: '参数: kwargs'
type: string
required:
- command
- kwargs
type: object
result: {}
required:
@@ -3216,7 +3201,6 @@ virtual_solenoid_valve:
goal: {}
goal_default:
command: null
kwargs: null
handles: []
result: {}
schema:
@@ -3229,11 +3213,7 @@ virtual_solenoid_valve:
command:
description: '参数: command'
type: string
kwargs:
description: '参数: kwargs'
type: string
required:
- kwargs
required: []
type: object
result: {}
required:
@@ -3852,7 +3832,7 @@ virtual_stirrer:
properties:
config:
description: '参数: config'
type: string
type: object
device_id:
description: '参数: device_id'
type: string

View File

@@ -459,6 +459,8 @@ class HostNode(BaseROS2DeviceNode):
self.devices_instances[device_id] = d
# noinspection PyProtectedMember
for action_name, action_value_mapping in d._ros_node._action_value_mappings.items():
if action_name.startswith("auto-"):
continue
action_id = f"/devices/{device_id}/{action_name}"
if action_id not in self._action_clients:
action_type = action_value_mapping["type"]

View File

@@ -216,15 +216,16 @@ class ImportManager:
f"{module_path} 失败(将使用静态分析,"
f"建议修复导入错误,以实现更好的注册表识别效果!): {e}"
)
# 尝试静态分析
static_info = None
try:
static_info = self._get_static_class_info(module_path)
result["static_analysis_success"] = True
logger.debug(f"[ImportManager] 静态分析类 {module_path} 成功")
except Exception as e:
logger.warning(f"[ImportManager] 静态分析类 {module_path} 失败: {e}")
use_dynamic = False
if not use_dynamic:
# 尝试静态分析
static_info = None
try:
static_info = self._get_static_class_info(module_path)
result["static_analysis_success"] = True
logger.debug(f"[ImportManager] 静态分析类 {module_path} 成功")
except Exception as e:
logger.warning(f"[ImportManager] 静态分析类 {module_path} 失败: {e}")
# 合并信息(优先使用动态导入的信息)
if dynamic_info:
@@ -351,15 +352,32 @@ class ImportManager:
return result
def _analyze_method_signature(self, method) -> Dict[str, Any]:
"""分析方法签名"""
signature = inspect.signature(method)
"""
分析方法签名,提取具体的命名参数信息
注意:此方法会跳过*args和**kwargs只提取具体的命名参数
这样可以确保通过**dict方式传参时的准确性
示例用法:
method_info = self._analyze_method_signature(some_method)
params = {"param1": "value1", "param2": "value2"}
result = some_method(**params) # 安全的参数传递
"""
signature = inspect.signature(method)
args = []
num_required = 0
for param_name, param in signature.parameters.items():
# 跳过self参数
if param_name == "self":
continue
# 跳过*args和**kwargs参数
if param.kind == param.VAR_POSITIONAL: # *args
continue
if param.kind == param.VAR_KEYWORD: # **kwargs
continue
is_required = param.default == inspect.Parameter.empty
if is_required:
num_required += 1
@@ -392,10 +410,15 @@ class ImportManager:
"""将类型注解转换为字符串"""
if annotation == inspect.Parameter.empty:
return "Any" # 如果没有注解返回Any
if annotation is None:
return "None" # 明确的None类型
annotation_str = str(annotation)
# 处理typing模块的复杂类型
if "typing." in annotation_str:
# 简化typing类型显示
return (
annotation_str.replace("typing.", "") if getattr(annotation, "_name", None) is None else annotation._name.lower()
)
# 如果是类型对象
if hasattr(annotation, "__name__"):
# 如果是内置类型
@@ -404,22 +427,13 @@ class ImportManager:
else:
# 如果是自定义类,返回完整路径
return f"{annotation.__module__}:{annotation.__name__}"
# 如果是typing模块的类型
elif hasattr(annotation, "_name"):
return annotation._name
# 如果是字符串形式的类型注解
elif isinstance(annotation, str):
return annotation
# 其他情况,尝试转换为字符串
else:
annotation_str = str(annotation)
# 处理typing模块的复杂类型
if "typing." in annotation_str:
# 简化typing类型显示
return annotation_str.replace("typing.", "")
return annotation_str
def _is_property_method(self, node: ast.FunctionDef) -> bool: