workstation_by_hhm

宜宾扣电工站与奔曜配液工站,更新截止10月20日
This commit is contained in:
h840473807
2025-10-20 15:36:53 +08:00
parent 54cfaf15f3
commit 079ec9d1b4
28 changed files with 26531 additions and 604 deletions

View File

@@ -24,6 +24,13 @@ class ElectrodeSheetState(TypedDict):
thickness: float # 厚度 (mm)
mass: float # 质量 (g)
material_type: str # 材料类型(正极、负极、隔膜、弹片、垫片、铝箔等)
height: float
electrolyte_name: str
data_electrolyte_code: str
open_circuit_voltage: float
assembly_pressure: float
electrolyte_volume: float
info: Optional[str] # 附加信息
class ElectrodeSheet(Resource):
@@ -147,10 +154,10 @@ class MaterialHole(Resource):
):
"""放置极片"""
# TODO: 这里要改diameter找不到加入._unilabos_state后应该没问题
if resource._unilabos_state["diameter"] > self._unilabos_state["diameter"]:
raise ValueError(f"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}")
if len(self.children) >= self._unilabos_state["max_sheets"]:
raise ValueError(f"洞位已满,无法放置更多极片")
#if resource._unilabos_state["diameter"] > self._unilabos_state["diameter"]:
# raise ValueError(f"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}")
#if len(self.children) >= self._unilabos_state["max_sheets"]:
# raise ValueError(f"洞位已满,无法放置更多极片")
super().assign_child_resource(resource, location, reassign)
# 根据children的编号取物料对象。
@@ -165,8 +172,6 @@ class MaterialPlateState(TypedDict):
hole_diameter: float
info: Optional[str] # 附加信息
class MaterialPlate(ItemizedResource[MaterialHole]):
"""料板类 - 4x4个洞位每个洞位放1个极片"""
@@ -324,12 +329,13 @@ class PlateSlot(ResourceStack):
class ClipMagazineHole(Container):
"""子弹夹洞位类"""
children: List[ElectrodeSheet] = []
def __init__(
self,
name: str,
diameter: float,
depth: float,
max_sheets: int = 100,
category: str = "clip_magazine_hole",
):
"""初始化子弹夹洞位
@@ -338,6 +344,7 @@ class ClipMagazineHole(Container):
name: 洞位名称
diameter: 洞直径 (mm)
depth: 洞深度 (mm)
max_sheets: 最大极片数量
category: 类别
"""
super().__init__(
@@ -349,143 +356,46 @@ class ClipMagazineHole(Container):
)
self.diameter = diameter
self.depth = depth
self.max_sheets = max_sheets
self._sheets: List[ElectrodeSheet] = []
def can_add_sheet(self, sheet: ElectrodeSheet) -> bool:
"""检查是否可以添加极片
根据洞的深度和极片的厚度来判断是否可以添加极片
"""
# 检查极片直径是否适合洞的直径
if sheet._unilabos_state["diameter"] > self.diameter:
return False
# 计算当前已添加极片的总厚度
current_thickness = sum(s._unilabos_state["thickness"] for s in self.children)
# 检查添加新极片后总厚度是否超过洞的深度
if current_thickness + sheet._unilabos_state["thickness"] > self.depth:
return False
return True
"""检查是否可以添加极片"""
return (len(self._sheets) < self.max_sheets and
sheet.diameter <= self.diameter)
def add_sheet(self, sheet: ElectrodeSheet) -> None:
"""添加极片"""
if not self.can_add_sheet(sheet):
raise ValueError(f"无法向洞位 {self.name} 添加极片")
self._sheets.append(sheet)
def assign_child_resource(
self,
resource: ElectrodeSheet,
location: Optional[Coordinate] = None,
reassign: bool = True,
):
"""放置极片到洞位中
Args:
resource: 要放置的极片
location: 极片在洞位中的位置对于洞位通常为None
reassign: 是否允许重新分配
"""
# 检查是否可以添加极片
if not self.can_add_sheet(resource):
raise ValueError(f"无法向洞位 {self.name} 添加极片:直径或厚度不匹配")
# 调用父类方法实际执行分配
super().assign_child_resource(resource, location, reassign)
def unassign_child_resource(self, resource: ElectrodeSheet):
"""从洞位中移除极片
Args:
resource: 要移除的极片
"""
if resource not in self.children:
raise ValueError(f"极片 {resource.name} 不在洞位 {self.name}")
# 调用父类方法实际执行移除
super().unassign_child_resource(resource)
def take_sheet(self) -> ElectrodeSheet:
"""取出极片"""
if len(self._sheets) == 0:
raise ValueError(f"洞位 {self.name} 没有极片")
return self._sheets.pop()
def get_sheet_count(self) -> int:
"""获取极片数量"""
return len(self._sheets)
def serialize_state(self) -> Dict[str, Any]:
return {
"sheet_count": len(self.children),
"sheets": [sheet.serialize() for sheet in self.children],
"sheet_count": len(self._sheets),
"sheets": [sheet.serialize() for sheet in self._sheets],
}
class ClipMagazine_four(ItemizedResource[ClipMagazineHole]):
"""子弹夹类 - 有4个洞位每个洞位放多个极片"""
children: List[ClipMagazineHole]
def __init__(
self,
name: str,
size_x: float,
size_y: float,
size_z: float,
hole_diameter: float = 14.0,
hole_depth: float = 10.0,
hole_spacing: float = 25.0,
max_sheets_per_hole: int = 100,
category: str = "clip_magazine_four",
model: Optional[str] = None,
):
"""初始化子弹夹
Args:
name: 子弹夹名称
size_x: 长度 (mm)
size_y: 宽度 (mm)
size_z: 高度 (mm)
hole_diameter: 洞直径 (mm)
hole_depth: 洞深度 (mm)
hole_spacing: 洞位间距 (mm)
max_sheets_per_hole: 每个洞位最大极片数量
category: 类别
model: 型号
"""
# 创建4个洞位排成2x2布局
holes = create_ordered_items_2d(
klass=ClipMagazineHole,
num_items_x=2,
num_items_y=2,
dx=(size_x - 2 * hole_spacing) / 2, # 居中
dy=(size_y - hole_spacing) / 2, # 居中
dz=size_z - 0,
item_dx=hole_spacing,
item_dy=hole_spacing,
diameter=hole_diameter,
depth=hole_depth,
)
super().__init__(
name=name,
size_x=size_x,
size_y=size_y,
size_z=size_z,
ordered_items=holes,
category=category,
model=model,
)
# 保存洞位的直径和深度
self.hole_diameter = hole_diameter
self.hole_depth = hole_depth
self.max_sheets_per_hole = max_sheets_per_hole
def serialize(self) -> dict:
return {
**super().serialize(),
"hole_diameter": self.hole_diameter,
"hole_depth": self.hole_depth,
"max_sheets_per_hole": self.max_sheets_per_hole,
}
# TODO: 这个要改
class ClipMagazine(ItemizedResource[ClipMagazineHole]):
class ClipMagazine(Resource):
"""子弹夹类 - 有6个洞位每个洞位放多个极片"""
children: List[ClipMagazineHole]
def __init__(
self,
name: str,
size_x: float,
size_y: float,
size_z: float,
hole_diameter: float = 14.0,
hole_depth: float = 10.0,
hole_spacing: float = 25.0,
max_sheets_per_hole: int = 100,
category: str = "clip_magazine",
@@ -515,8 +425,8 @@ class ClipMagazine(ItemizedResource[ClipMagazineHole]):
dz=size_z - 0,
item_dx=hole_spacing,
item_dy=hole_spacing,
diameter=hole_diameter,
depth=hole_depth,
diameter=0,
depth=0,
)
super().__init__(
@@ -529,7 +439,6 @@ class ClipMagazine(ItemizedResource[ClipMagazineHole]):
model=model,
)
# 保存洞位的直径和深度
self.hole_diameter = hole_diameter
self.hole_depth = hole_depth
self.max_sheets_per_hole = max_sheets_per_hole
@@ -546,9 +455,9 @@ class BatteryState(TypedDict):
"""电池状态字典"""
diameter: float
height: float
electrolyte_name: str
assembly_pressure: float
electrolyte_volume: float
electrolyte_name: str
class Battery(Resource):
"""电池类 - 可容纳极片"""
@@ -557,6 +466,9 @@ class Battery(Resource):
def __init__(
self,
name: str,
size_x=1,
size_y=1,
size_z=1,
category: str = "battery",
):
"""初始化电池
@@ -577,7 +489,13 @@ class Battery(Resource):
size_z=1,
category=category,
)
self._unilabos_state: BatteryState = BatteryState()
self._unilabos_state: BatteryState = BatteryState(
diameter = 1.0,
height = 1.0,
assembly_pressure = 1.0,
electrolyte_volume = 1.0,
electrolyte_name = "DP001"
)
def add_electrolyte_with_bottle(self, bottle: Bottle) -> bool:
to_add_name = bottle._unilabos_state["electrolyte_name"]
@@ -733,15 +651,6 @@ class TipBox64(TipRack):
make_tip=make_tip,
)
self._unilabos_state: WasteTipBoxstate = WasteTipBoxstate()
# 记录网格参数用于前端渲染
self._grid_params = {
"num_items_x": 8,
"num_items_y": 8,
"dx": 8.0,
"dy": 8.0,
"item_dx": 9.0,
"item_dy": 9.0,
}
super().__init__(
name=name,
size_x=size_x,
@@ -753,12 +662,6 @@ class TipBox64(TipRack):
with_tips=True,
)
def serialize(self) -> dict:
return {
**super().serialize(),
**self._grid_params,
}
class WasteTipBoxstate(TypedDict):
@@ -836,34 +739,19 @@ class BottleRackState(TypedDict):
name_to_index: dict
class BottleRackState(TypedDict):
""" bottle_diameter: 瓶子直径 (mm)
bottle_height: 瓶子高度 (mm)
position_spacing: 位置间距 (mm)"""
bottle_diameter: float
bottle_height: float
position_spacing: float
name_to_index: dict
class BottleRack(Resource):
"""瓶架类 - 12个待配位置+12个已配位置"""
children: List[Resource] = []
children: List[Bottle] = []
def __init__(
self,
name: str,
size_x: float,
size_y: float,
size_z: float,
category: str = "bottle_rack",
model: Optional[str] = None,
num_items_x: int = 3,
num_items_y: int = 4,
position_spacing: float = 35.0,
orientation: str = "horizontal",
padding_x: float = 20.0,
padding_y: float = 20.0,
self,
name: str,
size_x: float,
size_y: float,
size_z: float,
category: str = "bottle_rack",
model: Optional[str] = None,
):
"""初始化瓶架
@@ -883,42 +771,13 @@ class BottleRack(Resource):
category=category,
model=model,
)
# 初始化状态
self._unilabos_state: BottleRackState = BottleRackState(
bottle_diameter=30.0,
bottle_height=100.0,
position_spacing=position_spacing,
name_to_index={},
)
# 基于网格生成瓶位坐标映射(居中摆放)
# 使用内边距避免点跑到容器外前端渲染不按mm等比缩放时更稳妥
origin_x = padding_x
origin_y = padding_y
self.index_to_pos = {}
for j in range(num_items_y):
for i in range(num_items_x):
idx = j * num_items_x + i
if orientation == "vertical":
# 纵向:沿 y 方向优先排列
self.index_to_pos[idx] = Coordinate(
x=origin_x + j * position_spacing,
y=origin_y + i * position_spacing,
z=0,
)
else:
# 横向(默认):沿 x 方向优先排列
self.index_to_pos[idx] = Coordinate(
x=origin_x + i * position_spacing,
y=origin_y + j * position_spacing,
z=0,
)
# TODO: 添加瓶位坐标映射
self.index_to_pos = {
0: Coordinate.zero(),
1: Coordinate(x=1, y=2, z=3) # 添加
}
self.name_to_index = {}
self.name_to_pos = {}
self.num_items_x = num_items_x
self.num_items_y = num_items_y
self.orientation = orientation
self.padding_x = padding_x
self.padding_y = padding_y
def load_state(self, state: Dict[str, Any]) -> None:
"""格式不变"""
@@ -928,23 +787,20 @@ class BottleRack(Resource):
def serialize_state(self) -> Dict[str, Dict[str, Any]]:
"""格式不变"""
data = super().serialize_state()
data.update(
self._unilabos_state) # Container自身的信息云端物料将保存这一data本地也通过这里的data进行读写当前类用来表示这个物料的长宽高大小的属性而datastate用来表示物料的内容细节等
data.update(self._unilabos_state) # Container自身的信息云端物料将保存这一data本地也通过这里的data进行读写当前类用来表示这个物料的长宽高大小的属性而datastate用来表示物料的内容细节等
return data
# TODO: 这里有些问题要重新写一下
def assign_child_resource_old(self, resource: Resource, location=Coordinate.zero(), reassign=True):
capacity = self.num_items_x * self.num_items_y
assert len(self.children) < capacity, "瓶架已满,无法添加更多瓶子"
def assign_child_resource(self, resource: Bottle, location=Coordinate.zero(), reassign = True):
assert len(self.children) <= 12, "瓶架已满,无法添加更多瓶子"
index = len(self.children)
location = self.index_to_pos.get(index, Coordinate.zero())
location = Coordinate(x=20 + (index % 4) * 15, y=20 + (index // 4) * 15, z=0)
self.name_to_pos[resource.name] = location
self.name_to_index[resource.name] = index
return super().assign_child_resource(resource, location, reassign)
def assign_child_resource(self, resource: Resource, index: int):
capacity = self.num_items_x * self.num_items_y
assert 0 <= index < capacity, "无效的瓶子索引"
def assign_child_resource_by_index(self, resource: Bottle, index: int):
assert 0 <= index < 12, "无效的瓶子索引"
self.name_to_index[resource.name] = index
location = self.index_to_pos[index]
return super().assign_child_resource(resource, location)
@@ -953,16 +809,9 @@ class BottleRack(Resource):
super().unassign_child_resource(resource)
self.index_to_pos.pop(self.name_to_index.pop(resource.name, None), None)
def serialize(self) -> dict:
return {
**super().serialize(),
"num_items_x": self.num_items_x,
"num_items_y": self.num_items_y,
"position_spacing": self._unilabos_state.get("position_spacing", 35.0),
"orientation": self.orientation,
"padding_x": self.padding_x,
"padding_y": self.padding_y,
}
# def serialize(self):
# self.children.sort(key=lambda x: self.name_to_index.get(x.name, 0))
# return super().serialize()
class BottleState(TypedDict):
@@ -1098,16 +947,20 @@ class CoincellDeck(Deck):
# plate.assign_child_resource(hole)
# return plate
def create_a_liaopan():
liaopan = MaterialPlate(name="liaopan", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
for i in range(16):
jipian = ElectrodeSheet(name=f"jipian_{i}", size_x= 12, size_y=12, size_z=0.1)
liaopan1.children[i].assign_child_resource(jipian, location=None)
return liaopan
import json
def create_a_coin_cell_deck():
deck = Deck(size_x=1200,
size_y=800,
if __name__ == "__main__":
#electrode1 = BatteryPressSlot()
#print(electrode1.get_size_x())
#print(electrode1.get_size_y())
#print(electrode1.get_size_z())
#jipian = ElectrodeSheet()
#jipian._unilabos_state["diameter"] = 18
#print(jipian.serialize())
#print(jipian.serialize_state())
deck = CoincellDeck(size_x=1000,
size_y=1000,
size_z=900)
#liaopan = TipBox64(name="liaopan")
@@ -1118,172 +971,33 @@ def create_a_coin_cell_deck():
deck.assign_child_resource(liaopan1, Coordinate(x=0, y=0, z=0))
#创建一个极片
for i in range(16):
jipian = ElectrodeSheet(name=f"jipian_{i}", size_x= 12, size_y=12, size_z=0.1)
jipian = ElectrodeSheet(name=f"jipian1_{i}", size_x= 12, size_y=12, size_z=0.1)
liaopan1.children[i].assign_child_resource(jipian, location=None)
#
#创建一个4*4的物料板
liaopan2 = MaterialPlate(name="liaopan2", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
#把物料板放到桌子上
deck.assign_child_resource(liaopan2, Coordinate(x=500, y=0, z=0))
#创建一个4*4的物料板
liaopan3 = MaterialPlate(name="liaopan3", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)
liaopan3 = MaterialPlate(name="电池料盘", size_x=120.8, size_y=160.5, size_z=10.0, fill=True)
#把物料板放到桌子上
deck.assign_child_resource(liaopan3, Coordinate(x=1000, y=0, z=0))
print(deck)
return deck
deck.assign_child_resource(liaopan3, Coordinate(x=100, y=100, z=0))
import json
if __name__ == "__main__":
electrode1 = BatteryPressSlot()
#print(electrode1.get_size_x())
#print(electrode1.get_size_y())
#print(electrode1.get_size_z())
#jipian = ElectrodeSheet()
#jipian._unilabos_state["diameter"] = 18
#print(jipian.serialize())
#print(jipian.serialize_state())
deck = CoincellDeck()
"""======================================子弹夹============================================"""
zip_dan_jia = ClipMagazine_four("zi_dan_jia", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia, Coordinate(x=1400, y=50, z=0))
zip_dan_jia2 = ClipMagazine_four("zi_dan_jia2", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia2, Coordinate(x=1600, y=200, z=0))
zip_dan_jia3 = ClipMagazine("zi_dan_jia3", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia3, Coordinate(x=1500, y=200, z=0))
zip_dan_jia4 = ClipMagazine("zi_dan_jia4", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia4, Coordinate(x=1500, y=300, z=0))
zip_dan_jia5 = ClipMagazine("zi_dan_jia5", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia5, Coordinate(x=1600, y=300, z=0))
zip_dan_jia6 = ClipMagazine("zi_dan_jia6", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia6, Coordinate(x=1530, y=500, z=0))
zip_dan_jia7 = ClipMagazine("zi_dan_jia7", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia7, Coordinate(x=1180, y=400, z=0))
zip_dan_jia8 = ClipMagazine("zi_dan_jia8", 80, 80, 10)
deck.assign_child_resource(zip_dan_jia8, Coordinate(x=1280, y=400, z=0))
for i in range(4):
jipian = ElectrodeSheet(name=f"zi_dan_jia_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia2.children[i].assign_child_resource(jipian, location=None)
for i in range(4):
jipian2 = ElectrodeSheet(name=f"zi_dan_jia2_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia.children[i].assign_child_resource(jipian2, location=None)
for i in range(6):
jipian3 = ElectrodeSheet(name=f"zi_dan_jia3_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia3.children[i].assign_child_resource(jipian3, location=None)
for i in range(6):
jipian4 = ElectrodeSheet(name=f"zi_dan_jia4_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia4.children[i].assign_child_resource(jipian4, location=None)
for i in range(6):
jipian5 = ElectrodeSheet(name=f"zi_dan_jia5_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia5.children[i].assign_child_resource(jipian5, location=None)
for i in range(6):
jipian6 = ElectrodeSheet(name=f"zi_dan_jia6_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia6.children[i].assign_child_resource(jipian6, location=None)
for i in range(6):
jipian7 = ElectrodeSheet(name=f"zi_dan_jia7_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia7.children[i].assign_child_resource(jipian7, location=None)
for i in range(6):
jipian8 = ElectrodeSheet(name=f"zi_dan_jia8_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
zip_dan_jia8.children[i].assign_child_resource(jipian8, location=None)
"""======================================子弹夹============================================"""
#liaopan = TipBox64(name="liaopan")
"""======================================物料板============================================"""
#创建一个4*4的物料板
liaopan1 = MaterialPlate(name="liaopan1", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan1, Coordinate(x=1010, y=50, z=0))
for i in range(16):
jipian_1 = ElectrodeSheet(name=f"{liaopan1.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
liaopan1.children[i].assign_child_resource(jipian_1, location=None)
liaopan2 = MaterialPlate(name="liaopan2", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan2, Coordinate(x=1130, y=50, z=0))
liaopan3 = MaterialPlate(name="liaopan3", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan3, Coordinate(x=1250, y=50, z=0))
liaopan4 = MaterialPlate(name="liaopan4", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan4, Coordinate(x=1010, y=150, z=0))
for i in range(16):
jipian_4 = ElectrodeSheet(name=f"{liaopan4.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
liaopan4.children[i].assign_child_resource(jipian_4, location=None)
liaopan5 = MaterialPlate(name="liaopan5", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan5, Coordinate(x=1130, y=150, z=0))
liaopan6 = MaterialPlate(name="liaopan6", size_x=120, size_y=100, size_z=10.0, fill=True)
deck.assign_child_resource(liaopan6, Coordinate(x=1250, y=150, z=0))
#liaopan.children[3].assign_child_resource(jipian, location=None)
"""======================================物料板============================================"""
"""======================================瓶架,移液枪============================================"""
# 在台面上放置 3x4 瓶架、6x2 瓶架 与 64孔移液枪头盒
bottle_rack_3x4 = BottleRack(
name="bottle_rack_3x4",
size_x=210.0,
size_y=140.0,
size_z=100.0,
num_items_x=3,
num_items_y=4,
position_spacing=35.0,
orientation="vertical",
)
deck.assign_child_resource(bottle_rack_3x4, Coordinate(x=100, y=200, z=0))
bottle_rack_6x2 = BottleRack(
name="bottle_rack_6x2",
size_x=120.0,
size_y=250.0,
size_z=100.0,
num_items_x=6,
num_items_y=2,
position_spacing=35.0,
orientation="vertical",
)
deck.assign_child_resource(bottle_rack_6x2, Coordinate(x=300, y=300, z=0))
bottle_rack_6x2_2 = BottleRack(
name="bottle_rack_6x2_2",
size_x=120.0,
size_y=250.0,
size_z=100.0,
num_items_x=6,
num_items_y=2,
position_spacing=35.0,
orientation="vertical",
)
deck.assign_child_resource(bottle_rack_6x2_2, Coordinate(x=430, y=300, z=0))
# 将 ElectrodeSheet 放满 3x4 与 6x2 的所有孔位
for idx in range(bottle_rack_3x4.num_items_x * bottle_rack_3x4.num_items_y):
sheet = ElectrodeSheet(name=f"sheet_3x4_{idx}", size_x=12, size_y=12, size_z=0.1)
bottle_rack_3x4.assign_child_resource(sheet, index=idx)
for idx in range(bottle_rack_6x2.num_items_x * bottle_rack_6x2.num_items_y):
sheet = ElectrodeSheet(name=f"sheet_6x2_{idx}", size_x=12, size_y=12, size_z=0.1)
bottle_rack_6x2.assign_child_resource(sheet, index=idx)
tip_box = TipBox64(name="tip_box_64")
deck.assign_child_resource(tip_box, Coordinate(x=300, y=100, z=0))
waste_tip_box = WasteTipBox(name="waste_tip_box")
deck.assign_child_resource(waste_tip_box, Coordinate(x=300, y=200, z=0))
"""======================================瓶架,移液枪============================================"""
print(deck)
from unilabos.resources.graphio import convert_resources_from_type
from unilabos.config.config import BasicConfig
BasicConfig.ak = "56bbed5b-6e30-438c-b06d-f69eaa63bb45"
BasicConfig.sk = "238222fe-0bf7-4350-a426-e5ced8011dcf"
BasicConfig.ak = "4d5ce6ae-7234-4639-834e-93899b9caf94"
BasicConfig.sk = "505d3b0a-620e-459a-9905-1efcffce382a"
from unilabos.app.web.client import http_client
resources = convert_resources_from_type([deck], [Resource])
# 检查序列化后的资源
json.dump({"nodes": resources, "links": []}, open("button_battery_decks_unilab.json", "w"), indent=2)
json.dump({"nodes": resources, "links": []}, open("button_battery_station_resources_unilab.json", "w"), indent=2)
#print(resources)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
class CoinCellAssemblyWorkstation(WorkstationBase):
def __init__(
self,
deck: CoincellDeck,
station_resource: CoincellDeck,
address: str = "192.168.1.20",
port: str = "502",
debug_mode: bool = True,
@@ -30,12 +30,12 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
):
super().__init__(
#桌子
deck=deck,
station_resource=station_resource,
*args,
**kwargs,
)
self.debug_mode = debug_mode
self.deck = deck
self.station_resource = station_resource
""" 连接初始化 """
modbus_client = TCPClient(addr=address, port=port)
print("modbus_client", modbus_client)
@@ -60,6 +60,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
self.csv_export_thread = None
self.csv_export_running = False
self.csv_export_file = None
self.coin_num_N = 0 #已组装电池数量
#创建一个物料台面,包含两个极片板
#self.deck = create_a_coin_cell_deck()
@@ -74,7 +75,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
self._ros_node = ros_node
#self.deck = create_a_coin_cell_deck()
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
"resources": [self.deck]
"resources": [self.station_resource]
})
# 批量操作在这里写
@@ -84,7 +85,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
async def fill_plate(self):
plate_1: MaterialPlate = self.deck.children[0].children[0]
plate_1: MaterialPlate = self.station_resource.children[0].children[0]
#plate_1
return await self._ros_node.update_resource(plate_1)
@@ -341,7 +342,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
def modify_deck_name(self, resource_name: str):
# figure_res = self._ros_node.resource_tracker.figure_resource({"name": resource_name})
# print(f"!!! figure_res: {type(figure_res)}")
self.deck.children[1]
self.station_resource.children[1]
return
@property
@@ -606,7 +607,8 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
print("waiting for start_cmd")
time.sleep(1)
def func_pack_send_bottle_num(self, bottle_num: int):
def func_pack_send_bottle_num(self, bottle_num):
bottle_num = int(bottle_num)
#发送电解液平台数
print("启动")
while (self._unilab_rece_electrolyte_bottle_num()) == False:
@@ -697,6 +699,23 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
print("data_electrolyte_code", data_electrolyte_code)
print("data_coin_cell_code", data_coin_cell_code)
#接收完信息后读取完毕标志位置True
liaopan3 = self.station_resource.get_resource("\u7535\u6c60\u6599\u76d8")
#把物料解绑后放到另一盘上
battery = ElectrodeSheet(name=f"battery_{self.coin_num_N}", size_x=14, size_y=14, size_z=2)
battery._unilabos_state = {
"electrolyte_name": data_coin_cell_code,
"data_electrolyte_code": data_electrolyte_code,
"open_circuit_voltage": data_open_circuit_voltage,
"assembly_pressure": data_assembly_pressure,
"electrolyte_volume": data_electrolyte_volume
}
liaopan3.children[self.coin_num_N].assign_child_resource(battery, location=None)
#print(jipian2.parent)
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
"resources": [self.station_resource]
})
self._unilab_rec_msg_succ_cmd(True)
time.sleep(1)
#等待允许读取标志位置False
@@ -757,6 +776,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
def func_allpack_cmd(self, elec_num, elec_use_num, file_path: str="D:\\coin_cell_data") -> bool:
elec_num, elec_use_num = int(elec_num), int(elec_use_num)
summary_csv_file = os.path.join(file_path, "duandian.csv")
# 如果断点文件存在,先读取之前的进度
if os.path.exists(summary_csv_file):
@@ -784,20 +804,22 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
elec_num_N = 0
elec_use_num_N = 0
coin_num_N = 0
print(f"剩余电解液瓶数: {elec_num}, 已组装电池数: {elec_use_num}")
for i in range(20):
print(f"剩余电解液瓶数: {elec_num}, 已组装电池数: {elec_use_num}")
print(f"剩余电解液瓶数: {type(elec_num)}, 已组装电池数: {type(elec_use_num)}")
print(f"剩余电解液瓶数: {type(int(elec_num))}, 已组装电池数: {type(int(elec_use_num))}")
#如果是第一次运行,则进行初始化、切换自动、启动, 如果是断点重启则跳过。
if read_status_flag == False:
pass
#初始化
self.func_pack_device_init()
#self.func_pack_device_init()
#切换自动
self.func_pack_device_auto()
#self.func_pack_device_auto()
#启动,小车收回
self.func_pack_device_start()
#self.func_pack_device_start()
#发送电解液瓶数量,启动搬运,多搬运没事
self.func_pack_send_bottle_num(elec_num)
#self.func_pack_send_bottle_num(elec_num)
last_i = elec_num_N
last_j = elec_use_num_N
for i in range(last_i, elec_num):
@@ -811,27 +833,9 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
#读取电池组装数据并存入csv
self.func_pack_get_msg_cmd(file_path)
time.sleep(1)
#这里定义物料系统
# TODO:读完再将电池数加一还是进入循环就将电池数加一需要考虑
liaopan1 = self.deck.get_resource("liaopan1")
liaopan4 = self.deck.get_resource("liaopan4")
jipian1 = liaopan1.children[coin_num_N].children[0]
jipian4 = liaopan4.children[coin_num_N].children[0]
#print(jipian1)
#从料盘上去物料解绑后放到另一盘上
jipian1.parent.unassign_child_resource(jipian1)
jipian4.parent.unassign_child_resource(jipian4)
#print(jipian2.parent)
battery = Battery(name = f"battery_{coin_num_N}")
battery.assign_child_resource(jipian1, location=None)
battery.assign_child_resource(jipian4, location=None)
zidanjia6 = self.deck.get_resource("zi_dan_jia6")
zidanjia6.children[0].assign_child_resource(battery, location=None)
# 生成断点文件
# 生成包含elec_num_N、coin_num_N、timestamp的CSV文件
@@ -842,6 +846,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
writer.writerow([elec_num, elec_use_num, elec_num_N, elec_use_num_N, coin_num_N, timestamp])
csvfile.flush()
coin_num_N += 1
self.coin_num_N = coin_num_N
elec_use_num_N += 1
elec_num_N += 1
elec_use_num_N = 0
@@ -878,34 +883,37 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
def fun_wuliao_test(self) -> bool:
#找到data_init中构建的2个物料盘
#liaopan1 = self.deck.get_resource("liaopan1")
#liaopan4 = self.deck.get_resource("liaopan4")
#for coin_num_N in range(16):
# liaopan1 = self.deck.get_resource("liaopan1")
# liaopan4 = self.deck.get_resource("liaopan4")
# jipian1 = liaopan1.children[coin_num_N].children[0]
# jipian4 = liaopan4.children[coin_num_N].children[0]
# #print(jipian1)
# #从料盘上去物料解绑后放到另一盘上
# jipian1.parent.unassign_child_resource(jipian1)
# jipian4.parent.unassign_child_resource(jipian4)
#
# #print(jipian2.parent)
# battery = Battery(name = f"battery_{coin_num_N}")
# battery.assign_child_resource(jipian1, location=None)
# battery.assign_child_resource(jipian4, location=None)
#
# zidanjia6 = self.deck.get_resource("zi_dan_jia6")
# zidanjia6.children[0].assign_child_resource(battery, location=None)
# ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
# "resources": [self.deck]
# })
# time.sleep(2)
for i in range(20):
print(f"输出{i}")
time.sleep(2)
liaopan1 = self.station_resource.get_resource("liaopan1")
liaopan2 = self.station_resource.get_resource("liaopan2")
for i in range(16):
#找到liaopan1上每一个jipian
jipian_linshi = liaopan1.children[i].children[0]
#把物料解绑后放到另一盘上
print("极片:", jipian_linshi)
jipian_linshi.parent.unassign_child_resource(jipian_linshi)
liaopan2.children[i].assign_child_resource(jipian_linshi, location=None)
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
"resources": [self.station_resource]
})
time.sleep(4)
"""
liaopan3 = self.station_resource.get_resource("\u7535\u6c60\u6599\u76d8")
for i in range(16):
battery = ElectrodeSheet(name=f"battery_{i}", size_x=16, size_y=16, size_z=2)
battery._unilabos_state = {
"diameter": 20.0,
"height": 20.0,
"assembly_pressure": i,
"electrolyte_volume": 20.0,
"electrolyte_name": f"DP{i}"
}
liaopan3.children[i].assign_child_resource(battery, location=None)
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
"resources": [self.station_resource]
})
time.sleep(4)
"""
# 数据读取与输出
def func_read_data_and_output(self, file_path: str="D:\\coin_cell_data"):
# 检查CSV导出是否正在运行已运行则跳出防止同时启动两个while循环
@@ -1119,24 +1127,52 @@ if __name__ == "__main__":
#print("success")
#创建一个物料台面
#deck = create_a_coin_cell_deck()
deck = create_a_coin_cell_deck()
#deck = create_a_full_coin_cell_deck()
##在台面上找到料盘和极片
#liaopan1 = deck.get_resource("liaopan1")
#liaopan2 = deck.get_resource("liaopan2")
#jipian1 = liaopan1.children[1].children[0]
#
##print(jipian1)
##
#print(jipian1)
##把物料解绑后放到另一盘上
#jipian1.parent.unassign_child_resource(jipian1)
#liaopan2.children[1].assign_child_resource(jipian1, location=None)
##print(jipian2.parent)
liaopan1 = deck.get_resource("liaopan1")
liaopan2 = deck.get_resource("liaopan2")
for i in range(16):
#找到liaopan1上每一个jipian
jipian_linshi = liaopan1.children[i].children[0]
#把物料解绑后放到另一盘上
print("极片:", jipian_linshi)
jipian_linshi.parent.unassign_child_resource(jipian_linshi)
liaopan2.children[i].assign_child_resource(jipian_linshi, location=None)
from unilabos.resources.graphio import resource_ulab_to_plr, convert_resources_to_type
#with open("./button_battery_station_resources_unilab.json", "r", encoding="utf-8") as f:
# bioyond_resources_unilab = json.load(f)
#print(f"成功读取 JSON 文件,包含 {len(bioyond_resources_unilab)} 个资源")
#ulab_resources = convert_resources_to_type(bioyond_resources_unilab, List[PLRResource])
#print(f"转换结果类型: {type(ulab_resources)}")
#print(ulab_resources)
with open("./button_battery_decks_unilab.json", "r", encoding="utf-8") as f:
bioyond_resources_unilab = json.load(f)
print(f"成功读取 JSON 文件,包含 {len(bioyond_resources_unilab)} 个资源")
ulab_resources = convert_resources_to_type(bioyond_resources_unilab, List[PLRResource])
print(f"转换结果类型: {type(ulab_resources)}")
print(ulab_resources)
from unilabos.resources.graphio import convert_resources_from_type
from unilabos.config.config import BasicConfig
BasicConfig.ak = "beb0c15f-2279-46a1-aba5-00eaf89aef55"
BasicConfig.sk = "15d4f25e-3512-4f9c-9bfb-43ab85e7b561"
from unilabos.app.web.client import http_client
resources = convert_resources_from_type([deck], [Resource])
json.dump({"nodes": resources, "links": []}, open("button_battery_station_resources_unilab.json", "w"), indent=2)
#print(resources)
http_client.remote_addr = "https://uni-lab.test.bohrium.com/api/v1"
http_client.resource_add(resources)

View File

@@ -0,0 +1,44 @@
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address
COIL_SYS_START_CMD,BOOL,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8010
COIL_SYS_STOP_CMD,BOOL,,<EFBFBD>豸ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8020
COIL_SYS_RESET_CMD,BOOL,,<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8030
COIL_SYS_HAND_CMD,BOOL,,<EFBFBD><EFBFBD>ֶ<EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8040
COIL_SYS_AUTO_CMD,BOOL,,<EFBFBD><EFBFBD>Զ<EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8050
COIL_SYS_INIT_CMD,BOOL,,<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8060
COIL_UNILAB_SEND_MSG_SUCC_CMD,BOOL,,UNILAB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8700
COIL_UNILAB_REC_MSG_SUCC_CMD,BOOL,,UNILAB<EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8710
COIL_SYS_START_STATUS,BOOL,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8210
COIL_SYS_STOP_STATUS,BOOL,,<EFBFBD>豸ֹͣ<EFBFBD><EFBFBD>,,coil,8220
COIL_SYS_RESET_STATUS,BOOL,,<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>,,coil,8230
COIL_SYS_HAND_STATUS,BOOL,,<EFBFBD><EFBFBD>ֶ<EFBFBD>ģʽ,,coil,8240
COIL_SYS_AUTO_STATUS,BOOL,,<EFBFBD><EFBFBD>Զ<EFBFBD>ģʽ,,coil,8250
COIL_SYS_INIT_STATUS,BOOL,,<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8260
COIL_REQUEST_REC_MSG_STATUS,BOOL,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8510
COIL_REQUEST_SEND_MSG_STATUS,BOOL,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,coil,8500
REG_MSG_ELECTROLYTE_USE_NUM,INT16,,<EFBFBD><EFBFBD>ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һʹ<EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD>,,hold_register,11000
REG_MSG_ELECTROLYTE_NUM,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һʹ<EFBFBD><EFBFBD>ƿ<EFBFBD><EFBFBD>,,hold_register,11002
REG_MSG_ELECTROLYTE_VOLUME,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>,,hold_register,11004
REG_MSG_ASSEMBLY_TYPE,INT16,,<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD>ʽ,,hold_register,11006
REG_MSG_ASSEMBLY_PRESSURE,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,11008
REG_DATA_ASSEMBLY_COIN_CELL_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10000
REG_DATA_OPEN_CIRCUIT_VOLTAGE,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10002
REG_DATA_AXIS_X_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺX<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10004
REG_DATA_AXIS_Y_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺZ<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10006
REG_DATA_AXIS_Z_POS,FLOAT32,,<EFBFBD><EFBFBD>ҺY<EFBFBD>ᵱǰλ<EFBFBD><EFBFBD>,,hold_register,10008
REG_DATA_POLE_WEIGHT,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10010
REG_DATA_ASSEMBLY_PER_TIME,FLOAT32,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װʱ<EFBFBD><EFBFBD>,,hold_register,10012
REG_DATA_ASSEMBLY_PRESSURE,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10014
REG_DATA_ELECTROLYTE_VOLUME,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>,,hold_register,10016
REG_DATA_COIN_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10018
REG_DATA_ELECTROLYTE_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>,,hold_register,10020
REG_DATA_COIN_CELL_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>,,hold_register,10030
REG_DATA_STACK_VISON_CODE,STRING,,<EFBFBD><EFBFBD><EFBFBD>϶ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,12004
REG_DATA_GLOVE_BOX_PRESSURE,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>,,hold_register,10050
REG_DATA_GLOVE_BOX_WATER_CONTENT,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10052
REG_DATA_GLOVE_BOX_O2_CONTENT,FLOAT32,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10054
UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM,BOOL,,Unilabȷ<EFBFBD><EFBFBD><EFBFBD>ѷ<EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Һƿ<EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8720
UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM,BOOL,,Unilab<EFBFBD>ɽ<EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD>Һƿ<EFBFBD><EFBFBD>,,coil,8520
REG_MSG_ELECTROLYTE_NUM_USED,INT16,,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,496
REG_DATA_ELECTROLYTE_USE_NUM,INT16,,<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>װƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,hold_register,10000
UNILAB_SEND_FINISHED_CMD,BOOL,,Unilab<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8730
UNILAB_RECE_FINISHED_CMD,BOOL,,<EFBFBD><EFBFBD>֪unilab<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,,coil,8530
1 Name DataType InitValue Comment Attribute DeviceType Address
2 COIL_SYS_START_CMD BOOL 设备启动命令 coil 8010
3 COIL_SYS_STOP_CMD BOOL 设备停止命令 coil 8020
4 COIL_SYS_RESET_CMD BOOL 设备复位命令 coil 8030
5 COIL_SYS_HAND_CMD BOOL 设备手动模式命令 coil 8040
6 COIL_SYS_AUTO_CMD BOOL 设备自动模式命令 coil 8050
7 COIL_SYS_INIT_CMD BOOL 设备初始化模式命令 coil 8060
8 COIL_UNILAB_SEND_MSG_SUCC_CMD BOOL UNILAB发送配方完毕 coil 8700
9 COIL_UNILAB_REC_MSG_SUCC_CMD BOOL UNILAB接受测试数据完毕 coil 8710
10 COIL_SYS_START_STATUS BOOL 设备启动中 coil 8210
11 COIL_SYS_STOP_STATUS BOOL 设备停止中 coil 8220
12 COIL_SYS_RESET_STATUS BOOL 设备复位中 coil 8230
13 COIL_SYS_HAND_STATUS BOOL 设备手动模式 coil 8240
14 COIL_SYS_AUTO_STATUS BOOL 设备自动模式 coil 8250
15 COIL_SYS_INIT_STATUS BOOL 设备初始化完成 coil 8260
16 COIL_REQUEST_REC_MSG_STATUS BOOL 设备请求接受配方 coil 8510
17 COIL_REQUEST_SEND_MSG_STATUS BOOL 设备请求发送测试数据 coil 8500
18 REG_MSG_ELECTROLYTE_USE_NUM INT16 单瓶电解液使用次数 hold_register 11000
19 REG_MSG_ELECTROLYTE_NUM INT16 电解液使用瓶数 hold_register 11002
20 REG_MSG_ELECTROLYTE_VOLUME INT16 电解液吸取量 hold_register 11004
21 REG_MSG_ASSEMBLY_TYPE INT16 组装参数:极片堆叠方式 hold_register 11006
22 REG_MSG_ASSEMBLY_PRESSURE INT16 电池组装压制力 hold_register 11008
23 REG_DATA_ASSEMBLY_COIN_CELL_NUM INT16 当前完成组装电池数量 hold_register 10000
24 REG_DATA_OPEN_CIRCUIT_VOLTAGE FLOAT32 当前电池电压数据 hold_register 10002
25 REG_DATA_AXIS_X_POS FLOAT32 分液X轴当前位置 hold_register 10004
26 REG_DATA_AXIS_Y_POS FLOAT32 分液Z轴当前位置 hold_register 10006
27 REG_DATA_AXIS_Z_POS FLOAT32 分液Y轴当前位置 hold_register 10008
28 REG_DATA_POLE_WEIGHT FLOAT32 当前电池正极片称重数据 hold_register 10010
29 REG_DATA_ASSEMBLY_PER_TIME FLOAT32 当前单颗电池组装时间 hold_register 10012
30 REG_DATA_ASSEMBLY_PRESSURE INT16 当前电池组装压制力 hold_register 10014
31 REG_DATA_ELECTROLYTE_VOLUME INT16 当前电解液加注量 hold_register 10016
32 REG_DATA_COIN_NUM INT16 当前电池物料数 hold_register 10018
33 REG_DATA_ELECTROLYTE_CODE STRING 电解液二维码序列号 hold_register 10020
34 REG_DATA_COIN_CELL_CODE STRING 电池二维码序列号 hold_register 10030
35 REG_DATA_STACK_VISON_CODE STRING 物料堆叠复检图片编码 hold_register 12004
36 REG_DATA_GLOVE_BOX_PRESSURE FLOAT32 手套箱压力 hold_register 10050
37 REG_DATA_GLOVE_BOX_WATER_CONTENT FLOAT32 手套箱水含量 hold_register 10052
38 REG_DATA_GLOVE_BOX_O2_CONTENT FLOAT32 手套箱氧含量 hold_register 10054
39 UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM BOOL Unilab确认已发送电解液瓶数信号 coil 8720
40 UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM BOOL Unilab可接受电解液瓶数 coil 8520
41 REG_MSG_ELECTROLYTE_NUM_USED INT16 电解液组装电池平行样数 hold_register 496
42 REG_DATA_ELECTROLYTE_USE_NUM INT16 当前已组装平行样数 hold_register 10000
43 UNILAB_SEND_FINISHED_CMD BOOL Unilab发送收到完成信号 coil 8730
44 UNILAB_RECE_FINISHED_CMD BOOL 告知unilab结束信号 coil 8530

View File

@@ -0,0 +1,46 @@
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address,
COIL_SYS_START_CMD,BOOL,,,,coil,8010,
COIL_SYS_STOP_CMD,BOOL,,,,coil,8020,
COIL_SYS_RESET_CMD,BOOL,,,,coil,8030,
COIL_SYS_HAND_CMD,BOOL,,,,coil,8040,
COIL_SYS_AUTO_CMD,BOOL,,,,coil,8050,
COIL_SYS_INIT_CMD,BOOL,,,,coil,8060,
COIL_UNILAB_SEND_MSG_SUCC_CMD,BOOL,,,,coil,8700,
COIL_UNILAB_REC_MSG_SUCC_CMD,BOOL,,,,coil,8710,unilab_rec_msg_succ_cmd
COIL_SYS_START_STATUS,BOOL,,,,coil,8210,
COIL_SYS_STOP_STATUS,BOOL,,,,coil,8220,
COIL_SYS_RESET_STATUS,BOOL,,,,coil,8230,
COIL_SYS_HAND_STATUS,BOOL,,,,coil,8240,
COIL_SYS_AUTO_STATUS,BOOL,,,,coil,8250,
COIL_SYS_INIT_STATUS,BOOL,,,,coil,8260,
COIL_REQUEST_REC_MSG_STATUS,BOOL,,,,coil,8500,
COIL_REQUEST_SEND_MSG_STATUS,BOOL,,,,coil,8510,request_send_msg_status
REG_MSG_ELECTROLYTE_USE_NUM,INT16,,,,hold_register,11000,
REG_MSG_ELECTROLYTE_NUM,INT16,,,,hold_register,11002,unilab_send_msg_electrolyte_num
REG_MSG_ELECTROLYTE_VOLUME,INT16,,,,hold_register,11004,unilab_send_msg_electrolyte_vol
REG_MSG_ASSEMBLY_TYPE,INT16,,,,hold_register,11006,unilab_send_msg_assembly_type
REG_MSG_ASSEMBLY_PRESSURE,INT16,,,,hold_register,11008,unilab_send_msg_assembly_pressure
REG_DATA_ASSEMBLY_COIN_CELL_NUM,INT16,,,,hold_register,10000,data_assembly_coin_cell_num
REG_DATA_OPEN_CIRCUIT_VOLTAGE,FLOAT32,,,,hold_register,10002,data_open_circuit_voltage
REG_DATA_AXIS_X_POS,FLOAT32,,,,hold_register,10004,
REG_DATA_AXIS_Y_POS,FLOAT32,,,,hold_register,10006,
REG_DATA_AXIS_Z_POS,FLOAT32,,,,hold_register,10008,
REG_DATA_POLE_WEIGHT,FLOAT32,,,,hold_register,10010,data_pole_weight
REG_DATA_ASSEMBLY_PER_TIME,FLOAT32,,,,hold_register,10012,data_assembly_time
REG_DATA_ASSEMBLY_PRESSURE,INT16,,,,hold_register,10014,data_assembly_pressure
REG_DATA_ELECTROLYTE_VOLUME,INT16,,,,hold_register,10016,data_electrolyte_volume
REG_DATA_COIN_NUM,INT16,,,,hold_register,10018,data_coin_num
REG_DATA_ELECTROLYTE_CODE,STRING,,,,hold_register,10020,data_electrolyte_code()
REG_DATA_COIN_CELL_CODE,STRING,,,,hold_register,10030,data_coin_cell_code()
REG_DATA_STACK_VISON_CODE,STRING,,,,hold_register,12004,data_stack_vision_code()
REG_DATA_GLOVE_BOX_PRESSURE,FLOAT32,,,,hold_register,10050,data_glove_box_pressure
REG_DATA_GLOVE_BOX_WATER_CONTENT,FLOAT32,,,,hold_register,10052,data_glove_box_water_content
REG_DATA_GLOVE_BOX_O2_CONTENT,FLOAT32,,,,hold_register,10054,data_glove_box_o2_content
UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM,BOOL,,,,coil,8720,
UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM,BOOL,,,,coil,8520,
REG_MSG_ELECTROLYTE_NUM_USED,INT16,,,,hold_register,496,
REG_DATA_ELECTROLYTE_USE_NUM,INT16,,,,hold_register,10000,
UNILAB_SEND_FINISHED_CMD,BOOL,,,,coil,8730,
UNILAB_RECE_FINISHED_CMD,BOOL,,,,coil,8530,
REG_DATA_ASSEMBLY_TYPE,INT16,,,,hold_register,10018,ASSEMBLY_TYPE7or8
COIL_ALUMINUM_FOIL,BOOL,,,,coil,8340,
1 Name DataType InitValue Comment Attribute DeviceType Address
2 COIL_SYS_START_CMD BOOL coil 8010
3 COIL_SYS_STOP_CMD BOOL coil 8020
4 COIL_SYS_RESET_CMD BOOL coil 8030
5 COIL_SYS_HAND_CMD BOOL coil 8040
6 COIL_SYS_AUTO_CMD BOOL coil 8050
7 COIL_SYS_INIT_CMD BOOL coil 8060
8 COIL_UNILAB_SEND_MSG_SUCC_CMD BOOL coil 8700
9 COIL_UNILAB_REC_MSG_SUCC_CMD BOOL coil 8710 unilab_rec_msg_succ_cmd
10 COIL_SYS_START_STATUS BOOL coil 8210
11 COIL_SYS_STOP_STATUS BOOL coil 8220
12 COIL_SYS_RESET_STATUS BOOL coil 8230
13 COIL_SYS_HAND_STATUS BOOL coil 8240
14 COIL_SYS_AUTO_STATUS BOOL coil 8250
15 COIL_SYS_INIT_STATUS BOOL coil 8260
16 COIL_REQUEST_REC_MSG_STATUS BOOL coil 8500
17 COIL_REQUEST_SEND_MSG_STATUS BOOL coil 8510 request_send_msg_status
18 REG_MSG_ELECTROLYTE_USE_NUM INT16 hold_register 11000
19 REG_MSG_ELECTROLYTE_NUM INT16 hold_register 11002 unilab_send_msg_electrolyte_num
20 REG_MSG_ELECTROLYTE_VOLUME INT16 hold_register 11004 unilab_send_msg_electrolyte_vol
21 REG_MSG_ASSEMBLY_TYPE INT16 hold_register 11006 unilab_send_msg_assembly_type
22 REG_MSG_ASSEMBLY_PRESSURE INT16 hold_register 11008 unilab_send_msg_assembly_pressure
23 REG_DATA_ASSEMBLY_COIN_CELL_NUM INT16 hold_register 10000 data_assembly_coin_cell_num
24 REG_DATA_OPEN_CIRCUIT_VOLTAGE FLOAT32 hold_register 10002 data_open_circuit_voltage
25 REG_DATA_AXIS_X_POS FLOAT32 hold_register 10004
26 REG_DATA_AXIS_Y_POS FLOAT32 hold_register 10006
27 REG_DATA_AXIS_Z_POS FLOAT32 hold_register 10008
28 REG_DATA_POLE_WEIGHT FLOAT32 hold_register 10010 data_pole_weight
29 REG_DATA_ASSEMBLY_PER_TIME FLOAT32 hold_register 10012 data_assembly_time
30 REG_DATA_ASSEMBLY_PRESSURE INT16 hold_register 10014 data_assembly_pressure
31 REG_DATA_ELECTROLYTE_VOLUME INT16 hold_register 10016 data_electrolyte_volume
32 REG_DATA_COIN_NUM INT16 hold_register 10018 data_coin_num
33 REG_DATA_ELECTROLYTE_CODE STRING hold_register 10020 data_electrolyte_code()
34 REG_DATA_COIN_CELL_CODE STRING hold_register 10030 data_coin_cell_code()
35 REG_DATA_STACK_VISON_CODE STRING hold_register 12004 data_stack_vision_code()
36 REG_DATA_GLOVE_BOX_PRESSURE FLOAT32 hold_register 10050 data_glove_box_pressure
37 REG_DATA_GLOVE_BOX_WATER_CONTENT FLOAT32 hold_register 10052 data_glove_box_water_content
38 REG_DATA_GLOVE_BOX_O2_CONTENT FLOAT32 hold_register 10054 data_glove_box_o2_content
39 UNILAB_SEND_ELECTROLYTE_BOTTLE_NUM BOOL coil 8720
40 UNILAB_RECE_ELECTROLYTE_BOTTLE_NUM BOOL coil 8520
41 REG_MSG_ELECTROLYTE_NUM_USED INT16 hold_register 496
42 REG_DATA_ELECTROLYTE_USE_NUM INT16 hold_register 10000
43 UNILAB_SEND_FINISHED_CMD BOOL coil 8730
44 UNILAB_RECE_FINISHED_CMD BOOL coil 8530
45 REG_DATA_ASSEMBLY_TYPE INT16 hold_register 10018 ASSEMBLY_TYPE7or8
46 COIL_ALUMINUM_FOIL BOOL coil 8340

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,691 @@
{
"nodes": [
{
"id": "BatteryStation",
"name": "扣电工作站",
"children": [
"coin_cell_deck"
],
"parent": null,
"type": "device",
"class": "bettery_station_registry",
"position": {
"x": 600,
"y": 400,
"z": 0
},
"config": {
"debug_mode": false,
"_comment": "protocol_type接外部工站固定写法字段一般为空station_resource写法也固定",
"protocol_type": [],
"station_resource": {
"data": {
"_resource_child_name": "coin_cell_deck",
"_resource_type": "unilabos.devices.workstation.coin_cell_assembly.button_battery_station:CoincellDeck"
}
},
"address": "192.168.1.20",
"port": 502
},
"data": {}
},
{
"id": "coin_cell_deck",
"name": "coin_cell_deck",
"sample_id": null,
"children": [
"\u7535\u6c60\u6599\u76d8"
],
"parent": null,
"type": "container",
"class": "",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"config": {
"type": "CoincellDeck",
"size_x": 1000,
"size_y": 1000,
"size_z": 900,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "coin_cell_deck",
"barcode": null
},
"data": {}
},
{
"id": "\u7535\u6c60\u6599\u76d8",
"name": "\u7535\u6c60\u6599\u76d8",
"sample_id": null,
"children": [
"\u7535\u6c60\u6599\u76d8_materialhole_0_0",
"\u7535\u6c60\u6599\u76d8_materialhole_0_1",
"\u7535\u6c60\u6599\u76d8_materialhole_0_2",
"\u7535\u6c60\u6599\u76d8_materialhole_0_3",
"\u7535\u6c60\u6599\u76d8_materialhole_1_0",
"\u7535\u6c60\u6599\u76d8_materialhole_1_1",
"\u7535\u6c60\u6599\u76d8_materialhole_1_2",
"\u7535\u6c60\u6599\u76d8_materialhole_1_3",
"\u7535\u6c60\u6599\u76d8_materialhole_2_0",
"\u7535\u6c60\u6599\u76d8_materialhole_2_1",
"\u7535\u6c60\u6599\u76d8_materialhole_2_2",
"\u7535\u6c60\u6599\u76d8_materialhole_2_3",
"\u7535\u6c60\u6599\u76d8_materialhole_3_0",
"\u7535\u6c60\u6599\u76d8_materialhole_3_1",
"\u7535\u6c60\u6599\u76d8_materialhole_3_2",
"\u7535\u6c60\u6599\u76d8_materialhole_3_3"
],
"parent": "coin_cell_deck",
"type": "container",
"class": "",
"position": {
"x": 100,
"y": 100,
"z": 0
},
"config": {
"type": "MaterialPlate",
"size_x": 120.8,
"size_y": 160.5,
"size_z": 10.0,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_plate",
"model": null,
"barcode": null,
"ordering": {
"A1": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
"B1": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
"C1": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
"D1": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
"A2": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
"B2": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
"C2": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
"D2": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
"A3": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
"B3": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
"C3": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
"D3": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
"A4": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
"B4": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
"C4": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
"D4": "\u7535\u6c60\u6599\u76d8_materialhole_3_3"
}
},
"data": {}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_0",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 12.4,
"y": 104.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_1",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 12.4,
"y": 80.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_2",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 12.4,
"y": 56.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_0_3",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 12.4,
"y": 32.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_0",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 36.4,
"y": 104.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_1",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 36.4,
"y": 80.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_2",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 36.4,
"y": 56.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_1_3",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 36.4,
"y": 32.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_0",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 60.4,
"y": 104.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_1",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 60.4,
"y": 80.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_2",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 60.4,
"y": 56.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_2_3",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 60.4,
"y": 32.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_0",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 84.4,
"y": 104.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_1",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 84.4,
"y": 80.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_2",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 84.4,
"y": 56.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
},
{
"id": "\u7535\u6c60\u6599\u76d8_materialhole_3_3",
"name": "\u7535\u6c60\u6599\u76d8_materialhole_3_3",
"sample_id": null,
"children": [],
"parent": "\u7535\u6c60\u6599\u76d8",
"type": "container",
"class": "",
"position": {
"x": 84.4,
"y": 32.25,
"z": 10.0
},
"config": {
"type": "MaterialHole",
"size_x": 16,
"size_y": 16,
"size_z": 16,
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"type": "Rotation"
},
"category": "material_hole",
"model": null,
"barcode": null
},
"data": {
"diameter": 20,
"depth": 10,
"max_sheets": 1,
"info": null
}
}
],
"links": []
}

View File

@@ -16,9 +16,9 @@
},
"config": {
"debug_mode": false,
"_comment": "protocol_type接外部工站固定写法字段一般为空deck写法也固定",
"_comment": "protocol_type接外部工站固定写法字段一般为空station_resource写法也固定",
"protocol_type": [],
"deck": {
"station_resource": {
"data": {
"_resource_child_name": "coin_cell_deck",
"_resource_type": "unilabos.devices.workstation.coin_cell_assembly.button_battery_station:CoincellDeck"

File diff suppressed because it is too large Load Diff