Squash merge from dev

Update recipe.yaml

fix: figure_resource

use call_async in all service to avoid deadlock

fix: prcxi import error

临时兼容错误的driver写法

fix protocol node

fix filter protocol

bugfixes on organic protocols

fix and remove redundant info

feat: 新增use_remote_resource参数

fix all protocol_compilers and remove deprecated devices

feat: 优化protocol node节点运行日志

fix pumps and liquid_handler handle

feat: workstation example

add: prcxi res
fix: startup slow

fix: prcxi_res

fix: discard_tips

fix: discard_tips error

fix: drop_tips not using auto resource select

feat: 添加ChinWe设备控制类,支持串口通信和电机控制功能 (#79)

feat: add trace log level

modify default discovery_interval to 15s

fix: working dir error when input config path
feat: report publish topic when error

fix: workstation handlers and vessel_id parsing

Cleanup registry to be easy-understanding (#76)

* delete deprecated mock devices

* rename categories

* combine chromatographic devices

* rename rviz simulation nodes

* organic virtual devices

* parse vessel_id

* run registry completion before merge

---------

Co-authored-by: Xuwznln <18435084+Xuwznln@users.noreply.github.com>
This commit is contained in:
Junhan Chang
2025-08-03 11:21:37 +08:00
committed by Xuwznln
parent a555c59dc2
commit 0bfb52df00
97 changed files with 5033 additions and 164837 deletions

View File

@@ -95,6 +95,11 @@ def parse_args():
action="store_true",
help="启动unilab时同时报送注册表信息",
)
parser.add_argument(
"--use_remote_resource",
action="store_true",
help="启动unilab时使用远程资源启动",
)
parser.add_argument(
"--config",
type=str,
@@ -171,6 +176,8 @@ def main():
"error",
)
os._exit(1)
elif config_path and os.path.exists(config_path):
working_dir = os.path.dirname(config_path)
elif os.path.exists(working_dir) and os.path.exists(os.path.join(working_dir, "local_config.py")):
config_path = os.path.join(working_dir, "local_config.py")
elif not config_path and (
@@ -193,6 +200,16 @@ def main():
print_status(f"当前工作目录为 {working_dir}", "info")
load_config_from_file(config_path, args_dict["labid"])
if args_dict["use_remote_resource"]:
print_status("使用远程资源启动", "info")
from unilabos.app.web import http_client
res = http_client.resource_get("host_node", False)
if str(res.get("code", 0)) == "0" and len(res.get("data", [])) > 0:
print_status("远程资源已存在,使用云端物料!", "info")
args_dict["graph"] = None
else:
print_status("远程资源不存在,本地将进行首次上报!", "info")
# 设置BasicConfig参数
BasicConfig.working_dir = working_dir
BasicConfig.is_host_mode = not args_dict.get("without_host", False)
@@ -220,7 +237,7 @@ def main():
print_unilab_banner(args_dict)
# 注册表
build_registry(args_dict["registry_path"])
build_registry(args_dict["registry_path"], False, args_dict["upload_registry"])
if args_dict["graph"] is None:
request_startup_json = http_client.request_startup_json()
if not request_startup_json:

View File

@@ -166,7 +166,7 @@ class MQTTClient:
status = {"data": device_status.get(device_id, {}), "device_id": device_id, "timestamp": time.time()}
address = f"labs/{MQConfig.lab_id}/devices/"
self.client.publish(address, json.dumps(status), qos=2)
logger.info(f"Device {device_id} status published: address: {address}, {status}")
# logger.info(f"Device {device_id} status published: address: {address}, {status}")
def publish_job_status(self, feedback_data: dict, job_id: str, status: str, return_info: Optional[str] = None):
if self.mqtt_disable:

View File

@@ -69,7 +69,7 @@ def main():
args = parser.parse_args()
load_config_from_file(args.config)
# 构建注册表
build_registry(args.registry, args.complete_registry)
build_registry(args.registry, args.complete_registry, True)
from unilabos.app.mq import mqtt_client
# 连接mqtt