update registry with nested obj

This commit is contained in:
Xuwznln
2025-09-19 03:44:18 +08:00
parent e5006285df
commit 01f8816597
14 changed files with 144 additions and 81 deletions

View File

@@ -94,7 +94,7 @@ serial:
port:
type: string
resource_tracker:
type: string
type: object
required:
- device_id
- port

View File

@@ -63,7 +63,7 @@ camera.USB:
default: 0.1
type: number
resource_tracker:
type: string
type: object
required: []
type: object
data:

View File

@@ -170,7 +170,7 @@ hplc.agilent:
module: unilabos.devices.hplc.AgilentHPLC:HPLCDriver
status_types:
could_run: bool
data_file: list
data_file: String
device_status: str
driver_init_ok: bool
finish_status: str
@@ -195,6 +195,8 @@ hplc.agilent:
could_run:
type: boolean
data_file:
items:
type: string
type: array
device_status:
type: string

View File

@@ -4508,14 +4508,22 @@ liquid_handler.biomek:
bind_parent_id:
type: string
liquid_input_slot:
items:
type: integer
type: array
liquid_type:
items:
type: string
type: array
liquid_volume:
items:
type: integer
type: array
resource_tracker:
type: string
type: object
resources:
items:
type: object
type: array
slot_on_deck:
type: integer
@@ -4559,10 +4567,16 @@ liquid_handler.biomek:
id:
type: string
liquid_input_wells:
items:
type: string
type: array
liquid_type:
items:
type: string
type: array
liquid_volume:
items:
type: integer
type: array
parent:
type: string
@@ -6039,6 +6053,8 @@ liquid_handler.prcxi:
properties:
none_keys:
default: []
items:
type: string
type: array
protocol_author:
default: ''
@@ -6139,7 +6155,7 @@ liquid_handler.prcxi:
default: 0
type: number
well:
type: string
type: object
required:
- well
type: object
@@ -8358,7 +8374,7 @@ liquid_handler.prcxi:
default: false
type: string
deck:
type: string
type: object
host:
type: string
matrix_id:

View File

@@ -832,7 +832,7 @@ syringe_pump_with_valve.runze.SY03B-T06:
default: 25.0
type: number
mode:
type: string
type: object
port:
type: string
required:
@@ -1352,7 +1352,7 @@ syringe_pump_with_valve.runze.SY03B-T08:
default: 25.0
type: number
mode:
type: string
type: object
port:
type: string
required:

View File

@@ -133,7 +133,7 @@ robotic_arm.SCARA_with_slider.virtual:
goal:
properties:
ros_node:
type: string
type: object
required:
- ros_node
type: object
@@ -753,7 +753,7 @@ robotic_arm.elite:
module: unilabos.devices.arm.elite_robot:EliteRobot
status_types:
actual_joint_positions: String
arm_pose: list
arm_pose: String
type: python
config_info: []
description: Elite robot arm
@@ -775,6 +775,8 @@ robotic_arm.elite:
actual_joint_positions:
type: string
arm_pose:
items:
type: number
type: array
required:
- arm_pose

View File

@@ -37,7 +37,7 @@ linear_motion.grbl:
goal:
properties:
position:
type: string
type: object
required:
- position
type: object
@@ -450,6 +450,8 @@ linear_motion.grbl:
- 0
- -80
- 0
items:
type: integer
type: array
port:
type: string
@@ -459,7 +461,7 @@ linear_motion.grbl:
data:
properties:
position:
type: string
type: object
spindle_speed:
type: number
status:
@@ -605,7 +607,7 @@ linear_motion.toyo_xyz.sim:
goal:
properties:
ros_node:
type: string
type: object
required:
- ros_node
type: object

View File

@@ -6129,7 +6129,7 @@ workstation:
protocol_type:
type: string
resource_tracker:
type: string
type: object
required:
- device_id
- children
@@ -6171,14 +6171,22 @@ workstation.example:
bind_parent_id:
type: string
liquid_input_slot:
items:
type: integer
type: array
liquid_type:
items:
type: string
type: array
liquid_volume:
items:
type: integer
type: array
resource_tracker:
type: string
type: object
resources:
items:
type: object
type: array
slot_on_deck:
type: integer
@@ -6213,9 +6221,9 @@ workstation.example:
goal:
properties:
base_plate:
type: string
type: object
tip_rack:
type: string
type: object
required:
- tip_rack
- base_plate
@@ -6241,9 +6249,9 @@ workstation.example:
goal:
properties:
from_plate:
type: string
type: object
to_base_plate:
type: string
type: object
required:
- from_plate
- to_base_plate
@@ -6271,7 +6279,7 @@ workstation.example:
protocol_type:
type: string
resource_tracker:
type: string
type: object
required:
- device_id
- children

