mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-19 05:51:17 +00:00
Resource update & asyncio fix
correct bioyond config prcxi example fix append_resource fix regularcontainer fix cancel error fix resource_get param fix json dumps support name change during materials change enable slave mode change uuid logger to trace level correct remove_resource stats disable slave connect websocket adjust with_children param modify devices to use correct executor (sleep, create_task) support sleep and create_task in node fix run async execution error
This commit is contained in:
@@ -2,7 +2,7 @@ import traceback
|
||||
import uuid
|
||||
from pydantic import BaseModel, field_serializer, field_validator
|
||||
from pydantic import Field
|
||||
from typing import List, Tuple, Any, Dict, Literal, Optional, cast, TYPE_CHECKING
|
||||
from typing import List, Tuple, Any, Dict, Literal, Optional, cast, TYPE_CHECKING, Union
|
||||
|
||||
from unilabos.utils.log import logger
|
||||
|
||||
@@ -60,7 +60,7 @@ class ResourceDict(BaseModel):
|
||||
icon: str = Field(description="Resource icon", default="")
|
||||
parent_uuid: Optional["str"] = Field(description="Parent resource uuid", default=None) # 先设定parent_uuid
|
||||
parent: Optional["ResourceDict"] = Field(description="Parent resource object", default=None, exclude=True)
|
||||
type: Literal["device"] | str = Field(description="Resource type")
|
||||
type: Union[Literal["device"], str] = Field(description="Resource type")
|
||||
klass: str = Field(alias="class", description="Resource class name")
|
||||
position: ResourceDictPosition = Field(description="Resource position", default_factory=ResourceDictPosition)
|
||||
pose: ResourceDictPosition = Field(description="Resource position", default_factory=ResourceDictPosition)
|
||||
@@ -848,15 +848,13 @@ class DeviceNodeResourceTracker(object):
|
||||
extra: extra字典值
|
||||
"""
|
||||
if isinstance(resource, dict):
|
||||
# ⭐ 修复:合并extra而不是覆盖
|
||||
current_extra = resource.get("extra", {})
|
||||
current_extra.update(extra)
|
||||
resource["extra"] = current_extra
|
||||
c_extra = resource.get("extra", {})
|
||||
c_extra.update(extra)
|
||||
resource["extra"] = c_extra
|
||||
else:
|
||||
# ⭐ 修复:合并unilabos_extra而不是覆盖
|
||||
current_extra = getattr(resource, "unilabos_extra", {})
|
||||
current_extra.update(extra)
|
||||
setattr(resource, "unilabos_extra", current_extra)
|
||||
c_extra = getattr(resource, "unilabos_extra", {})
|
||||
c_extra.update(extra)
|
||||
setattr(resource, "unilabos_extra", c_extra)
|
||||
|
||||
def _traverse_and_process(self, resource, process_func) -> int:
|
||||
"""
|
||||
@@ -900,7 +898,7 @@ class DeviceNodeResourceTracker(object):
|
||||
new_uuid = name_to_uuid_map[resource_name]
|
||||
self.set_resource_uuid(res, new_uuid)
|
||||
self.uuid_to_resources[new_uuid] = res
|
||||
logger.debug(f"设置资源UUID: {resource_name} -> {new_uuid}")
|
||||
logger.trace(f"设置资源UUID: {resource_name} -> {new_uuid}")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -923,7 +921,8 @@ class DeviceNodeResourceTracker(object):
|
||||
if resource_name and resource_name in name_to_extra_map:
|
||||
extra = name_to_extra_map[resource_name]
|
||||
self.set_resource_extra(res, extra)
|
||||
logger.debug(f"设置资源Extra: {resource_name} -> {extra}")
|
||||
if len(extra):
|
||||
logger.debug(f"设置资源Extra: {resource_name} -> {extra}")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -933,7 +932,7 @@ class DeviceNodeResourceTracker(object):
|
||||
"""
|
||||
递归遍历资源树,更新所有节点的uuid
|
||||
|
||||
Args:0
|
||||
Args:
|
||||
resource: 资源对象(可以是dict或实例)
|
||||
uuid_map: uuid映射字典,{old_uuid: new_uuid}
|
||||
|
||||
@@ -958,6 +957,27 @@ class DeviceNodeResourceTracker(object):
|
||||
|
||||
return self._traverse_and_process(resource, process)
|
||||
|
||||
def loop_gather_uuid(self, resource) -> List[str]:
|
||||
"""
|
||||
递归遍历资源树,收集所有节点的uuid
|
||||
|
||||
Args:
|
||||
resource: 资源对象(可以是dict或实例)
|
||||
|
||||
Returns:
|
||||
收集到的uuid列表
|
||||
"""
|
||||
uuid_list = []
|
||||
|
||||
def process(res):
|
||||
current_uuid = self._get_resource_attr(res, "uuid", "unilabos_uuid")
|
||||
if current_uuid:
|
||||
uuid_list.append(current_uuid)
|
||||
return 0
|
||||
|
||||
self._traverse_and_process(resource, process)
|
||||
return uuid_list
|
||||
|
||||
def _collect_uuid_mapping(self, resource):
|
||||
"""
|
||||
递归收集资源的 uuid 映射到 uuid_to_resources
|
||||
@@ -971,14 +991,15 @@ class DeviceNodeResourceTracker(object):
|
||||
if current_uuid:
|
||||
old = self.uuid_to_resources.get(current_uuid)
|
||||
self.uuid_to_resources[current_uuid] = res
|
||||
logger.debug(
|
||||
logger.trace(
|
||||
f"收集资源UUID映射: {current_uuid} -> {res} {'' if old is None else f'(覆盖旧值: {old})'}"
|
||||
)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
self._traverse_and_process(resource, process)
|
||||
|
||||
def _remove_uuid_mapping(self, resource):
|
||||
def _remove_uuid_mapping(self, resource) -> int:
|
||||
"""
|
||||
递归清除资源的 uuid 映射
|
||||
|
||||
@@ -990,10 +1011,11 @@ class DeviceNodeResourceTracker(object):
|
||||
current_uuid = self._get_resource_attr(res, "uuid", "unilabos_uuid")
|
||||
if current_uuid and current_uuid in self.uuid_to_resources:
|
||||
self.uuid_to_resources.pop(current_uuid)
|
||||
logger.debug(f"移除资源UUID映射: {current_uuid} -> {res}")
|
||||
logger.trace(f"移除资源UUID映射: {current_uuid} -> {res}")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
self._traverse_and_process(resource, process)
|
||||
return self._traverse_and_process(resource, process)
|
||||
|
||||
def parent_resource(self, resource):
|
||||
if id(resource) in self.resource2parent_resource:
|
||||
@@ -1048,13 +1070,12 @@ class DeviceNodeResourceTracker(object):
|
||||
removed = True
|
||||
break
|
||||
|
||||
if not removed:
|
||||
# 递归清除uuid映射
|
||||
count = self._remove_uuid_mapping(resource)
|
||||
if not count:
|
||||
logger.warning(f"尝试移除不存在的资源: {resource}")
|
||||
return False
|
||||
|
||||
# 递归清除uuid映射
|
||||
self._remove_uuid_mapping(resource)
|
||||
|
||||
# 清除 resource2parent_resource 中与该资源相关的映射
|
||||
# 需要清除:1) 该资源作为 key 的映射 2) 该资源作为 value 的映射
|
||||
keys_to_remove = []
|
||||
@@ -1077,7 +1098,9 @@ class DeviceNodeResourceTracker(object):
|
||||
self.uuid_to_resources.clear()
|
||||
self.resource2parent_resource.clear()
|
||||
|
||||
def figure_resource(self, query_resource, try_mode=False):
|
||||
def figure_resource(
|
||||
self, query_resource: Union[List[Union[dict, "PLRResource"]], dict, "PLRResource"], try_mode=False
|
||||
) -> Union[List[Union[dict, "PLRResource", List[Union[dict, "PLRResource"]]]], dict, "PLRResource"]:
|
||||
if isinstance(query_resource, list):
|
||||
return [self.figure_resource(r, try_mode) for r in query_resource]
|
||||
elif (
|
||||
|
||||
Reference in New Issue
Block a user