mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-14 03:35:12 +00:00
Compare commits
11 Commits
6fd95fdb08
...
ac88c59b50
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac88c59b50 | ||
|
|
2492af57c0 | ||
|
|
b1dae6da17 | ||
|
|
af812d630a | ||
|
|
183579fd7f | ||
|
|
678ace6109 | ||
|
|
18c4eb3e4d | ||
|
|
dd7abe987e | ||
|
|
3e6c8d6340 | ||
|
|
ab7f1539af | ||
|
|
ee918a0e93 |
1
setup.py
1
setup.py
@@ -17,6 +17,7 @@ setup(
|
|||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
"unilab = unilabos.app.main:main",
|
"unilab = unilabos.app.main:main",
|
||||||
|
"unilab-register = unilabos.app.register:main"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
virtual_heatchill() 加热器
|
virtual_heatchill() 加热器
|
||||||
virtual_stirrer() 搅拌器
|
virtual_stirrer() 搅拌器
|
||||||
virtual_solenoid_valve() 电磁阀
|
virtual_solenoid_valve() 电磁阀
|
||||||
vacuum_pump() vacuum_pump.mock 真空泵
|
virtual_vacuum_pump(√) vacuum_pump.mock 真空泵
|
||||||
gas_source() 气源
|
virtual_gas_source(√) 气源
|
||||||
virtual_filter() 过滤器
|
virtual_filter() 过滤器
|
||||||
virtual_column(√) 层析柱
|
virtual_column(√) 层析柱
|
||||||
separator() homemade_grbl_conductivity 分液漏斗
|
separator() homemade_grbl_conductivity 分液漏斗
|
||||||
@@ -24,9 +24,9 @@
|
|||||||
DissolveProtocol()
|
DissolveProtocol()
|
||||||
FilterThroughProtocol()
|
FilterThroughProtocol()
|
||||||
WashSolidProtocol()
|
WashSolidProtocol()
|
||||||
SeparateProtocol(√)
|
SeparateProtocol()
|
||||||
EvaporateProtocol(√)
|
EvaporateProtocol()
|
||||||
HeatChillProtocol()
|
HeatChillProtocol()
|
||||||
HeatChillStartProtocol()
|
HeatChillStartProtocol()
|
||||||
HeatChillStopProtocol()
|
HeatChillStopProtocol()
|
||||||
EvacuateAndRefillProtocol(√)
|
EvacuateAndRefillProtocol()
|
||||||
|
|||||||
@@ -59,7 +59,8 @@
|
|||||||
"HeatChillProtocol",
|
"HeatChillProtocol",
|
||||||
"HeatChillStartProtocol",
|
"HeatChillStartProtocol",
|
||||||
"HeatChillStopProtocol",
|
"HeatChillStopProtocol",
|
||||||
"EvacuateAndRefillProtocol"
|
"EvacuateAndRefillProtocol",
|
||||||
|
"PumpTransferProtocol"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"data": {}
|
"data": {}
|
||||||
@@ -152,7 +153,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 200,
|
"x": 200,
|
||||||
"y": 150,
|
"y": 150,
|
||||||
@@ -173,7 +174,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 250,
|
"x": 250,
|
||||||
"y": 150,
|
"y": 150,
|
||||||
@@ -194,7 +195,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 300,
|
"x": 300,
|
||||||
"y": 150,
|
"y": 150,
|
||||||
@@ -215,7 +216,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 900,
|
"x": 900,
|
||||||
"y": 150,
|
"y": 150,
|
||||||
@@ -236,7 +237,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 950,
|
"x": 950,
|
||||||
"y": 150,
|
"y": 150,
|
||||||
@@ -301,7 +302,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 400,
|
"x": 400,
|
||||||
"y": 450,
|
"y": 450,
|
||||||
@@ -386,7 +387,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 500,
|
"x": 500,
|
||||||
"y": 400,
|
"y": 400,
|
||||||
@@ -405,7 +406,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 1100,
|
"x": 1100,
|
||||||
"y": 500,
|
"y": 500,
|
||||||
@@ -569,7 +570,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 900,
|
"x": 900,
|
||||||
"y": 500,
|
"y": 500,
|
||||||
@@ -588,7 +589,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 950,
|
"x": 950,
|
||||||
"y": 500,
|
"y": 500,
|
||||||
@@ -607,7 +608,7 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"parent": "ComprehensiveProtocolStation",
|
"parent": "ComprehensiveProtocolStation",
|
||||||
"type": "container",
|
"type": "container",
|
||||||
"class": null,
|
"class": "container",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 1050,
|
"x": 1050,
|
||||||
"y": 500,
|
"y": 500,
|
||||||
@@ -626,257 +627,261 @@
|
|||||||
"id": "link_valve1_pump1",
|
"id": "link_valve1_pump1",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "transfer_pump_1",
|
"target": "transfer_pump_1",
|
||||||
"source_port": "port_0",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_0"
|
"multiway_valve_1": "transferpump",
|
||||||
|
"transfer_pump_1": "transferpump"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_reagent1",
|
"id": "link_valve1_reagent1",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "reagent_bottle_1",
|
"target": "reagent_bottle_1",
|
||||||
"source_port": "port_1",
|
|
||||||
"target_port": "outlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_1"
|
"multiway_valve_1": "1",
|
||||||
|
"reagent_bottle_1": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_reagent2",
|
"id": "link_valve1_reagent2",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "reagent_bottle_2",
|
"target": "reagent_bottle_2",
|
||||||
"source_port": "port_2",
|
|
||||||
"target_port": "outlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_2"
|
"multiway_valve_1": "2",
|
||||||
|
"reagent_bottle_2": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_reagent3",
|
"id": "link_valve1_reagent3",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "reagent_bottle_3",
|
"target": "reagent_bottle_3",
|
||||||
"source_port": "port_3",
|
|
||||||
"target_port": "outlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_3"
|
"multiway_valve_1": "3",
|
||||||
|
"reagent_bottle_3": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_centrifuge",
|
"id": "link_valve1_centrifuge",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "centrifuge_1",
|
"target": "centrifuge_1",
|
||||||
"source_port": "port_4",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_4"
|
"multiway_valve_1": "4",
|
||||||
|
"centrifuge_1": "centrifuge"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_rotavap",
|
"id": "link_valve1_rotavap",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "rotavap_1",
|
"target": "rotavap_1",
|
||||||
"source_port": "port_5",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_5"
|
"multiway_valve_1": "5",
|
||||||
|
"rotavap_1": "rotavap-sample"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_reactor",
|
"id": "link_valve1_reactor",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "main_reactor",
|
"target": "main_reactor",
|
||||||
"source_port": "port_6",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_6"
|
"multiway_valve_1": "6",
|
||||||
|
"main_reactor": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_waste1",
|
"id": "link_valve1_waste1",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "waste_bottle_1",
|
"target": "waste_bottle_1",
|
||||||
"source_port": "port_7",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_7"
|
"multiway_valve_1": "7",
|
||||||
|
"waste_bottle_1": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve1_valve2",
|
"id": "link_valve1_valve2",
|
||||||
"source": "multiway_valve_1",
|
"source": "multiway_valve_1",
|
||||||
"target": "multiway_valve_2",
|
"target": "multiway_valve_2",
|
||||||
"source_port": "port_8",
|
|
||||||
"target_port": "port_1",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_1": "port_8",
|
"multiway_valve_1": "8",
|
||||||
"multiway_valve_2": "port_1"
|
"multiway_valve_2": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_pump2",
|
"id": "link_valve2_pump2",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "transfer_pump_2",
|
"target": "transfer_pump_2",
|
||||||
"source_port": "port_0",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_0"
|
"multiway_valve_2": "transferpump",
|
||||||
|
"transfer_pump_2": "transferpump"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_solenoid1",
|
"id": "link_valve2_solenoid1",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "solenoid_valve_1",
|
"target": "solenoid_valve_1",
|
||||||
"source_port": "port_2",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_2"
|
"multiway_valve_2": "2",
|
||||||
|
"solenoid_valve_1": "in"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_solenoid1_vacuum",
|
"id": "link_solenoid1_vacuum",
|
||||||
"source": "solenoid_valve_1",
|
"source": "solenoid_valve_1",
|
||||||
"target": "vacuum_pump_1",
|
"target": "vacuum_pump_1",
|
||||||
"source_port": "outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"solenoid_valve_1": "out",
|
||||||
|
"vacuum_pump_1": "vacuumpump"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_solenoid2",
|
"id": "link_valve2_solenoid2",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "solenoid_valve_2",
|
"target": "solenoid_valve_2",
|
||||||
"source_port": "port_3",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_3"
|
"multiway_valve_2": "3",
|
||||||
|
"solenoid_valve_2": "in"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_solenoid2_gas",
|
"id": "link_solenoid2_gas",
|
||||||
"source": "solenoid_valve_2",
|
"source": "solenoid_valve_2",
|
||||||
"target": "gas_source_1",
|
"target": "gas_source_1",
|
||||||
"source_port": "outlet",
|
"type": "fluid",
|
||||||
"target_port": "outlet",
|
"port": {
|
||||||
"type": "fluid"
|
"solenoid_valve_2": "out",
|
||||||
|
"gas_source_1": "gassource"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_filter",
|
"id": "link_valve2_filter",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "filter_1",
|
"target": "filter_1",
|
||||||
"source_port": "port_4",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_4"
|
"multiway_valve_2": "4",
|
||||||
|
"filter_1": "filterin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_filter_collection1",
|
"id": "link_filter_collection1",
|
||||||
"source": "filter_1",
|
"source": "filter_1",
|
||||||
"target": "collection_bottle_1",
|
"target": "collection_bottle_1",
|
||||||
"source_port": "filtrate_outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"filter_1": "filtrate_out",
|
||||||
|
"collection_bottle_1": "top"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_column",
|
"id": "link_valve2_column",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "column_1",
|
"target": "column_1",
|
||||||
"source_port": "port_5",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_5"
|
"multiway_valve_2": "5",
|
||||||
|
"column_1": "columnin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_column_collection2",
|
"id": "link_column_collection2",
|
||||||
"source": "column_1",
|
"source": "column_1",
|
||||||
"target": "collection_bottle_2",
|
"target": "collection_bottle_2",
|
||||||
"source_port": "outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"column_1": "columnout",
|
||||||
|
"collection_bottle_2": "top"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_separator",
|
"id": "link_valve2_separator",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "separator_1",
|
"target": "separator_1",
|
||||||
"source_port": "port_6",
|
|
||||||
"target_port": "inlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_6"
|
"multiway_valve_2": "6",
|
||||||
|
"separator_1": "separatorin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_separator_collection3",
|
"id": "link_separator_collection3",
|
||||||
"source": "separator_1",
|
"source": "separator_1",
|
||||||
"target": "collection_bottle_3",
|
"target": "collection_bottle_3",
|
||||||
"source_port": "top_outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"separator_1": "separatorout",
|
||||||
|
"collection_bottle_3": "top"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_separator_stirrer_2",
|
"id": "link_separator_stirrer_2",
|
||||||
"source": "separator_1",
|
"source": "separator_1",
|
||||||
"target": "stirrer_2",
|
"target": "stirrer_2",
|
||||||
"source_port": "top_outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"separator_1": "separatorout",
|
||||||
|
"stirrer_2": "stirrer"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_separator_waste2",
|
"id": "link_separator_waste2",
|
||||||
"source": "separator_1",
|
"source": "separator_1",
|
||||||
"target": "waste_bottle_2",
|
"target": "waste_bottle_2",
|
||||||
"source_port": "bottom_outlet",
|
"type": "fluid",
|
||||||
"target_port": "inlet",
|
"port": {
|
||||||
"type": "fluid"
|
"separator_1": "separatorout",
|
||||||
|
"waste_bottle_2": "top"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_reagent4",
|
"id": "link_valve2_reagent4",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "reagent_bottle_4",
|
"target": "reagent_bottle_4",
|
||||||
"source_port": "port_7",
|
|
||||||
"target_port": "outlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_7"
|
"multiway_valve_2": "7",
|
||||||
|
"reagent_bottle_4": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "link_valve2_reagent5",
|
"id": "link_valve2_reagent5",
|
||||||
"source": "multiway_valve_2",
|
"source": "multiway_valve_2",
|
||||||
"target": "reagent_bottle_5",
|
"target": "reagent_bottle_5",
|
||||||
"source_port": "port_8",
|
|
||||||
"target_port": "outlet",
|
|
||||||
"type": "fluid",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"multiway_valve_2": "port_8"
|
"multiway_valve_2": "8",
|
||||||
|
"reagent_bottle_5": "top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "mech_stirrer_reactor",
|
"id": "mech_stirrer_reactor",
|
||||||
"source": "stirrer_1",
|
"source": "stirrer_1",
|
||||||
"target": "main_reactor",
|
"target": "main_reactor",
|
||||||
"type": "fluid"
|
"type": "fluid",
|
||||||
|
"port": {
|
||||||
|
"stirrer_1": "stirrer",
|
||||||
|
"main_reactor": "top"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "thermal_heater_reactor",
|
"id": "thermal_heater_reactor",
|
||||||
"source": "heater_1",
|
"source": "heater_1",
|
||||||
"target": "main_reactor",
|
"target": "main_reactor",
|
||||||
"type": "fluid"
|
"type": "fluid",
|
||||||
|
"port": {
|
||||||
|
"heater_1": "heatchill",
|
||||||
|
"main_reactor": "bottom"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -122,39 +122,39 @@
|
|||||||
],
|
],
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"source": "reactor",
|
"source": "vacuum_valve",
|
||||||
"target": "vacuum_valve",
|
"target": "reactor",
|
||||||
"type": "physical",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"reactor": "top",
|
"reactor": "top",
|
||||||
"vacuum_valve": "1"
|
"vacuum_valve": "out"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "reactor",
|
"source": "gas_valve",
|
||||||
"target": "gas_valve",
|
"target": "reactor",
|
||||||
"type": "physical",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"reactor": "top",
|
"reactor": "top",
|
||||||
"gas_valve": "1"
|
"gas_valve": "out"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "vacuum_pump",
|
"source": "vacuum_valve",
|
||||||
"target": "vacuum_valve",
|
"target": "vacuum_pump",
|
||||||
"type": "physical",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"vacuum_pump": "out",
|
"vacuum_pump": "out",
|
||||||
"vacuum_valve": "0"
|
"vacuum_valve": "in"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "gas_source",
|
"source": "gas_valve",
|
||||||
"target": "gas_valve",
|
"target": "gas_source",
|
||||||
"type": "physical",
|
"type": "fluid",
|
||||||
"port": {
|
"port": {
|
||||||
"gas_source": "out",
|
"gas_source": "out",
|
||||||
"gas_valve": "0"
|
"gas_valve": "in"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ from unilabos.config.config import load_config, BasicConfig, _update_config_from
|
|||||||
from unilabos.utils.banner_print import print_status, print_unilab_banner
|
from unilabos.utils.banner_print import print_status, print_unilab_banner
|
||||||
|
|
||||||
|
|
||||||
|
def load_config_from_file(config_path):
|
||||||
|
if config_path is None:
|
||||||
|
config_path = os.environ.get("UNILABOS.BASICCONFIG.CONFIG_PATH", None)
|
||||||
|
if config_path:
|
||||||
|
if not os.path.exists(config_path):
|
||||||
|
print_status(f"配置文件 {config_path} 不存在", "error")
|
||||||
|
elif not config_path.endswith(".py"):
|
||||||
|
print_status(f"配置文件 {config_path} 不是Python文件,必须以.py结尾", "error")
|
||||||
|
else:
|
||||||
|
load_config(config_path)
|
||||||
|
else:
|
||||||
|
print_status(f"启动 UniLab-OS时,配置文件参数未正确传入 --config '{config_path}' 尝试本地配置...", "warning")
|
||||||
|
load_config(config_path)
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
"""解析命令行参数"""
|
"""解析命令行参数"""
|
||||||
parser = argparse.ArgumentParser(description="Start Uni-Lab Edge server.")
|
parser = argparse.ArgumentParser(description="Start Uni-Lab Edge server.")
|
||||||
@@ -58,6 +73,11 @@ def parse_args():
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Slave模式下跳过等待host服务",
|
help="Slave模式下跳过等待host服务",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--upload_registry",
|
||||||
|
action="store_true",
|
||||||
|
help="启动unilab时同时报送注册表信息",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--config",
|
"--config",
|
||||||
type=str,
|
type=str,
|
||||||
@@ -97,22 +117,12 @@ def main():
|
|||||||
|
|
||||||
# 加载配置文件,优先加载config,然后从env读取
|
# 加载配置文件,优先加载config,然后从env读取
|
||||||
config_path = args_dict.get("config")
|
config_path = args_dict.get("config")
|
||||||
if config_path is None:
|
load_config_from_file(config_path)
|
||||||
config_path = os.environ.get("UNILABOS.BASICCONFIG.CONFIG_PATH", None)
|
|
||||||
if config_path:
|
|
||||||
if not os.path.exists(config_path):
|
|
||||||
print_status(f"配置文件 {config_path} 不存在", "error")
|
|
||||||
elif not config_path.endswith(".py"):
|
|
||||||
print_status(f"配置文件 {config_path} 不是Python文件,必须以.py结尾", "error")
|
|
||||||
else:
|
|
||||||
load_config(config_path)
|
|
||||||
else:
|
|
||||||
print_status(f"启动 UniLab-OS时,配置文件参数未正确传入 --config '{config_path}' 尝试本地配置...", "warning")
|
|
||||||
load_config(config_path)
|
|
||||||
|
|
||||||
# 设置BasicConfig参数
|
# 设置BasicConfig参数
|
||||||
BasicConfig.is_host_mode = not args_dict.get("without_host", False)
|
BasicConfig.is_host_mode = not args_dict.get("without_host", False)
|
||||||
BasicConfig.slave_no_host = args_dict.get("slave_no_host", False)
|
BasicConfig.slave_no_host = args_dict.get("slave_no_host", False)
|
||||||
|
BasicConfig.upload_registry = args_dict.get("upload_registry", False)
|
||||||
machine_name = os.popen("hostname").read().strip()
|
machine_name = os.popen("hostname").read().strip()
|
||||||
machine_name = "".join([c if c.isalnum() or c == "_" else "_" for c in machine_name])
|
machine_name = "".join([c if c.isalnum() or c == "_" else "_" for c in machine_name])
|
||||||
BasicConfig.machine_name = machine_name
|
BasicConfig.machine_name = machine_name
|
||||||
|
|||||||
@@ -172,13 +172,14 @@ class MQTTClient:
|
|||||||
jobdata = {"job_id": job_id, "data": feedback_data, "status": status, "return_info": return_info}
|
jobdata = {"job_id": job_id, "data": feedback_data, "status": status, "return_info": return_info}
|
||||||
self.client.publish(f"labs/{MQConfig.lab_id}/job/list/", json.dumps(jobdata), qos=2)
|
self.client.publish(f"labs/{MQConfig.lab_id}/job/list/", json.dumps(jobdata), qos=2)
|
||||||
|
|
||||||
def publish_registry(self, device_id: str, device_info: dict):
|
def publish_registry(self, device_id: str, device_info: dict, print_debug: bool = True):
|
||||||
if self.mqtt_disable:
|
if self.mqtt_disable:
|
||||||
return
|
return
|
||||||
address = f"labs/{MQConfig.lab_id}/registry/"
|
address = f"labs/{MQConfig.lab_id}/registry/"
|
||||||
registry_data = json.dumps({device_id: device_info}, ensure_ascii=False, cls=TypeEncoder)
|
registry_data = json.dumps({device_id: device_info}, ensure_ascii=False, cls=TypeEncoder)
|
||||||
self.client.publish(address, registry_data, qos=2)
|
self.client.publish(address, registry_data, qos=2)
|
||||||
logger.debug(f"Registry data published: address: {address}, {registry_data}")
|
if print_debug:
|
||||||
|
logger.debug(f"Registry data published: address: {address}, {registry_data}")
|
||||||
|
|
||||||
def publish_actions(self, action_id: str, action_info: dict):
|
def publish_actions(self, action_id: str, action_info: dict):
|
||||||
if self.mqtt_disable:
|
if self.mqtt_disable:
|
||||||
|
|||||||
67
unilabos/app/register.py
Normal file
67
unilabos/app/register.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import argparse
|
||||||
|
import time
|
||||||
|
|
||||||
|
from unilabos.registry.registry import build_registry
|
||||||
|
|
||||||
|
from unilabos.app.main import load_config_from_file
|
||||||
|
from unilabos.utils.log import logger
|
||||||
|
|
||||||
|
|
||||||
|
def register_devices_and_resources(mqtt_client, lab_registry):
|
||||||
|
"""
|
||||||
|
注册设备和资源到 MQTT
|
||||||
|
"""
|
||||||
|
logger.info("[UniLab Register] 开始注册设备和资源...")
|
||||||
|
|
||||||
|
# 注册设备信息
|
||||||
|
for device_info in lab_registry.obtain_registry_device_info():
|
||||||
|
mqtt_client.publish_registry(device_info["id"], device_info, False)
|
||||||
|
logger.debug(f"[UniLab Register] 注册设备: {device_info['id']}")
|
||||||
|
|
||||||
|
# 注册资源信息
|
||||||
|
for resource_info in lab_registry.obtain_registry_resource_info():
|
||||||
|
mqtt_client.publish_registry(resource_info["id"], resource_info, False)
|
||||||
|
logger.debug(f"[UniLab Register] 注册资源: {resource_info['id']}")
|
||||||
|
|
||||||
|
time.sleep(10)
|
||||||
|
|
||||||
|
logger.info("[UniLab Register] 设备和资源注册完成.")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
命令行入口函数
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(description="注册设备和资源到 MQTT")
|
||||||
|
parser.add_argument(
|
||||||
|
"--registry_path",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
action="append",
|
||||||
|
help="注册表路径",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--config",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="配置文件路径,支持.py格式的Python配置文件",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# 构建注册表
|
||||||
|
build_registry(args.registry_path)
|
||||||
|
load_config_from_file(args.config)
|
||||||
|
|
||||||
|
from unilabos.app.mq import mqtt_client
|
||||||
|
|
||||||
|
# 连接mqtt
|
||||||
|
mqtt_client.start()
|
||||||
|
|
||||||
|
from unilabos.registry.registry import lab_registry
|
||||||
|
|
||||||
|
# 注册设备和资源
|
||||||
|
register_devices_and_resources(mqtt_client, lab_registry)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -44,10 +44,10 @@ class HTTPClient:
|
|||||||
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,
|
||||||
headers={"Authorization": f"lab {self.auth}"},
|
headers={"Authorization": f"lab {self.auth}"},
|
||||||
timeout=5,
|
timeout=100,
|
||||||
)
|
)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200 and response.status_code != 201:
|
||||||
logger.error(f"添加物料关系失败: {response.text}")
|
logger.error(f"添加物料关系失败: {response.status_code}, {response.text}")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def resource_add(self, resources: List[Dict[str, Any]], database_process_later: bool) -> requests.Response:
|
def resource_add(self, resources: List[Dict[str, Any]], database_process_later: bool) -> requests.Response:
|
||||||
@@ -64,7 +64,7 @@ class HTTPClient:
|
|||||||
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,
|
||||||
headers={"Authorization": f"lab {self.auth}"},
|
headers={"Authorization": f"lab {self.auth}"},
|
||||||
timeout=5,
|
timeout=100,
|
||||||
)
|
)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
logger.error(f"添加物料失败: {response.text}")
|
logger.error(f"添加物料失败: {response.text}")
|
||||||
@@ -85,7 +85,7 @@ class HTTPClient:
|
|||||||
f"{self.remote_addr}/lab/resource/?edge_format=1",
|
f"{self.remote_addr}/lab/resource/?edge_format=1",
|
||||||
params={"id": id, "with_children": with_children},
|
params={"id": id, "with_children": with_children},
|
||||||
headers={"Authorization": f"lab {self.auth}"},
|
headers={"Authorization": f"lab {self.auth}"},
|
||||||
timeout=5,
|
timeout=20,
|
||||||
)
|
)
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ class HTTPClient:
|
|||||||
f"{self.remote_addr}/lab/resource/batch_delete/",
|
f"{self.remote_addr}/lab/resource/batch_delete/",
|
||||||
params={"id": id},
|
params={"id": id},
|
||||||
headers={"Authorization": f"lab {self.auth}"},
|
headers={"Authorization": f"lab {self.auth}"},
|
||||||
timeout=5,
|
timeout=20,
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ class HTTPClient:
|
|||||||
f"{self.remote_addr}/lab/resource/batch_update/?edge_format=1",
|
f"{self.remote_addr}/lab/resource/batch_update/?edge_format=1",
|
||||||
json=resources,
|
json=resources,
|
||||||
headers={"Authorization": f"lab {self.auth}"},
|
headers={"Authorization": f"lab {self.auth}"},
|
||||||
timeout=5,
|
timeout=100,
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ from unilabos.utils import logger
|
|||||||
class BasicConfig:
|
class BasicConfig:
|
||||||
ENV = "pro" # 'test'
|
ENV = "pro" # 'test'
|
||||||
config_path = ""
|
config_path = ""
|
||||||
is_host_mode = True # 从registry.py移动过来
|
is_host_mode = True
|
||||||
slave_no_host = False # 是否跳过rclient.wait_for_service()
|
slave_no_host = False # 是否跳过rclient.wait_for_service()
|
||||||
|
upload_registry = False
|
||||||
machine_name = "undefined"
|
machine_name = "undefined"
|
||||||
vis_2d_enable = False
|
vis_2d_enable = False
|
||||||
|
|
||||||
|
|||||||
@@ -48,12 +48,14 @@ solenoid_valve.mock:
|
|||||||
feedback: {}
|
feedback: {}
|
||||||
result: {}
|
result: {}
|
||||||
handles:
|
handles:
|
||||||
- handler_key: 0
|
- handler_key: in
|
||||||
label: 0
|
label: in
|
||||||
|
io_type: target
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
- handler_key: 1
|
- handler_key: out
|
||||||
label: 1
|
label: out
|
||||||
|
io_type: source
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
init_param_schema:
|
init_param_schema:
|
||||||
|
|||||||
@@ -55,8 +55,21 @@
|
|||||||
# 连接特性:1个输入口(混合液),2个输出口(上相和下相)
|
# 连接特性:1个输入口(混合液),2个输出口(上相和下相)
|
||||||
# 数据类型:fluid(流体连接)
|
# 数据类型:fluid(流体连接)
|
||||||
|
|
||||||
|
# 11. virtual_vacuum_pump - 虚拟真空泵
|
||||||
|
# 描述:真空泵设备,用于抽真空操作和真空/充气循环
|
||||||
|
# 连接特性:1个输入口(连接需要抽真空的系统)
|
||||||
|
# 数据类型:fluid(流体连接)
|
||||||
|
# 主要功能:开启/关闭、状态控制(ON/OFF)
|
||||||
|
|
||||||
|
# 12. virtual_gas_source - 虚拟气源
|
||||||
|
# 描述:气源设备,用于充气操作和真空/充气循环
|
||||||
|
# 连接特性:1个输出口(向系统提供加压气体)
|
||||||
|
# 数据类型:fluid(流体连接)
|
||||||
|
# 主要功能:开启/关闭、状态控制(ON/OFF)
|
||||||
|
|
||||||
virtual_pump:
|
virtual_pump:
|
||||||
description: Virtual Pump for PumpTransferProtocol Testing
|
description: Virtual Pump for PumpTransferProtocol Testing
|
||||||
|
#icon: 这个注册的设备应该是写错了,后续删掉
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_pump:VirtualPump
|
module: unilabos.devices.virtual.virtual_pump:VirtualPump
|
||||||
type: python
|
type: python
|
||||||
@@ -94,10 +107,10 @@ virtual_pump:
|
|||||||
success: success
|
success: success
|
||||||
# 虚拟泵节点配置 - 具有多通道阀门特性,根据valve_position可连接多个容器
|
# 虚拟泵节点配置 - 具有多通道阀门特性,根据valve_position可连接多个容器
|
||||||
handles:
|
handles:
|
||||||
- handler_key: pump-inlet
|
- handler_key: pumpio
|
||||||
label: Pump Inlet
|
label: pumpio
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
io_type: target
|
io_type: source
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: fluid_in
|
data_key: fluid_in
|
||||||
description: "泵的进液口,连接源容器"
|
description: "泵的进液口,连接源容器"
|
||||||
@@ -114,6 +127,7 @@ virtual_pump:
|
|||||||
|
|
||||||
virtual_stirrer:
|
virtual_stirrer:
|
||||||
description: Virtual Stirrer for StirProtocol Testing
|
description: Virtual Stirrer for StirProtocol Testing
|
||||||
|
icon: Stirrer.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_stirrer:VirtualStirrer
|
module: unilabos.devices.virtual.virtual_stirrer:VirtualStirrer
|
||||||
type: python
|
type: python
|
||||||
@@ -150,11 +164,11 @@ virtual_stirrer:
|
|||||||
success: success
|
success: success
|
||||||
# 虚拟搅拌器节点配置 - 机械连接设备,单一双向连接点
|
# 虚拟搅拌器节点配置 - 机械连接设备,单一双向连接点
|
||||||
handles:
|
handles:
|
||||||
- handler_key: stirrer-vessel
|
- handler_key: stirrer
|
||||||
label: Vessel Connection
|
label: stirrer
|
||||||
data_type: mechanical
|
data_type: mechanical
|
||||||
side: SOUTH
|
side: NORTH
|
||||||
io_type: undirected
|
io_type: source
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: vessel
|
data_key: vessel
|
||||||
description: "搅拌器的机械连接口,直接与反应容器连接提供搅拌功能"
|
description: "搅拌器的机械连接口,直接与反应容器连接提供搅拌功能"
|
||||||
@@ -174,6 +188,7 @@ virtual_stirrer:
|
|||||||
|
|
||||||
virtual_multiway_valve:
|
virtual_multiway_valve:
|
||||||
description: Virtual 8-Way Valve for flow direction control
|
description: Virtual 8-Way Valve for flow direction control
|
||||||
|
icon: EightPipeline.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_multiway_valve:VirtualMultiwayValve
|
module: unilabos.devices.virtual.virtual_multiway_valve:VirtualMultiwayValve
|
||||||
type: python
|
type: python
|
||||||
@@ -193,14 +208,15 @@ virtual_multiway_valve:
|
|||||||
success: success
|
success: success
|
||||||
# 八通阀门节点配置 - 1个输入口,8个输出口,可切换流向
|
# 八通阀门节点配置 - 1个输入口,8个输出口,可切换流向
|
||||||
handles:
|
handles:
|
||||||
- handler_key: multiway-valve-inlet
|
- handler_key: transferpump
|
||||||
label: Valve Inlet
|
label: transferpump
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
|
side: NORTH
|
||||||
io_type: target
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: fluid_in
|
data_key: fluid_in
|
||||||
description: "八通阀门进液口,接收来源流体"
|
description: "八通阀门进液口,接收来源流体"
|
||||||
- handler_key: multiway-valve-port-1
|
- handler_key: 1
|
||||||
label: 1
|
label: 1
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
@@ -208,7 +224,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_1
|
data_key: fluid_port_1
|
||||||
description: "八通阀门端口1,position=1时流体从此口流出"
|
description: "八通阀门端口1,position=1时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-2
|
- handler_key: 2
|
||||||
label: 2
|
label: 2
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: EAST
|
side: EAST
|
||||||
@@ -216,7 +232,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_2
|
data_key: fluid_port_2
|
||||||
description: "八通阀门端口2,position=2时流体从此口流出"
|
description: "八通阀门端口2,position=2时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-3
|
- handler_key: 3
|
||||||
label: 3
|
label: 3
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: EAST
|
side: EAST
|
||||||
@@ -224,7 +240,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_3
|
data_key: fluid_port_3
|
||||||
description: "八通阀门端口3,position=3时流体从此口流出"
|
description: "八通阀门端口3,position=3时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-4
|
- handler_key: 4
|
||||||
label: 4
|
label: 4
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
@@ -232,7 +248,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_4
|
data_key: fluid_port_4
|
||||||
description: "八通阀门端口4,position=4时流体从此口流出"
|
description: "八通阀门端口4,position=4时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-5
|
- handler_key: 5
|
||||||
label: 5
|
label: 5
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
@@ -240,7 +256,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_5
|
data_key: fluid_port_5
|
||||||
description: "八通阀门端口5,position=5时流体从此口流出"
|
description: "八通阀门端口5,position=5时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-7
|
- handler_key: 7
|
||||||
label: 7
|
label: 7
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: WEST
|
side: WEST
|
||||||
@@ -248,7 +264,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_7
|
data_key: fluid_port_7
|
||||||
description: "八通阀门端口7,position=7时流体从此口流出"
|
description: "八通阀门端口7,position=7时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-6
|
- handler_key: 6
|
||||||
label: 6
|
label: 6
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: WEST
|
side: WEST
|
||||||
@@ -256,7 +272,7 @@ virtual_multiway_valve:
|
|||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: fluid_port_6
|
data_key: fluid_port_6
|
||||||
description: "八通阀门端口6,position=6时流体从此口流出"
|
description: "八通阀门端口6,position=6时流体从此口流出"
|
||||||
- handler_key: multiway-valve-port-8
|
- handler_key: 8
|
||||||
label: 8
|
label: 8
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
@@ -276,6 +292,7 @@ virtual_multiway_valve:
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
virtual_solenoid_valve:
|
virtual_solenoid_valve:
|
||||||
description: Virtual Solenoid Valve for simple on/off flow control
|
description: Virtual Solenoid Valve for simple on/off flow control
|
||||||
|
#icon: SolenoidValve.webp暂时还没有
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_solenoid_valve:VirtualSolenoidValve
|
module: unilabos.devices.virtual.virtual_solenoid_valve:VirtualSolenoidValve
|
||||||
type: python
|
type: python
|
||||||
@@ -307,19 +324,21 @@ virtual_solenoid_valve:
|
|||||||
success: success
|
success: success
|
||||||
# 电磁阀门节点配置 - 双向流通的开关型阀门,流动方向由泵决定
|
# 电磁阀门节点配置 - 双向流通的开关型阀门,流动方向由泵决定
|
||||||
handles:
|
handles:
|
||||||
- handler_key: solenoid-valve-port-in
|
- handler_key: in
|
||||||
label: in
|
label: in
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
io_type: undirected
|
side: NORTH
|
||||||
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: fluid_port
|
data_key: fluid_port_in
|
||||||
description: "电磁阀的双向流体口,开启时允许流体双向通过,关闭时完全阻断"
|
description: "电磁阀的双向流体口,开启时允许流体双向通过,关闭时完全阻断"
|
||||||
- handler_key: solenoid-valve-port-out
|
- handler_key: out
|
||||||
label: out
|
label: out
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
io_type: undirected
|
side: SOUTH
|
||||||
|
io_type: source
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: fluid_port
|
data_key: fluid_port_out
|
||||||
description: "电磁阀的双向流体口,开启时允许流体双向通过,关闭时完全阻断"
|
description: "电磁阀的双向流体口,开启时允许流体双向通过,关闭时完全阻断"
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
@@ -336,6 +355,7 @@ virtual_solenoid_valve:
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
virtual_centrifuge:
|
virtual_centrifuge:
|
||||||
description: Virtual Centrifuge for CentrifugeProtocol Testing
|
description: Virtual Centrifuge for CentrifugeProtocol Testing
|
||||||
|
#icon: Centrifuge.webp暂时还没有
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_centrifuge:VirtualCentrifuge
|
module: unilabos.devices.virtual.virtual_centrifuge:VirtualCentrifuge
|
||||||
type: python
|
type: python
|
||||||
@@ -368,10 +388,11 @@ virtual_centrifuge:
|
|||||||
message: message
|
message: message
|
||||||
# 虚拟离心机节点配置 - 单个样品处理设备,输入输出都是同一个样品容器
|
# 虚拟离心机节点配置 - 单个样品处理设备,输入输出都是同一个样品容器
|
||||||
handles:
|
handles:
|
||||||
- handler_key: centrifuge-sample
|
- handler_key: centrifuge
|
||||||
label: Sample Input/Output
|
label: centrifuge
|
||||||
data_type: transport
|
data_type: transport
|
||||||
io_type: undirected
|
side: NORTH
|
||||||
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: vessel
|
data_key: vessel
|
||||||
description: "需要离心的样品容器"
|
description: "需要离心的样品容器"
|
||||||
@@ -394,6 +415,7 @@ virtual_centrifuge:
|
|||||||
|
|
||||||
virtual_filter:
|
virtual_filter:
|
||||||
description: Virtual Filter for FilterProtocol Testing
|
description: Virtual Filter for FilterProtocol Testing
|
||||||
|
icon: Filter.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_filter:VirtualFilter
|
module: unilabos.devices.virtual.virtual_filter:VirtualFilter
|
||||||
type: python
|
type: python
|
||||||
@@ -429,16 +451,16 @@ virtual_filter:
|
|||||||
message: message
|
message: message
|
||||||
# 虚拟过滤器节点配置 - 分离设备,1个输入(原始样品),2个输出(滤液和滤渣)
|
# 虚拟过滤器节点配置 - 分离设备,1个输入(原始样品),2个输出(滤液和滤渣)
|
||||||
handles:
|
handles:
|
||||||
- handler_key: filter-in
|
- handler_key: filterin
|
||||||
label: Input
|
label: filterin
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
io_type: target
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: vessel
|
data_key: vessel
|
||||||
description: "需要过滤的原始样品容器"
|
description: "需要过滤的原始样品容器"
|
||||||
- handler_key: filter-filtrate-out
|
- handler_key: filtrate_out
|
||||||
label: Output
|
label: filtrate_out
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
io_type: source
|
io_type: source
|
||||||
@@ -469,6 +491,7 @@ virtual_filter:
|
|||||||
|
|
||||||
virtual_heatchill:
|
virtual_heatchill:
|
||||||
description: Virtual HeatChill for HeatChillProtocol Testing
|
description: Virtual HeatChill for HeatChillProtocol Testing
|
||||||
|
icon: Heater.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_heatchill:VirtualHeatChill
|
module: unilabos.devices.virtual.virtual_heatchill:VirtualHeatChill
|
||||||
type: python
|
type: python
|
||||||
@@ -508,11 +531,11 @@ virtual_heatchill:
|
|||||||
success: success
|
success: success
|
||||||
# 虚拟加热/冷却器节点配置 - 温控设备,单一双向连接点用于放置容器
|
# 虚拟加热/冷却器节点配置 - 温控设备,单一双向连接点用于放置容器
|
||||||
handles:
|
handles:
|
||||||
- handler_key: heatchill-vessel
|
- handler_key: heatchill
|
||||||
label: Connection
|
label: heatchill
|
||||||
data_type: mechanical
|
data_type: mechanical
|
||||||
side: NORTH
|
side: NORTH
|
||||||
io_type: undirected
|
io_type: source
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: vessel
|
data_key: vessel
|
||||||
description: "加热/冷却器的物理连接口,容器直接放置在设备上进行温度控制"
|
description: "加热/冷却器的物理连接口,容器直接放置在设备上进行温度控制"
|
||||||
@@ -535,6 +558,7 @@ virtual_heatchill:
|
|||||||
|
|
||||||
virtual_transfer_pump:
|
virtual_transfer_pump:
|
||||||
description: Virtual Transfer Pump for TransferProtocol Testing (Syringe-style)
|
description: Virtual Transfer Pump for TransferProtocol Testing (Syringe-style)
|
||||||
|
icon: Pump.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_transferpump:VirtualPump
|
module: unilabos.devices.virtual.virtual_transferpump:VirtualPump
|
||||||
type: python
|
type: python
|
||||||
@@ -566,14 +590,14 @@ virtual_transfer_pump:
|
|||||||
message: message
|
message: message
|
||||||
# 注射器式转移泵节点配置 - 只有一个双向连接口,可吸入和排出液体
|
# 注射器式转移泵节点配置 - 只有一个双向连接口,可吸入和排出液体
|
||||||
handles:
|
handles:
|
||||||
undirected:
|
- handler_key: transferpump
|
||||||
- handler_key: syringe-port
|
label: transferpump
|
||||||
label: Syringe Port
|
data_type: fluid
|
||||||
data_type: fluid
|
side: SOUTH
|
||||||
io_type: undirected
|
io_type: source
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: fluid_port
|
data_key: fluid_port
|
||||||
description: "注射器式转移泵的唯一连接口,通过阀门切换实现吸入和排出"
|
description: "注射器式转移泵的唯一连接口,通过阀门切换实现吸入和排出"
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -590,6 +614,7 @@ virtual_transfer_pump:
|
|||||||
|
|
||||||
virtual_column:
|
virtual_column:
|
||||||
description: Virtual Column for RunColumn Protocol Testing
|
description: Virtual Column for RunColumn Protocol Testing
|
||||||
|
#icon: Column.webp暂时还没有
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_column:VirtualColumn
|
module: unilabos.devices.virtual.virtual_column:VirtualColumn
|
||||||
type: python
|
type: python
|
||||||
@@ -618,16 +643,16 @@ virtual_column:
|
|||||||
message: message
|
message: message
|
||||||
# 虚拟色谱柱节点配置 - 分离纯化设备,1个样品输入口,1个纯化产物输出口
|
# 虚拟色谱柱节点配置 - 分离纯化设备,1个样品输入口,1个纯化产物输出口
|
||||||
handles:
|
handles:
|
||||||
- handler_key: column-sample-inlet
|
- handler_key: columnin
|
||||||
label: Sample Input
|
label: columnin
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
io_type: target
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: from_vessel
|
data_key: from_vessel
|
||||||
description: "需要纯化的样品输入口"
|
description: "需要纯化的样品输入口"
|
||||||
- handler_key: column-product-outlet
|
- handler_key: columnout
|
||||||
label: Purified Product
|
label: columnout
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
io_type: source
|
io_type: source
|
||||||
@@ -653,6 +678,7 @@ virtual_column:
|
|||||||
|
|
||||||
virtual_rotavap:
|
virtual_rotavap:
|
||||||
description: Virtual Rotary Evaporator for EvaporateProtocol Testing
|
description: Virtual Rotary Evaporator for EvaporateProtocol Testing
|
||||||
|
icon: Rotaryevaporator.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_rotavap:VirtualRotavap
|
module: unilabos.devices.virtual.virtual_rotavap:VirtualRotavap
|
||||||
type: python
|
type: python
|
||||||
@@ -685,32 +711,24 @@ virtual_rotavap:
|
|||||||
result:
|
result:
|
||||||
success: success
|
success: success
|
||||||
message: message
|
message: message
|
||||||
# 虚拟旋转蒸发仪节点配置 - 蒸发浓缩设备,1个输入口(样品),2个输出口(浓缩物和冷凝液)
|
# 虚拟旋转蒸发仪节点配置 - 1个双向口(样品进出),1个单向输出口(冷凝溶剂)
|
||||||
handles:
|
handles:
|
||||||
- handler_key: rotavap-sample-inlet
|
- handler_key: rotavap-sample
|
||||||
label: Sample Input
|
label: rotavap-sample
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
io_type: target
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: vessel
|
data_key: vessel
|
||||||
description: "需要蒸发的样品输入口"
|
description: "样品的双向连接口,可放入需要蒸发的样品,蒸发完成后取出浓缩物"
|
||||||
- handler_key: rotavap-concentrate-outlet
|
|
||||||
label: Concentrate
|
|
||||||
data_type: fluid
|
|
||||||
side: SOUTH
|
|
||||||
io_type: source
|
|
||||||
data_source: executor
|
|
||||||
data_key: concentrate_vessel
|
|
||||||
description: "蒸发浓缩后的产物输出口"
|
|
||||||
- handler_key: rotavap-distillate-outlet
|
- handler_key: rotavap-distillate-outlet
|
||||||
label: Distillate
|
label: Distillate Outlet
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: WEST
|
side: WEST
|
||||||
io_type: source
|
io_type: source
|
||||||
data_source: executor
|
data_source: executor
|
||||||
data_key: distillate_vessel
|
data_key: distillate_vessel
|
||||||
description: "冷凝回收的溶剂输出口"
|
description: "冷凝回收的溶剂单向输出口,连接收集瓶"
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -727,6 +745,7 @@ virtual_rotavap:
|
|||||||
|
|
||||||
virtual_separator:
|
virtual_separator:
|
||||||
description: Virtual Separator for SeparateProtocol Testing
|
description: Virtual Separator for SeparateProtocol Testing
|
||||||
|
icon: Separator.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_separator:VirtualSeparator
|
module: unilabos.devices.virtual.virtual_separator:VirtualSeparator
|
||||||
type: python
|
type: python
|
||||||
@@ -765,24 +784,16 @@ virtual_separator:
|
|||||||
message: message
|
message: message
|
||||||
# 虚拟分液器节点配置 - 分离设备,1个输入口(混合液),2个输出口(上相和下相)
|
# 虚拟分液器节点配置 - 分离设备,1个输入口(混合液),2个输出口(上相和下相)
|
||||||
handles:
|
handles:
|
||||||
- handler_key: separator-inlet
|
- handler_key: separatorin
|
||||||
label: Mixed Input
|
label: separatorin
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
io_type: target
|
io_type: target
|
||||||
data_source: handle
|
data_source: handle
|
||||||
data_key: from_vessel
|
data_key: from_vessel
|
||||||
description: "需要分离的混合液体输入口"
|
description: "需要分离的混合液体输入口"
|
||||||
- handler_key: separator-top-outlet
|
- handler_key: separatorout
|
||||||
label: Top Phase
|
label: separatorout
|
||||||
data_type: fluid
|
|
||||||
side: EAST
|
|
||||||
io_type: source
|
|
||||||
data_source: executor
|
|
||||||
data_key: top_outlet
|
|
||||||
description: "上相(轻相)液体输出口"
|
|
||||||
- handler_key: separator-bottom-outlet
|
|
||||||
label: Bottom Phase
|
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
io_type: source
|
io_type: source
|
||||||
@@ -805,6 +816,7 @@ virtual_separator:
|
|||||||
|
|
||||||
virtual_vacuum_pump:
|
virtual_vacuum_pump:
|
||||||
description: Virtual vacuum pump
|
description: Virtual vacuum pump
|
||||||
|
icon: Vacuum.webp
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_vacuum_pump:VirtualVacuumPump
|
module: unilabos.devices.virtual.virtual_vacuum_pump:VirtualVacuumPump
|
||||||
type: python
|
type: python
|
||||||
@@ -827,25 +839,28 @@ virtual_vacuum_pump:
|
|||||||
string: string
|
string: string
|
||||||
feedback: {}
|
feedback: {}
|
||||||
result: {}
|
result: {}
|
||||||
|
# 虚拟真空泵节点配置 - 真空设备,1个输入口连接需要抽真空的系统
|
||||||
handles:
|
handles:
|
||||||
- handler_key: out
|
- handler_key: vacuumpump
|
||||||
label: out
|
label: vacuumpump
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
io_type: target
|
side: SOUTH
|
||||||
data_source: handle
|
io_type: source
|
||||||
data_key: fluid_in
|
data_source: handle
|
||||||
init_param_schema:
|
data_key: fluid_in
|
||||||
|
description: "真空泵进气口,连接需要抽真空的容器或管路"
|
||||||
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
port:
|
port:
|
||||||
type: string
|
type: string
|
||||||
description: "通信端口"
|
|
||||||
default: "VIRTUAL"
|
default: "VIRTUAL"
|
||||||
required:
|
description: "通信端口"
|
||||||
- port
|
additionalProperties: false
|
||||||
|
|
||||||
virtual_gas_source:
|
virtual_gas_source:
|
||||||
description: Virtual gas source
|
description: Virtual gas source
|
||||||
|
#icon: GasSource.webp暂时还没有
|
||||||
class:
|
class:
|
||||||
module: unilabos.devices.virtual.virtual_gas_source:VirtualGasSource
|
module: unilabos.devices.virtual.virtual_gas_source:VirtualGasSource
|
||||||
type: python
|
type: python
|
||||||
@@ -868,19 +883,29 @@ virtual_gas_source:
|
|||||||
string: string
|
string: string
|
||||||
feedback: {}
|
feedback: {}
|
||||||
result: {}
|
result: {}
|
||||||
|
# 虚拟气源节点配置 - 气体供应设备,1个输出口提供加压气体
|
||||||
handles:
|
handles:
|
||||||
- handler_key: out
|
- handler_key: gassource
|
||||||
label: out
|
label: gassource
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
io_type: source
|
side: SOUTH
|
||||||
data_source: executor
|
io_type: source
|
||||||
data_key: fluid_out
|
data_source: executor
|
||||||
init_param_schema:
|
data_key: fluid_out
|
||||||
|
description: "气源出气口,向容器或管路提供加压气体"
|
||||||
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
port:
|
port:
|
||||||
type: string
|
type: string
|
||||||
description: "通信端口"
|
|
||||||
default: "VIRTUAL"
|
default: "VIRTUAL"
|
||||||
required:
|
description: "通信端口"
|
||||||
- port
|
gas_type:
|
||||||
|
type: string
|
||||||
|
default: "nitrogen"
|
||||||
|
description: "气体类型"
|
||||||
|
max_pressure:
|
||||||
|
type: number
|
||||||
|
default: 5.0
|
||||||
|
description: "最大输出压力 (bar)"
|
||||||
|
additionalProperties: false
|
||||||
|
|||||||
@@ -6,9 +6,16 @@ container:
|
|||||||
handles:
|
handles:
|
||||||
- handler_key: top
|
- handler_key: top
|
||||||
label: top
|
label: top
|
||||||
|
io_type: target
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
side: NORTH
|
side: NORTH
|
||||||
- handler_key: bottom
|
- handler_key: bottom
|
||||||
label: bottom
|
label: bottom
|
||||||
|
io_type: source
|
||||||
data_type: fluid
|
data_type: fluid
|
||||||
|
side: SOUTH
|
||||||
|
- handler_key: bind
|
||||||
|
label: bind
|
||||||
|
io_type: target
|
||||||
|
data_type: mechanical
|
||||||
side: SOUTH
|
side: SOUTH
|
||||||
@@ -175,8 +175,7 @@ def modify_to_backend_format(data: list[dict[str, Any]]) -> list[dict[str, Any]]
|
|||||||
edge["targetHandle"] = port[target]
|
edge["targetHandle"] = port[target]
|
||||||
elif "target_port" in edge:
|
elif "target_port" in edge:
|
||||||
edge["targetHandle"] = edge.pop("target_port")
|
edge["targetHandle"] = edge.pop("target_port")
|
||||||
if "id" not in edge:
|
edge["id"] = f"reactflow__edge-{source}-{edge['sourceHandle']}-{target}-{edge['targetHandle']}"
|
||||||
edge["id"] = f"link_generated_{source}_{target}"
|
|
||||||
for key in ["source_port", "target_port"]:
|
for key in ["source_port", "target_port"]:
|
||||||
if key in edge:
|
if key in edge:
|
||||||
edge.pop(key)
|
edge.pop(key)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from unilabos_msgs.srv import (
|
|||||||
) # type: ignore
|
) # type: ignore
|
||||||
from unique_identifier_msgs.msg import UUID
|
from unique_identifier_msgs.msg import UUID
|
||||||
|
|
||||||
|
from unilabos.config.config import BasicConfig
|
||||||
from unilabos.registry.registry import lab_registry
|
from unilabos.registry.registry import lab_registry
|
||||||
from unilabos.resources.graphio import initialize_resource
|
from unilabos.resources.graphio import initialize_resource
|
||||||
from unilabos.resources.registry import add_schema
|
from unilabos.resources.registry import add_schema
|
||||||
@@ -146,13 +147,15 @@ class HostNode(BaseROS2DeviceNode):
|
|||||||
|
|
||||||
self.device_status = {} # 用来存储设备状态
|
self.device_status = {} # 用来存储设备状态
|
||||||
self.device_status_timestamps = {} # 用来存储设备状态最后更新时间
|
self.device_status_timestamps = {} # 用来存储设备状态最后更新时间
|
||||||
|
if BasicConfig.upload_registry:
|
||||||
|
from unilabos.app.mq import mqtt_client
|
||||||
|
|
||||||
from unilabos.app.mq import mqtt_client
|
for device_info in lab_registry.obtain_registry_device_info():
|
||||||
|
mqtt_client.publish_registry(device_info["id"], device_info)
|
||||||
for device_info in lab_registry.obtain_registry_device_info():
|
for resource_info in lab_registry.obtain_registry_resource_info():
|
||||||
mqtt_client.publish_registry(device_info["id"], device_info)
|
mqtt_client.publish_registry(resource_info["id"], resource_info)
|
||||||
for resource_info in lab_registry.obtain_registry_resource_info():
|
else:
|
||||||
mqtt_client.publish_registry(resource_info["id"], resource_info)
|
self.lab_logger().warning("本次启动注册表不报送云端,如果您需要联网调试,请使用unilab-register命令进行单独报送,或者在启动命令增加--upload_registry")
|
||||||
time.sleep(1) # 等待MQTT连接稳定
|
time.sleep(1) # 等待MQTT连接稳定
|
||||||
# 首次发现网络中的设备
|
# 首次发现网络中的设备
|
||||||
self._discover_devices()
|
self._discover_devices()
|
||||||
@@ -195,18 +198,18 @@ class HostNode(BaseROS2DeviceNode):
|
|||||||
resource_ids_to_instance = {i["id"]: i for i in resources_config}
|
resource_ids_to_instance = {i["id"]: i for i in resources_config}
|
||||||
resource_name_to_with_parent_name = {}
|
resource_name_to_with_parent_name = {}
|
||||||
for res in resources_config:
|
for res in resources_config:
|
||||||
if res.get("parent") and res.get("type") == "device" and res.get("class"):
|
# if res.get("parent") and res.get("type") == "device" and res.get("class"):
|
||||||
parent_id = res.get("parent")
|
# parent_id = res.get("parent")
|
||||||
parent_res = resource_ids_to_instance[parent_id]
|
# parent_res = resource_ids_to_instance[parent_id]
|
||||||
if parent_res.get("type") == "device" and parent_res.get("class"):
|
# if parent_res.get("type") == "device" and parent_res.get("class"):
|
||||||
resource_with_parent_name.append(copy.deepcopy(res))
|
# resource_with_parent_name.append(copy.deepcopy(res))
|
||||||
resource_name_to_with_parent_name[resource_with_parent_name[-1]["id"]] = f"{parent_res['id']}/{res['id']}"
|
# resource_name_to_with_parent_name[resource_with_parent_name[-1]["id"]] = f"{parent_res['id']}/{res['id']}"
|
||||||
resource_with_parent_name[-1]["id"] = f"{parent_res['id']}/{res['id']}"
|
# resource_with_parent_name[-1]["id"] = f"{parent_res['id']}/{res['id']}"
|
||||||
continue
|
# continue
|
||||||
resource_with_parent_name.append(copy.deepcopy(res))
|
resource_with_parent_name.append(copy.deepcopy(res))
|
||||||
for edge in self.resources_edge_config:
|
# for edge in self.resources_edge_config:
|
||||||
edge["source"] = resource_name_to_with_parent_name.get(edge.get("source"), edge.get("source"))
|
# edge["source"] = resource_name_to_with_parent_name.get(edge.get("source"), edge.get("source"))
|
||||||
edge["target"] = resource_name_to_with_parent_name.get(edge.get("target"), edge.get("target"))
|
# edge["target"] = resource_name_to_with_parent_name.get(edge.get("target"), edge.get("target"))
|
||||||
try:
|
try:
|
||||||
for bridge in self.bridges:
|
for bridge in self.bridges:
|
||||||
if hasattr(bridge, "resource_add"):
|
if hasattr(bridge, "resource_add"):
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
|
|||||||
|
|
||||||
def initialize_device(self, device_id, device_config):
|
def initialize_device(self, device_id, device_config):
|
||||||
"""初始化设备并创建相应的动作客户端"""
|
"""初始化设备并创建相应的动作客户端"""
|
||||||
device_id_abs = f"{self.device_id}/{device_id}"
|
# device_id_abs = f"{self.device_id}/{device_id}"
|
||||||
|
device_id_abs = f"{device_id}"
|
||||||
self.lab_logger().info(f"初始化子设备: {device_id_abs}")
|
self.lab_logger().info(f"初始化子设备: {device_id_abs}")
|
||||||
d = self.sub_devices[device_id] = initialize_device_from_dict(device_id_abs, device_config)
|
d = self.sub_devices[device_id] = initialize_device_from_dict(device_id_abs, device_config)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user