View File

@@ -5,7 +5,7 @@ import sys
import inspect
import importlib
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Dict, List, Union, Tuple
import yaml
@@ -294,7 +294,7 @@ class Registry:
logger.warning(f"[UniLab Registry] 设备 {device_id}{field_name} 类型为空,跳过替换")
return type_name
convert_manager = { # 将python基本对象转为ros2基本对象
"str": "String",
"builtins:str": "String",
"bool": "Bool",
"int": "Int64",
"float": "Float64",
@@ -310,37 +310,73 @@ class Registry:
logger.error(f"[UniLab Registry] 无法找到类型 '{type_name}' 用于设备 {device_id}{field_name}")
sys.exit(1)
def _get_json_schema_type(self, type_str: str) -> str:
"""
根据类型字符串返回对应的JSON Schema类型
Args:
type_str: 类型字符串
Returns:
JSON Schema类型字符串
"""
type_lower = type_str.lower()
type_mapping = {
("str", "string"): "string",
("int", "integer"): "integer",
("float", "number"): "number",
("bool", "boolean"): "boolean",
("list", "array"): "array",
("dict", "object"): "object",
}
# 遍历映射找到匹配的类型
for type_variants, json_type in type_mapping.items():
if type_lower in type_variants:
return json_type
# 特殊处理包含冒号的类型如ROS消息类型
if ":" in type_lower:
return "object"
# 默认返回字符串类型
return "string"
def _generate_schema_from_info(
self,
param_name: str,
param_type: str,
param_type: Union[str, Tuple[str]],
param_default: Any,
) -> Dict[str, Any]:
"""
根据参数信息生成JSON Schema
"""
prop_schema = {}
# 根据类型设置schema FIXME 不完整
if param_type:
param_type_lower = param_type.lower()
if param_type_lower in ["str", "string"]:
prop_schema["type"] = "string"
elif param_type_lower in ["int", "integer"]:
prop_schema["type"] = "integer"
elif param_type_lower in ["float", "number"]:
prop_schema["type"] = "number"
elif param_type_lower in ["bool", "boolean"]:
prop_schema["type"] = "boolean"
elif param_type_lower in ["list", "array"]:
prop_schema["type"] = "array"
elif param_type_lower in ["dict", "object"]:
prop_schema["type"] = "object"
# 处理嵌套类型Tuple[str]
if isinstance(param_type, tuple):
if len(param_type) == 2:
outer_type, inner_type = param_type
outer_json_type = self._get_json_schema_type(outer_type)
inner_json_type = self._get_json_schema_type(inner_type)
prop_schema["type"] = outer_json_type
# 根据外层类型设置内层类型信息
if outer_json_type == "array":
prop_schema["items"] = {"type": inner_json_type}
elif outer_json_type == "object":
prop_schema["additionalProperties"] = {"type": inner_json_type}
else:
# 默认为字符串类型
# 不是标准的嵌套类型,默认为字符串
prop_schema["type"] = "string"
else:
# 如果没有类型信息,默认为字符串
prop_schema["type"] = "string"
# 处理非嵌套类型
if param_type:
prop_schema["type"] = self._get_json_schema_type(param_type)
else:
# 如果没有类型信息,默认为字符串
prop_schema["type"] = "string"
# 设置默认值
if param_default is not None:
@@ -456,7 +492,7 @@ class Registry:
{k: v["return_type"] for k, v in enhanced_info["status_methods"].items()}
)
for status_name, status_type in device_config["class"]["status_types"].items():
if status_type in ["Any", "None", "Unknown"]:
if isinstance(status_type, tuple) or status_type in ["Any", "None", "Unknown"]:
status_type = "String" # 替换成ROS的String便于显示
device_config["class"]["status_types"][status_name] = status_type
target_type = self._replace_type_with_class(status_type, device_id, f"状态 {status_name}")