mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-07 07:25:15 +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] 开始注册设备和资源...")
|
logger.info("[UniLab Register] 开始注册设备和资源...")
|
||||||
|
|
||||||
# # 注册设备信息
|
# 注册设备信息
|
||||||
# for device_info in lab_registry.obtain_registry_device_info():
|
for device_info in lab_registry.obtain_registry_device_info():
|
||||||
# mqtt_client.publish_registry(device_info["id"], device_info, False)
|
mqtt_client.publish_registry(device_info["id"], device_info, False)
|
||||||
# logger.debug(f"[UniLab Register] 注册设备: {device_info['id']}")
|
logger.debug(f"[UniLab Register] 注册设备: {device_info['id']}")
|
||||||
#
|
|
||||||
# # 注册资源信息
|
# 注册资源信息
|
||||||
# for resource_info in lab_registry.obtain_registry_resource_info():
|
for resource_info in lab_registry.obtain_registry_resource_info():
|
||||||
# mqtt_client.publish_registry(resource_info["id"], resource_info, False)
|
mqtt_client.publish_registry(resource_info["id"], resource_info, False)
|
||||||
# logger.debug(f"[UniLab Register] 注册资源: {resource_info['id']}")
|
logger.debug(f"[UniLab Register] 注册资源: {resource_info['id']}")
|
||||||
#
|
|
||||||
# time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
logger.info("[UniLab Register] 设备和资源注册完成.")
|
logger.info("[UniLab Register] 设备和资源注册完成.")
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class HTTPClient:
|
|||||||
Returns:
|
Returns:
|
||||||
Response: API响应对象
|
Response: API响应对象
|
||||||
"""
|
"""
|
||||||
return True
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{self.remote_addr}/lab/resource/edge/batch_create/?database_process_later={1 if database_process_later else 0}",
|
f"{self.remote_addr}/lab/resource/edge/batch_create/?database_process_later={1 if database_process_later else 0}",
|
||||||
json=resources,
|
json=resources,
|
||||||
@@ -61,7 +60,6 @@ class HTTPClient:
|
|||||||
Returns:
|
Returns:
|
||||||
Response: API响应对象
|
Response: API响应对象
|
||||||
"""
|
"""
|
||||||
return True
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{self.remote_addr}/lab/resource/?database_process_later={1 if database_process_later else 0}",
|
f"{self.remote_addr}/lab/resource/?database_process_later={1 if database_process_later else 0}",
|
||||||
json=resources,
|
json=resources,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Web页面模块
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import traceback
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ from jinja2 import Environment, FileSystemLoader
|
|||||||
from unilabos.config.config import BasicConfig
|
from unilabos.config.config import BasicConfig
|
||||||
from unilabos.registry.registry import lab_registry
|
from unilabos.registry.registry import lab_registry
|
||||||
from unilabos.ros.msgs.message_converter import msg_converter_manager
|
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.utils.type_check import TypeEncoder
|
||||||
from unilabos.app.web.utils.device_utils import get_registry_info
|
from unilabos.app.web.utils.device_utils import get_registry_info
|
||||||
from unilabos.app.web.utils.host_utils import get_host_node_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
|
return html
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
debug(traceback.format_exc())
|
||||||
error(f"生成状态页面时出错: {str(e)}")
|
error(f"生成状态页面时出错: {str(e)}")
|
||||||
raise HTTPException(status_code=500, detail=f"Error generating status page: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"Error generating status page: {str(e)}")
|
||||||
|
|
||||||
|
|||||||
@@ -4899,7 +4899,7 @@ liquid_handler.biomek:
|
|||||||
none_keys:
|
none_keys:
|
||||||
default: []
|
default: []
|
||||||
description: '参数: none_keys'
|
description: '参数: none_keys'
|
||||||
type: string
|
type: array
|
||||||
protocol_author:
|
protocol_author:
|
||||||
description: '参数: protocol_author'
|
description: '参数: protocol_author'
|
||||||
type: string
|
type: string
|
||||||
@@ -5287,7 +5287,7 @@ liquid_handler.biomek:
|
|||||||
none_keys:
|
none_keys:
|
||||||
default: []
|
default: []
|
||||||
description: '参数: none_keys'
|
description: '参数: none_keys'
|
||||||
type: string
|
type: array
|
||||||
offsets:
|
offsets:
|
||||||
description: '参数: offsets'
|
description: '参数: offsets'
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ virtual_column:
|
|||||||
properties:
|
properties:
|
||||||
config:
|
config:
|
||||||
description: '参数: config'
|
description: '参数: config'
|
||||||
type: string
|
type: object
|
||||||
device_id:
|
device_id:
|
||||||
description: '参数: device_id'
|
description: '参数: device_id'
|
||||||
type: string
|
type: string
|
||||||
@@ -1370,7 +1370,7 @@ virtual_heatchill:
|
|||||||
properties:
|
properties:
|
||||||
config:
|
config:
|
||||||
description: '参数: config'
|
description: '参数: config'
|
||||||
type: string
|
type: object
|
||||||
device_id:
|
device_id:
|
||||||
description: '参数: device_id'
|
description: '参数: device_id'
|
||||||
type: string
|
type: string
|
||||||
@@ -1893,7 +1893,7 @@ virtual_multiway_valve:
|
|||||||
module: unilabos.devices.virtual.virtual_multiway_valve:VirtualMultiwayValve
|
module: unilabos.devices.virtual.virtual_multiway_valve:VirtualMultiwayValve
|
||||||
status_types:
|
status_types:
|
||||||
current_position: int
|
current_position: int
|
||||||
get_available_ports: typing:Dict
|
get_available_ports: dict
|
||||||
get_available_positions: list
|
get_available_positions: list
|
||||||
get_current_port: str
|
get_current_port: str
|
||||||
get_current_position: int
|
get_current_position: int
|
||||||
@@ -2372,7 +2372,7 @@ virtual_pump:
|
|||||||
properties:
|
properties:
|
||||||
config:
|
config:
|
||||||
description: '参数: config'
|
description: '参数: config'
|
||||||
type: string
|
type: object
|
||||||
device_id:
|
device_id:
|
||||||
description: '参数: device_id'
|
description: '参数: device_id'
|
||||||
type: string
|
type: string
|
||||||
@@ -3026,8 +3026,7 @@ virtual_solenoid_valve:
|
|||||||
auto-close:
|
auto-close:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
goal_default:
|
goal_default: {}
|
||||||
kwargs: null
|
|
||||||
handles: []
|
handles: []
|
||||||
result: {}
|
result: {}
|
||||||
schema:
|
schema:
|
||||||
@@ -3036,12 +3035,8 @@ virtual_solenoid_valve:
|
|||||||
feedback: {}
|
feedback: {}
|
||||||
goal:
|
goal:
|
||||||
description: UniLabJsonCommand close 的参数schema
|
description: UniLabJsonCommand close 的参数schema
|
||||||
properties:
|
properties: {}
|
||||||
kwargs:
|
required: []
|
||||||
description: '参数: kwargs'
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kwargs
|
|
||||||
type: object
|
type: object
|
||||||
result: {}
|
result: {}
|
||||||
required:
|
required:
|
||||||
@@ -3136,8 +3131,7 @@ virtual_solenoid_valve:
|
|||||||
auto-open:
|
auto-open:
|
||||||
feedback: {}
|
feedback: {}
|
||||||
goal: {}
|
goal: {}
|
||||||
goal_default:
|
goal_default: {}
|
||||||
kwargs: null
|
|
||||||
handles: []
|
handles: []
|
||||||
result: {}
|
result: {}
|
||||||
schema:
|
schema:
|
||||||
@@ -3146,12 +3140,8 @@ virtual_solenoid_valve:
|
|||||||
feedback: {}
|
feedback: {}
|
||||||
goal:
|
goal:
|
||||||
description: UniLabJsonCommand open 的参数schema
|
description: UniLabJsonCommand open 的参数schema
|
||||||
properties:
|
properties: {}
|
||||||
kwargs:
|
required: []
|
||||||
description: '参数: kwargs'
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kwargs
|
|
||||||
type: object
|
type: object
|
||||||
result: {}
|
result: {}
|
||||||
required:
|
required:
|
||||||
@@ -3185,7 +3175,6 @@ virtual_solenoid_valve:
|
|||||||
goal: {}
|
goal: {}
|
||||||
goal_default:
|
goal_default:
|
||||||
command: null
|
command: null
|
||||||
kwargs: null
|
|
||||||
handles: []
|
handles: []
|
||||||
result: {}
|
result: {}
|
||||||
schema:
|
schema:
|
||||||
@@ -3198,12 +3187,8 @@ virtual_solenoid_valve:
|
|||||||
command:
|
command:
|
||||||
description: '参数: command'
|
description: '参数: command'
|
||||||
type: string
|
type: string
|
||||||
kwargs:
|
|
||||||
description: '参数: kwargs'
|
|
||||||
type: string
|
|
||||||
required:
|
required:
|
||||||
- command
|
- command
|
||||||
- kwargs
|
|
||||||
type: object
|
type: object
|
||||||
result: {}
|
result: {}
|
||||||
required:
|
required:
|
||||||
@@ -3216,7 +3201,6 @@ virtual_solenoid_valve:
|
|||||||
goal: {}
|
goal: {}
|
||||||
goal_default:
|
goal_default:
|
||||||
command: null
|
command: null
|
||||||
kwargs: null
|
|
||||||
handles: []
|
handles: []
|
||||||
result: {}
|
result: {}
|
||||||
schema:
|
schema:
|
||||||
@@ -3229,11 +3213,7 @@ virtual_solenoid_valve:
|
|||||||
command:
|
command:
|
||||||
description: '参数: command'
|
description: '参数: command'
|
||||||
type: string
|
type: string
|
||||||
kwargs:
|
required: []
|
||||||
description: '参数: kwargs'
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kwargs
|
|
||||||
type: object
|
type: object
|
||||||
result: {}
|
result: {}
|
||||||
required:
|
required:
|
||||||
@@ -3852,7 +3832,7 @@ virtual_stirrer:
|
|||||||
properties:
|
properties:
|
||||||
config:
|
config:
|
||||||
description: '参数: config'
|
description: '参数: config'
|
||||||
type: string
|
type: object
|
||||||
device_id:
|
device_id:
|
||||||
description: '参数: device_id'
|
description: '参数: device_id'
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
@@ -459,6 +459,8 @@ class HostNode(BaseROS2DeviceNode):
|
|||||||
self.devices_instances[device_id] = d
|
self.devices_instances[device_id] = d
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
for action_name, action_value_mapping in d._ros_node._action_value_mappings.items():
|
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}"
|
action_id = f"/devices/{device_id}/{action_name}"
|
||||||
if action_id not in self._action_clients:
|
if action_id not in self._action_clients:
|
||||||
action_type = action_value_mapping["type"]
|
action_type = action_value_mapping["type"]
|
||||||
|
|||||||
@@ -216,7 +216,8 @@ class ImportManager:
|
|||||||
f"{module_path} 失败(将使用静态分析,"
|
f"{module_path} 失败(将使用静态分析,"
|
||||||
f"建议修复导入错误,以实现更好的注册表识别效果!): {e}"
|
f"建议修复导入错误,以实现更好的注册表识别效果!): {e}"
|
||||||
)
|
)
|
||||||
|
use_dynamic = False
|
||||||
|
if not use_dynamic:
|
||||||
# 尝试静态分析
|
# 尝试静态分析
|
||||||
static_info = None
|
static_info = None
|
||||||
try:
|
try:
|
||||||
@@ -351,15 +352,32 @@ class ImportManager:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def _analyze_method_signature(self, method) -> Dict[str, Any]:
|
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 = []
|
args = []
|
||||||
num_required = 0
|
num_required = 0
|
||||||
|
|
||||||
for param_name, param in signature.parameters.items():
|
for param_name, param in signature.parameters.items():
|
||||||
|
# 跳过self参数
|
||||||
if param_name == "self":
|
if param_name == "self":
|
||||||
continue
|
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
|
is_required = param.default == inspect.Parameter.empty
|
||||||
if is_required:
|
if is_required:
|
||||||
num_required += 1
|
num_required += 1
|
||||||
@@ -392,10 +410,15 @@ class ImportManager:
|
|||||||
"""将类型注解转换为字符串"""
|
"""将类型注解转换为字符串"""
|
||||||
if annotation == inspect.Parameter.empty:
|
if annotation == inspect.Parameter.empty:
|
||||||
return "Any" # 如果没有注解,返回Any
|
return "Any" # 如果没有注解,返回Any
|
||||||
|
|
||||||
if annotation is None:
|
if annotation is None:
|
||||||
return "None" # 明确的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__"):
|
if hasattr(annotation, "__name__"):
|
||||||
# 如果是内置类型
|
# 如果是内置类型
|
||||||
@@ -404,22 +427,13 @@ class ImportManager:
|
|||||||
else:
|
else:
|
||||||
# 如果是自定义类,返回完整路径
|
# 如果是自定义类,返回完整路径
|
||||||
return f"{annotation.__module__}:{annotation.__name__}"
|
return f"{annotation.__module__}:{annotation.__name__}"
|
||||||
|
|
||||||
# 如果是typing模块的类型
|
# 如果是typing模块的类型
|
||||||
elif hasattr(annotation, "_name"):
|
elif hasattr(annotation, "_name"):
|
||||||
return annotation._name
|
return annotation._name
|
||||||
|
|
||||||
# 如果是字符串形式的类型注解
|
# 如果是字符串形式的类型注解
|
||||||
elif isinstance(annotation, str):
|
elif isinstance(annotation, str):
|
||||||
return annotation
|
return annotation
|
||||||
|
|
||||||
# 其他情况,尝试转换为字符串
|
|
||||||
else:
|
else:
|
||||||
annotation_str = str(annotation)
|
|
||||||
# 处理typing模块的复杂类型
|
|
||||||
if "typing." in annotation_str:
|
|
||||||
# 简化typing类型显示
|
|
||||||
return annotation_str.replace("typing.", "")
|
|
||||||
return annotation_str
|
return annotation_str
|
||||||
|
|
||||||
def _is_property_method(self, node: ast.FunctionDef) -> bool:
|
def _is_property_method(self, node: ast.FunctionDef) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user