diff --git a/unilabos/devices/workstation/bioyond_studio/sirna_station/sirna_station.py b/unilabos/devices/workstation/bioyond_studio/sirna_station/sirna_station.py index d9c8767d..c6a34a32 100644 --- a/unilabos/devices/workstation/bioyond_studio/sirna_station/sirna_station.py +++ b/unilabos/devices/workstation/bioyond_studio/sirna_station/sirna_station.py @@ -431,13 +431,14 @@ class BioyondSirnaStation(BioyondWorkstation): ) def resync_external_materials( self, - refresh_material_cache: bool = True, + refresh_material_cache: bool = False, **kwargs: Any, ) -> Dict[str, Any]: """手动触发共享 Bioyond 外部物料同步。 Args: - refresh_material_cache: 同步前是否调用 Bioyond 物料缓存刷新(若 RPC 支持)。 + refresh_material_cache: 是否在同步前额外刷新 Bioyond 物料缓存。通常保持 False, + 共享同步路径会用同一次库存查询结果更新缓存。 """ with self._debug_call_session("resync_external_materials"): api_host = self._kwarg_text(kwargs, "api_host") @@ -1813,7 +1814,7 @@ class BioyondSirnaStation(BioyondWorkstation): def _run_shared_external_material_sync( self, rpc: Optional[Any] = None, - refresh_material_cache: bool = True, + refresh_material_cache: bool = False, ) -> Dict[str, Any]: """为 reset / 手动 resync 运行共享 Bioyond 外部物料同步路径。""" if rpc is None: @@ -3865,6 +3866,8 @@ class BioyondSirnaStation(BioyondWorkstation): return False +# TODO: Refactor this into a small BioyondResourceSynchronizer classification hook +# before re-enabling long-term; keep only the Sirna reagent-as-liquid rule here. class SirnaResourceSynchronizer(BioyondResourceSynchronizer): """Sirna-specific resource synchronizer. diff --git a/unilabos/devices/workstation/bioyond_studio/station.py b/unilabos/devices/workstation/bioyond_studio/station.py index d9e9f166..eb888a95 100644 --- a/unilabos/devices/workstation/bioyond_studio/station.py +++ b/unilabos/devices/workstation/bioyond_studio/station.py @@ -176,6 +176,8 @@ class BioyondResourceSynchronizer(ResourceSynchronizer): logger.warning("从Bioyond获取的物料数据为空") return False + self._update_material_cache_from_stock(all_bioyond_data) + # 转换为UniLab格式 unilab_resources = resource_bioyond_to_plr( all_bioyond_data, @@ -189,6 +191,29 @@ class BioyondResourceSynchronizer(ResourceSynchronizer): logger.error(f"从Bioyond同步物料数据失败: {e}") return False + def _update_material_cache_from_stock(self, materials: List[Dict[str, Any]]) -> None: + """用本次库存查询结果同步 RPC 的 name -> material id 缓存。""" + material_cache = getattr(self.bioyond_api_client, "material_cache", None) + if not isinstance(material_cache, dict): + return + + before_count = len(material_cache) + for material in materials: + material_name = material.get("name") + material_id = material.get("id") + if material_name and material_id: + material_cache[material_name] = material_id + + for detail_material in material.get("detail", []) or []: + detail_name = detail_material.get("name") + detail_id = detail_material.get("detailMaterialId") or detail_material.get("id") + if detail_name and detail_id: + material_cache[detail_name] = detail_id + + logger.debug( + f"已用Bioyond库存同步物料缓存: {before_count} -> {len(material_cache)}" + ) + def sync_to_external(self, resource: Any) -> bool: """将本地物料数据变更同步到Bioyond系统""" try: @@ -1404,11 +1429,7 @@ class BioyondWorkstation(WorkstationBase): if self.hardware_interface: self.hardware_interface.scheduler_reset() - # 刷新物料缓存 - if self.hardware_interface: - self.hardware_interface.refresh_material_cache() - - # 重新同步资源 + # 重新同步资源,并用同一次库存查询结果更新物料缓存 if self.resource_synchronizer: self.resource_synchronizer.sync_from_external() diff --git a/unilabos/resources/graphio.py b/unilabos/resources/graphio.py index 52771289..4e659bc2 100644 --- a/unilabos/resources/graphio.py +++ b/unilabos/resources/graphio.py @@ -934,7 +934,12 @@ def resource_bioyond_to_plr(bioyond_materials: list[dict], type_mapping: Dict[st ) current_resource = warehouse[idx] - if current_resource is None or isinstance(current_resource, ResourceHolder): + if current_resource is None or isinstance(current_resource, (ResourceHolder, str)): + if isinstance(current_resource, str): + logger.warning( + f"⚠️ 物料 {unique_name} 覆盖 {wh_name}[{idx}]" + f"{f'({slot_key})' if slot_key else ''} 的旧占位 occupied_by={current_resource!r}" + ) # 物料尺寸已在放入warehouse前根据需要进行了交换 warehouse[idx] = plr_material logger.debug(