mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-04 13:25:13 +00:00
修复部分识别error
This commit is contained in:
@@ -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] 设备和资源注册完成.")
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)}")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user