mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-07 23:45:10 +00:00
Compare commits
2 Commits
2901d72b4b
...
42f7010134
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42f7010134 | ||
|
|
190b2d2518 |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#coding=utf-8
|
||||
|
||||
ENV = 'pro'#'test'
|
||||
class MQConfig:
|
||||
"""MQTT 配置类"""
|
||||
lab_id: str = '9F05593C'
|
||||
instance_id: str = 'mqtt-cn-dsr48m6jy02'
|
||||
|
||||
group_id: str = 'GID_prod'
|
||||
broker_url: str = 'mqtt-cn-dsr48m6jy02.mqtt.aliyuncs.com'
|
||||
port: int = 8883
|
||||
ca_content: str = '''-----BEGIN CERTIFICATE-----
|
||||
MIID3jCCAsagAwIBAgIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDQYJKoZIhvcNAQEL
|
||||
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA1MDYxNTE0Mjda
|
||||
Fw0zNTA1MDQxNTE0MjdaMEsxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||
A1UEBwwCQkoxEDAOBgNVBAoMB2RwLnRlY2gxEDAOBgNVBAsMB3VuaS1sYWIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnTBywX+6DJ2n+prNKvylBBJF6
|
||||
NHQrCt2cztZfswHsW4QhAbDddp4PRzNVzKtIfHX5ZrXGbxNT1/TqQYXKiFjKbfPC
|
||||
VHTrS6+95LP3MxNTlBWHP6d2uI45KwrGgQ7D1uPDG1wZsfuJxvOkfAIxZRCDUMJr
|
||||
erYYK/p2/GVMAO5YKE7wENUMN+iLfVQRqQJRgte9z0B35DxUeOUblJDun0Dpl/6L
|
||||
0km/YRrjUKA/5+u/h+Ko9+36L1DAi+9rm3eyp+BQHBy5aiVhAG6uAJeMjbZMxwxz
|
||||
ixg9cWNxP1BW+aQQzixbEQ+YlO9+w/soJkLstiK7jF8uIg2QvmNUKNlqab0pAgMB
|
||||
AAGjgbkwgbYwHQYDVR0OBBYEFAqg0r7f6ngWODyVxVWHWM06b8wDMIGGBgNVHSME
|
||||
fzB9gBQKoNK+3+p4Fjg8lcVVh1jNOm/MA6FPpE0wSzELMAkGA1UEBhMCQ04xCzAJ
|
||||
BgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4GA1UECgwHZHAudGVjaDEQMA4GA1UE
|
||||
CwwHdW5pLWxhYoIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDAYDVR0TBAUwAwEB/zAN
|
||||
BgkqhkiG9w0BAQsFAAOCAQEAMylGHHhRCI8JLTizxqk2HaOFkF/WfnYC3XyNx3bK
|
||||
9KqwVcvaqES+C058lits5nCV1qjjSnKt6xU11S8C6E28Kazh+wMqnSw63fz4UOY5
|
||||
4cekPCPy8XcWlOY6UW2N27GR0c9JDo9ovruOn1Y4KjATpAQI4W2tPAQ2gCVSNpu1
|
||||
bw5uw35yJSRzdQIHlsVbslvj2wcugK3GZHmmxJK+q9ww7G6xXtE2Y0+vl6AZRj+I
|
||||
lcTy5TNNDZiiboIlAt+K3m4hxzSgGPbmFPJX3Lw3i+YMR/0PrWfXqxZgicO/V6/d
|
||||
SgGBqq/tH1caiaEjCFudSZcOiZvHIlb09O4qL7mCtWEiEQ==
|
||||
-----END CERTIFICATE-----
|
||||
'''
|
||||
cert_content: str = '''-----BEGIN CERTIFICATE-----
|
||||
MIIDlTCCAn2gAwIBAgIUa/ce6dpJ8K7XNvT0LknVmLgfJMIwDQYJKoZIhvcNAQEL
|
||||
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA4MTMwNDQ0MDVa
|
||||
Fw0yNjEyMjYwNDQ0MDVaMHoxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||
A1UEBwwCQkoxDDAKBgNVBAoMA0RQVDENMAsGA1UECwwETVFUVDEhMB8GCSqGSIb3
|
||||
DQEJARYSaHVhaGFpbWluZ0BkcC50ZWNoMREwDwYDVQQDDAg0NzJBMjZBQzCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPc4NHXcwaFX3jSN6DnDYoY7ON6c
|
||||
AeVIlcQp3CMHnulh4t3I3Fnsyelpc809s7l5vEpAjMIuZ40DJKZQmV9ckmeylMiY
|
||||
bAk851+i8YcRQPeYYY7Ggt0sfkY3TWIIqptZtlIhXtkTCWw6xpHAPkYxqNTiUN/0
|
||||
vwQWwiBS7WqD8NVjNhhHootYLsMjnQYc162L8nUwzG2pjB3UYqOldC3FkHXvBkG2
|
||||
Oeex8VM8Urblv0huCmoFRyuMmNol0QWqp+6nwAgdvf89Z38NJByPI9VHaBB/VV1F
|
||||
HiAZe3H8Ph7wzgUSXBuVHJ4BaeJbg4+ax6BccpaQn26jgpJGUEj+YR+NwdMCAwEA
|
||||
AaNCMEAwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCAvQwIAYDVR0lAQH/BBYw
|
||||
FAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQAZaF8puP0/
|
||||
OcRM7Gcd4LrF8H/WG0Q7WM0T9BWGvee6A+Fcd4ajBC0S0tIfdsfYat0+g4U57jrr
|
||||
vaQeZGFKc4YKVui8vSuth82fcsFk5fpyhz4JJRggzeoby+0gNx9eYDJwLIvbVy4Y
|
||||
2LKGq+rsO07QF54jtwB4WpDNFnEIadXyjPBsMy/0Ssbetp827WYZygXYyAcUlCfN
|
||||
Wns7K0phfZJwIMQgPs3d4mGwCC+xaRIB3GGjUGFXV1sFItjkTUHCvm+phw/MTpRp
|
||||
pauplyDcWYux7z1dKhbuHElzCEqxZNwyI0nGJlRFP13Oo+jnuDO7gQh2lyz/AFyX
|
||||
KyTA3xFZduHO
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID3jCCAsagAwIBAgIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDQYJKoZIhvcNAQEL
|
||||
BQAwSzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4G
|
||||
A1UECgwHZHAudGVjaDEQMA4GA1UECwwHdW5pLWxhYjAeFw0yNTA1MDYxNTE0Mjda
|
||||
Fw0zNTA1MDQxNTE0MjdaMEsxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJCSjELMAkG
|
||||
A1UEBwwCQkoxEDAOBgNVBAoMB2RwLnRlY2gxEDAOBgNVBAsMB3VuaS1sYWIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnTBywX+6DJ2n+prNKvylBBJF6
|
||||
NHQrCt2cztZfswHsW4QhAbDddp4PRzNVzKtIfHX5ZrXGbxNT1/TqQYXKiFjKbfPC
|
||||
VHTrS6+95LP3MxNTlBWHP6d2uI45KwrGgQ7D1uPDG1wZsfuJxvOkfAIxZRCDUMJr
|
||||
erYYK/p2/GVMAO5YKE7wENUMN+iLfVQRqQJRgte9z0B35DxUeOUblJDun0Dpl/6L
|
||||
0km/YRrjUKA/5+u/h+Ko9+36L1DAi+9rm3eyp+BQHBy5aiVhAG6uAJeMjbZMxwxz
|
||||
ixg9cWNxP1BW+aQQzixbEQ+YlO9+w/soJkLstiK7jF8uIg2QvmNUKNlqab0pAgMB
|
||||
AAGjgbkwgbYwHQYDVR0OBBYEFAqg0r7f6ngWODyVxVWHWM06b8wDMIGGBgNVHSME
|
||||
fzB9gBQKoNK+3+p4Fjg8lcVVh1jNOm/MA6FPpE0wSzELMAkGA1UEBhMCQ04xCzAJ
|
||||
BgNVBAgMAkJKMQswCQYDVQQHDAJCSjEQMA4GA1UECgwHZHAudGVjaDEQMA4GA1UE
|
||||
CwwHdW5pLWxhYoIUDyIgmg4qZtMPa8r2Vvn1b1fgJ+YwDAYDVR0TBAUwAwEB/zAN
|
||||
BgkqhkiG9w0BAQsFAAOCAQEAMylGHHhRCI8JLTizxqk2HaOFkF/WfnYC3XyNx3bK
|
||||
9KqwVcvaqES+C058lits5nCV1qjjSnKt6xU11S8C6E28Kazh+wMqnSw63fz4UOY5
|
||||
4cekPCPy8XcWlOY6UW2N27GR0c9JDo9ovruOn1Y4KjATpAQI4W2tPAQ2gCVSNpu1
|
||||
bw5uw35yJSRzdQIHlsVbslvj2wcugK3GZHmmxJK+q9ww7G6xXtE2Y0+vl6AZRj+I
|
||||
lcTy5TNNDZiiboIlAt+K3m4hxzSgGPbmFPJX3Lw3i+YMR/0PrWfXqxZgicO/V6/d
|
||||
SgGBqq/tH1caiaEjCFudSZcOiZvHIlb09O4qL7mCtWEiEQ==
|
||||
-----END CERTIFICATE-----
|
||||
'''
|
||||
key_content: str = '''-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA9zg0ddzBoVfeNI3oOcNihjs43pwB5UiVxCncIwee6WHi3cjc
|
||||
WezJ6WlzzT2zuXm8SkCMwi5njQMkplCZX1ySZ7KUyJhsCTznX6LxhxFA95hhjsaC
|
||||
3Sx+RjdNYgiqm1m2UiFe2RMJbDrGkcA+RjGo1OJQ3/S/BBbCIFLtaoPw1WM2GEei
|
||||
i1guwyOdBhzXrYvydTDMbamMHdRio6V0LcWQde8GQbY557HxUzxStuW/SG4KagVH
|
||||
K4yY2iXRBaqn7qfACB29/z1nfw0kHI8j1UdoEH9VXUUeIBl7cfw+HvDOBRJcG5Uc
|
||||
ngFp4luDj5rHoFxylpCfbqOCkkZQSP5hH43B0wIDAQABAoIBAAPzz0ZUcqmR1Eva
|
||||
5PH98gQzp2wB9snLY86HY3Z/JVAPf5Ht9sbAUWHhT8PVoWpIasSmFbuJxz6DRk3S
|
||||
M8VVVipxxgcTWqo/JOD4HZiCNfcRru6+5dHxZ4p2B/n4EWfoy+KyEZkgd5jQFONj
|
||||
jIX+rDR3qZzFqoBRhQSHLuD+i66eZ7l1LOqsnk51r3nTCnGmdyV8fll56MMB5D6+
|
||||
8LN2rwbmSYX/UIBBqHUthgEt2onFNaetTLgSa3RSNGZ3xEZt4N32vw1SARxItuso
|
||||
npAAY77POMUwWe3666fETI+yr/gJuppvTF4sQUXy7I4iz7I18n2SYivHabdgnk6H
|
||||
7y1TcGECgYEA/NbBLFz1YPOQiT6TsuitIlfWcFWXYI4yHh/Mwwm/heHV683HrUti
|
||||
RSHWbFxggW70BYJbGAQprEe9UIRVdP9YNi3aPeN5WNfnTFHlN2HRiKenlETM1tw9
|
||||
yaSWjNbAyc2ka+l1EblMJy92xoCkErS8riEPW83o+3+LqJwnjsJ8tVECgYEA+k93
|
||||
AyNpXuOZldAoqSHF3wHgzgd2jhfVdQcNlz9sLfT8TAdoR01mdBtdytcYAH+FHplW
|
||||
wlkCfpT1RPf3fEd0Asy727pJnL9v/QfY/BB+vfgWKUQg9CWNIevwItCaTNOSekis
|
||||
lKl5dxNGOyouU7rPbTj9BC26OHA50Z3vLMKmi+MCgYEAy0Sb6N6TJ26pNK1qcNs+
|
||||
1e1oKMem+6lWAYHvTJ35q9jz8q9taJTCXHHnwRZDP8vDwuoZ8iTmm+rQ+HprebQP
|
||||
Zv9WBYtrc1GgUmtErFGn8wVWZI0rYVGPGx2HK5M7SwJYvajixW0DHD28b7ncLm2/
|
||||
gv5xKo1QUWEpFlT0OIGDYQECgYEA8WRlH6+s1Iel++ZM8B7T1ibXh5mG6a1ue3eb
|
||||
0bqmNwPFtASIugqYvWwO3ajlSsWvuTyjgLWaRDye9C42i7HU3UZX/KUAjJvKAjjp
|
||||
Nt0pfUadCJrdNNZp7sa8RLbrtx9qaWdgl9WAgCckWbZqCvFjTK/iwX7f0cHY4J/w
|
||||
ojftqYUCgYARM6YaEJuBJEBmZV1I0rweiguqWssZz2j1awSlsfYxckwnci4VtSMI
|
||||
D/sp0Wp0yn2N4cgqp49BFD0rCQCTsASVICEf9HWdMQXsUhzWsz4SjVEhjWWC1VAk
|
||||
sEL+BOcbsHy3qMbV2uKBHrhuZShDdy5KtCm9TB+7zTWyDVHwE24nig==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
'''
|
||||
|
||||
# HTTP配置
|
||||
class HTTPConfig:
|
||||
remote_addr = "https://uni-lab.test.bohrium.com/api/v1"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -656,16 +656,25 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
# self.success = True
|
||||
# return self.success
|
||||
|
||||
def func_pack_send_msg_cmd(self, elec_use_num) -> bool:
|
||||
def func_pack_send_msg_cmd(self, elec_use_num, elec_vol, assembly_type, assembly_pressure) -> bool:
|
||||
"""UNILAB写参数"""
|
||||
while (self.request_rec_msg_status) == False:
|
||||
print("wait for request_rec_msg_status to True")
|
||||
time.sleep(1)
|
||||
self.success = False
|
||||
#self._unilab_send_msg_electrolyte_num(elec_num)
|
||||
time.sleep(1)
|
||||
#设置平行样数目
|
||||
self._unilab_send_msg_electrolyte_use_num(elec_use_num)
|
||||
time.sleep(1)
|
||||
#发送电解液加注量
|
||||
self._unilab_send_msg_electrolyte_vol(elec_vol)
|
||||
time.sleep(1)
|
||||
#发送电解液组装类型
|
||||
self._unilab_send_msg_assembly_type(assembly_type)
|
||||
time.sleep(1)
|
||||
#发送电池压制力
|
||||
self._unilab_send_msg_assembly_pressure(assembly_pressure)
|
||||
time.sleep(1)
|
||||
self._unilab_send_msg_succ_cmd(True)
|
||||
time.sleep(1)
|
||||
while (self.request_rec_msg_status) == True:
|
||||
@@ -775,8 +784,8 @@ 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)
|
||||
def func_allpack_cmd(self, elec_num, elec_use_num, elec_vol:int=50, assembly_type:int=7, assembly_pressure:int=4200, file_path: str="D:\\coin_cell_data") -> bool:
|
||||
elec_num, elec_use_num, elec_vol, assembly_type, assembly_pressure = int(elec_num), int(elec_use_num), int(elec_vol), int(assembly_type), int(assembly_pressure)
|
||||
summary_csv_file = os.path.join(file_path, "duandian.csv")
|
||||
# 如果断点文件存在,先读取之前的进度
|
||||
if os.path.exists(summary_csv_file):
|
||||
@@ -826,7 +835,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
print(f"开始第{last_i+i+1}瓶电解液的组装")
|
||||
#第一个循环从上次断点继续,后续循环从0开始
|
||||
j_start = last_j if i == last_i else 0
|
||||
self.func_pack_send_msg_cmd(elec_use_num-j_start)
|
||||
self.func_pack_send_msg_cmd(elec_use_num-j_start, elec_vol, assembly_type, assembly_pressure)
|
||||
|
||||
for j in range(j_start, elec_use_num):
|
||||
print(f"开始第{last_i+i+1}瓶电解液的第{j+j_start+1}个电池组装")
|
||||
@@ -43,4 +43,21 @@ 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,
|
||||
COIL_ALUMINUM_FOIL,BOOL,,使用铝箔垫,,coil,8340,
|
||||
REG_MSG_NE_PLATE_MATRIX,INT16,,负极片矩阵点位,,hold_register,440,
|
||||
REG_MSG_SEPARATOR_PLATE_MATRIX,INT16,,隔膜矩阵点位,,hold_register,450,
|
||||
REG_MSG_TIP_BOX_MATRIX,INT16,,移液枪头矩阵点位,,hold_register,480,
|
||||
REG_MSG_NE_PLATE_NUM,INT16,,负极片盘数,,hold_register,443,
|
||||
REG_MSG_SEPARATOR_PLATE_NUM,INT16,,隔膜盘数,,hold_register,453,
|
||||
REG_MSG_PRESS_MODE,BOOL,,压制模式(false:压力检测模式,True:距离模式),,coil,8360,电池压制模式
|
||||
,,,,,,,
|
||||
,BOOL,,视觉对位(false:使用,true:忽略),,coil,8300,视觉对位
|
||||
,BOOL,,复检(false:使用,true:忽略),,coil,8310,视觉复检
|
||||
,BOOL,,手套箱_左仓(false:使用,true:忽略),,coil,8320,手套箱左仓
|
||||
,BOOL,,手套箱_右仓(false:使用,true:忽略),,coil,8420,手套箱右仓
|
||||
,BOOL,,真空检知(false:使用,true:忽略),,coil,8350,真空检知
|
||||
,BOOL,,电解液添加模式(false:单次滴液,true:二次滴液),,coil,8370,滴液模式
|
||||
,BOOL,,正极片称重(false:使用,true:忽略),,coil,8380,正极片称重
|
||||
,BOOL,,正负极片组装方式(false:正装,true:倒装),,coil,8390,正负极反装
|
||||
,BOOL,,压制清洁(false:使用,true:忽略),,coil,8400,压制清洁
|
||||
,BOOL,,物料盘摆盘方式(false:水平摆盘,true:堆叠摆盘),,coil,8410,负极片摆盘方式
|
||||
|
@@ -1,44 +0,0 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
import json
|
||||
import re
|
||||
from pymodbus.client import ModbusTcpClient
|
||||
from unilabos.device_comms.modbus_plc.modbus import WorderOrder, Coil, DiscreteInputs, HoldRegister, InputRegister, DataType
|
||||
from pymodbus.constants import Endian
|
||||
import time
|
||||
import threading
|
||||
import csv
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Callable
|
||||
from unilabos.device_comms.modbus_plc.client import TCPClient, ModbusNode, PLCWorkflow, ModbusWorkflow, WorkflowAction, BaseClient
|
||||
from unilabos.device_comms.modbus_plc.modbus import DeviceType, Base as ModbusNodeBase, DataType, WorderOrder
|
||||
|
||||
class Coin_Cell_Assembly:
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
coin_cell_assmbly = Coin_Cell_Assembly(address="192.168.1.20", port="502")
|
||||
|
||||
#params = {
|
||||
# "elec_num": 32
|
||||
#}
|
||||
#str_data = json.dumps(params, ensure_ascii=False)
|
||||
#print('param:', coin_cell_assmbly.func_pack_device_write_batch_elec_param(params))
|
||||
#time.sleep(1)
|
||||
|
||||
print(coin_cell_assmbly.func_pack_device_write_per_elec_param(
|
||||
elec_use_num=4,
|
||||
elec_num=5,
|
||||
elec_vol=55,
|
||||
assembly_type=25,
|
||||
assembly_pressure=550))
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
'''
|
||||
print('start:', coin_cell_assmbly.func_pack_device_start())
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print('start:', coin_cell_assmbly.func_pack_device_start())
|
||||
time.sleep(1)
|
||||
|
||||
print('stop:', coin_cell_assmbly.func_pack_device_stop())
|
||||
time.sleep(1)
|
||||
|
||||
while True:
|
||||
# cmd coil
|
||||
print('start cmd:', coin_cell_assmbly.sys_start_cmd(True))
|
||||
time.sleep(1)
|
||||
print('stop cmd:', coin_cell_assmbly.sys_stop_cmd(False))
|
||||
time.sleep(1)
|
||||
print('reset cmd:', coin_cell_assmbly.sys_reset_cmd(True))
|
||||
time.sleep(1)
|
||||
print('hand cmd:', coin_cell_assmbly.sys_hand_cmd(False))
|
||||
time.sleep(1)
|
||||
print('auto cmd:', coin_cell_assmbly.sys_auto_cmd(True))
|
||||
time.sleep(1)
|
||||
print('init cmd:', coin_cell_assmbly.sys_init_cmd(False))
|
||||
time.sleep(1)
|
||||
print('send msg succ cmd:', coin_cell_assmbly.unilab_send_msg_succ_cmd(False))
|
||||
time.sleep(1)
|
||||
print('rec msg succ cmd:', coin_cell_assmbly.unilab_rec_msg_succ_cmd(True))
|
||||
time.sleep(1)
|
||||
|
||||
# cmd reg
|
||||
print('elec use num msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_use_num(8))
|
||||
time.sleep(1)
|
||||
print('elec num msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_num(4))
|
||||
time.sleep(1)
|
||||
print('elec vol msg:', coin_cell_assmbly.unilab_send_msg_electrolyte_vol(3.3))
|
||||
time.sleep(1)
|
||||
print('assembly type msg:', coin_cell_assmbly.unilab_send_msg_assembly_type(1))
|
||||
time.sleep(1)
|
||||
print('assembly pressure msg:', coin_cell_assmbly.unilab_send_msg_assembly_pressure(1))
|
||||
time.sleep(1)
|
||||
|
||||
# status coil
|
||||
print('start status:',coin_cell_assmbly.sys_start_status)
|
||||
time.sleep(1)
|
||||
print('stop status:',coin_cell_assmbly.sys_stop_status)
|
||||
time.sleep(1)
|
||||
print('reset status:',coin_cell_assmbly.sys_reset_status)
|
||||
time.sleep(1)
|
||||
print('hand status:',coin_cell_assmbly.sys_hand_status)
|
||||
time.sleep(1)
|
||||
print('auto status:', coin_cell_assmbly.sys_auto_status)
|
||||
time.sleep(1)
|
||||
print('init ok:', coin_cell_assmbly.sys_init_status)
|
||||
time.sleep(1)
|
||||
print('request rec msg:', coin_cell_assmbly.request_rec_msg_status)
|
||||
time.sleep(1)
|
||||
print('request send msg:', coin_cell_assmbly.request_send_msg_status)
|
||||
time.sleep(1)
|
||||
|
||||
# status reg
|
||||
print('assembly coin cell num:', coin_cell_assmbly.data_assembly_coin_cell_num)
|
||||
time.sleep(1)
|
||||
print('assembly coin assembly per time:', coin_cell_assmbly.data_assembly_time)
|
||||
time.sleep(1)
|
||||
print('open circuit vol:', coin_cell_assmbly.data_open_circuit_voltage)
|
||||
time.sleep(1)
|
||||
print('axis x pos:', coin_cell_assmbly.data_axis_x_pos)
|
||||
time.sleep(1)
|
||||
print('axis y pos:', coin_cell_assmbly.data_axis_y_pos)
|
||||
time.sleep(1)
|
||||
print('axis z pos:', coin_cell_assmbly.data_axis_z_pos)
|
||||
time.sleep(1)
|
||||
print('pole weight:', coin_cell_assmbly.data_pole_weight)
|
||||
time.sleep(1)
|
||||
print('assembly pressure:', coin_cell_assmbly.data_assembly_coin_cell_num)
|
||||
time.sleep(1)
|
||||
print('assembly electrolyte vol:', coin_cell_assmbly.data_electrolyte_volume)
|
||||
time.sleep(1)
|
||||
print('assembly coin num:', coin_cell_assmbly.data_coin_num)
|
||||
time.sleep(1)
|
||||
print('coin cell code:', coin_cell_assmbly.data_coin_cell_code)
|
||||
time.sleep(1)
|
||||
print('elec code:', coin_cell_assmbly.data_electrolyte_code)
|
||||
time.sleep(1)
|
||||
print('glove box pressure:', coin_cell_assmbly.data_glove_box_pressure)
|
||||
time.sleep(1)
|
||||
print('glove box o2:', coin_cell_assmbly.data_glove_box_o2_content)
|
||||
time.sleep(1)
|
||||
print('glove box water:', coin_cell_assmbly.data_glove_box_water_content)
|
||||
time.sleep(1)
|
||||
|
||||
'''
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -1,750 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "80bc9500",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from __future__ import annotations\n",
|
||||
"\n",
|
||||
"from collections import OrderedDict\n",
|
||||
"from typing import Any, Dict, List, Optional, TypedDict, Union, cast\n",
|
||||
"\n",
|
||||
"from pylabrobot.resources.coordinate import Coordinate\n",
|
||||
"from pylabrobot.resources.container import Container\n",
|
||||
"from pylabrobot.resources.deck import Deck\n",
|
||||
"from pylabrobot.resources.itemized_resource import ItemizedResource\n",
|
||||
"from pylabrobot.resources.resource import Resource\n",
|
||||
"from pylabrobot.resources.resource_stack import ResourceStack\n",
|
||||
"from pylabrobot.resources.tip_rack import TipRack, TipSpot\n",
|
||||
"from pylabrobot.resources.trash import Trash\n",
|
||||
"from pylabrobot.resources.utils import create_ordered_items_2d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "498a9159",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"物料类型构建"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"id": "f4a27241",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"class ElectrodeSheetState(TypedDict):\n",
|
||||
" diameter: float # 直径 (mm)\n",
|
||||
" thickness: float # 厚度 (mm)\n",
|
||||
" mass: float # 质量 (g)\n",
|
||||
" material_type: str # 材料类型(正极、负极、隔膜、弹片、垫片、铝箔等)\n",
|
||||
" info: Optional[str] # 附加信息\n",
|
||||
"\n",
|
||||
"class ElectrodeSheet(Resource):\n",
|
||||
" \"\"\"极片类 - 包含正负极片、隔膜、弹片、垫片、铝箔等所有片状材料\"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" name: str = \"极片\",\n",
|
||||
" size_x=10,\n",
|
||||
" size_y=10,\n",
|
||||
" size_z=10,\n",
|
||||
" category: str = \"electrode_sheet\",\n",
|
||||
" model: Optional[str] = None,\n",
|
||||
" ):\n",
|
||||
" \"\"\"初始化极片\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" name: 极片名称\n",
|
||||
" category: 类别\n",
|
||||
" model: 型号\n",
|
||||
" \"\"\"\n",
|
||||
" super().__init__(\n",
|
||||
" name=name,\n",
|
||||
" size_x=size_x,\n",
|
||||
" size_y=size_y,\n",
|
||||
" size_z=size_z,\n",
|
||||
" category=category,\n",
|
||||
" model=model,\n",
|
||||
" )\n",
|
||||
" self._unilabos_state: ElectrodeSheetState = ElectrodeSheetState(\n",
|
||||
" diameter=14,\n",
|
||||
" thickness=0.1,\n",
|
||||
" mass=0.5,\n",
|
||||
" material_type=\"copper\",\n",
|
||||
" info=None\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # TODO: 这个还要不要?给self._unilabos_state赋值的?\n",
|
||||
" def load_state(self, state: Dict[str, Any]) -> None:\n",
|
||||
" \"\"\"格式不变\"\"\"\n",
|
||||
" super().load_state(state)\n",
|
||||
" self._unilabos_state = state\n",
|
||||
" #序列化\n",
|
||||
" def serialize_state(self) -> Dict[str, Dict[str, Any]]:\n",
|
||||
" \"\"\"格式不变\"\"\"\n",
|
||||
" data = super().serialize_state()\n",
|
||||
" data.update(self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)\n",
|
||||
" return data\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"id": "830f052e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# TODO: 这个应该只能放一个极片\n",
|
||||
"class MaterialHoleState(TypedDict):\n",
|
||||
" diameter: int\n",
|
||||
" depth: int\n",
|
||||
" max_sheets: int\n",
|
||||
" info: Optional[str] # 附加信息\n",
|
||||
"\n",
|
||||
"class MaterialHole(Resource):\n",
|
||||
" \"\"\"料板洞位类\"\"\"\n",
|
||||
" children: List[ElectrodeSheet] = []\n",
|
||||
"\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" name: str,\n",
|
||||
" size_x: float,\n",
|
||||
" size_y: float,\n",
|
||||
" size_z: float,\n",
|
||||
" category: str = \"material_hole\",\n",
|
||||
" **kwargs\n",
|
||||
" ):\n",
|
||||
" super().__init__(\n",
|
||||
" name=name,\n",
|
||||
" size_x=size_x,\n",
|
||||
" size_y=size_y,\n",
|
||||
" size_z=size_z,\n",
|
||||
" category=category,\n",
|
||||
" )\n",
|
||||
" self._unilabos_state: MaterialHoleState = MaterialHoleState(\n",
|
||||
" diameter=20,\n",
|
||||
" depth=10,\n",
|
||||
" max_sheets=1,\n",
|
||||
" info=None\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def get_all_sheet_info(self):\n",
|
||||
" info_list = []\n",
|
||||
" for sheet in self.children:\n",
|
||||
" info_list.append(sheet._unilabos_state[\"info\"])\n",
|
||||
" return info_list\n",
|
||||
" \n",
|
||||
" #这个函数函数好像没用,一般不会集中赋值质量\n",
|
||||
" def set_all_sheet_mass(self):\n",
|
||||
" for sheet in self.children:\n",
|
||||
" sheet._unilabos_state[\"mass\"] = 0.5 # 示例:设置质量为0.5g\n",
|
||||
"\n",
|
||||
" def load_state(self, state: Dict[str, Any]) -> None:\n",
|
||||
" \"\"\"格式不变\"\"\"\n",
|
||||
" super().load_state(state)\n",
|
||||
" self._unilabos_state = state\n",
|
||||
"\n",
|
||||
" def serialize_state(self) -> Dict[str, Dict[str, Any]]:\n",
|
||||
" \"\"\"格式不变\"\"\"\n",
|
||||
" data = super().serialize_state()\n",
|
||||
" data.update(self._unilabos_state) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)\n",
|
||||
" return data\n",
|
||||
" #移动极片前先取出对象\n",
|
||||
" def get_sheet_with_name(self, name: str) -> Optional[ElectrodeSheet]:\n",
|
||||
" for sheet in self.children:\n",
|
||||
" if sheet.name == name:\n",
|
||||
" return sheet\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" def has_electrode_sheet(self) -> bool:\n",
|
||||
" \"\"\"检查洞位是否有极片\"\"\"\n",
|
||||
" return len(self.children) > 0\n",
|
||||
"\n",
|
||||
" def assign_child_resource(\n",
|
||||
" self,\n",
|
||||
" resource: ElectrodeSheet,\n",
|
||||
" location: Optional[Coordinate],\n",
|
||||
" reassign: bool = True,\n",
|
||||
" ):\n",
|
||||
" \"\"\"放置极片\"\"\"\n",
|
||||
" # TODO: 这里要改,diameter找不到,加入._unilabos_state后应该没问题\n",
|
||||
" if resource._unilabos_state[\"diameter\"] > self._unilabos_state[\"diameter\"]:\n",
|
||||
" raise ValueError(f\"极片直径 {resource._unilabos_state['diameter']} 超过洞位直径 {self._unilabos_state['diameter']}\")\n",
|
||||
" if len(self.children) >= self._unilabos_state[\"max_sheets\"]:\n",
|
||||
" raise ValueError(f\"洞位已满,无法放置更多极片\")\n",
|
||||
" super().assign_child_resource(resource, location, reassign)\n",
|
||||
"\n",
|
||||
" # 根据children的编号取物料对象。\n",
|
||||
" def get_electrode_sheet_info(self, index: int) -> ElectrodeSheet:\n",
|
||||
" return self.children[index]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#料板\n",
|
||||
"class MaterialPlateState(TypedDict):\n",
|
||||
" hole_spacing_x: float\n",
|
||||
" hole_spacing_y: float\n",
|
||||
" hole_diameter: float\n",
|
||||
" info: Optional[str] # 附加信息\n",
|
||||
"\n",
|
||||
"class MaterialPlate(ItemizedResource[MaterialHole]):\n",
|
||||
" \"\"\"料板类 - 4x4个洞位,每个洞位放1个极片\"\"\"\n",
|
||||
" \n",
|
||||
" children: List[MaterialHole]\n",
|
||||
"\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" name: str,\n",
|
||||
" size_x: float,\n",
|
||||
" size_y: float,\n",
|
||||
" size_z: float,\n",
|
||||
" ordered_items: Optional[Dict[str, MaterialHole]] = None,\n",
|
||||
" ordering: Optional[OrderedDict[str, str]] = None,\n",
|
||||
" category: str = \"material_plate\",\n",
|
||||
" model: Optional[str] = None,\n",
|
||||
" fill: bool = False\n",
|
||||
" ):\n",
|
||||
" \"\"\"初始化料板\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" name: 料板名称\n",
|
||||
" size_x: 长度 (mm)\n",
|
||||
" size_y: 宽度 (mm)\n",
|
||||
" size_z: 高度 (mm)\n",
|
||||
" hole_diameter: 洞直径 (mm)\n",
|
||||
" hole_depth: 洞深度 (mm)\n",
|
||||
" hole_spacing_x: X方向洞位间距 (mm)\n",
|
||||
" hole_spacing_y: Y方向洞位间距 (mm)\n",
|
||||
" number: 编号\n",
|
||||
" category: 类别\n",
|
||||
" model: 型号\n",
|
||||
" \"\"\"\n",
|
||||
" self._unilabos_state: MaterialPlateState = MaterialPlateState(\n",
|
||||
" hole_spacing_x=24.0,\n",
|
||||
" hole_spacing_y=24.0,\n",
|
||||
" hole_diameter=20.0,\n",
|
||||
" info=\"\",\n",
|
||||
" )\n",
|
||||
" # 创建4x4的洞位\n",
|
||||
" # TODO: 这里要改,对应不同形状\n",
|
||||
" holes = create_ordered_items_2d(\n",
|
||||
" klass=MaterialHole,\n",
|
||||
" num_items_x=4,\n",
|
||||
" num_items_y=4,\n",
|
||||
" dx=(size_x - 4 * self._unilabos_state[\"hole_spacing_x\"]) / 2, # 居中\n",
|
||||
" dy=(size_y - 4 * self._unilabos_state[\"hole_spacing_y\"]) / 2, # 居中\n",
|
||||
" dz=size_z,\n",
|
||||
" item_dx=self._unilabos_state[\"hole_spacing_x\"],\n",
|
||||
" item_dy=self._unilabos_state[\"hole_spacing_y\"],\n",
|
||||
" size_x = 16,\n",
|
||||
" size_y = 16,\n",
|
||||
" size_z = 16,\n",
|
||||
" )\n",
|
||||
" if fill:\n",
|
||||
" super().__init__(\n",
|
||||
" name=name,\n",
|
||||
" size_x=size_x,\n",
|
||||
" size_y=size_y,\n",
|
||||
" size_z=size_z,\n",
|
||||
" ordered_items=holes,\n",
|
||||
" category=category,\n",
|
||||
" model=model,\n",
|
||||
" )\n",
|
||||
" else:\n",
|
||||
" super().__init__(\n",
|
||||
" name=name,\n",
|
||||
" size_x=size_x,\n",
|
||||
" size_y=size_y,\n",
|
||||
" size_z=size_z,\n",
|
||||
" ordered_items=ordered_items,\n",
|
||||
" ordering=ordering,\n",
|
||||
" category=category,\n",
|
||||
" model=model,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def update_locations(self):\n",
|
||||
" # TODO:调多次相加\n",
|
||||
" holes = create_ordered_items_2d(\n",
|
||||
" klass=MaterialHole,\n",
|
||||
" num_items_x=4,\n",
|
||||
" num_items_y=4,\n",
|
||||
" dx=(self._size_x - 3 * self._unilabos_state[\"hole_spacing_x\"]) / 2, # 居中\n",
|
||||
" dy=(self._size_y - 3 * self._unilabos_state[\"hole_spacing_y\"]) / 2, # 居中\n",
|
||||
" dz=self._size_z,\n",
|
||||
" item_dx=self._unilabos_state[\"hole_spacing_x\"],\n",
|
||||
" item_dy=self._unilabos_state[\"hole_spacing_y\"],\n",
|
||||
" size_x = 1,\n",
|
||||
" size_y = 1,\n",
|
||||
" size_z = 1,\n",
|
||||
" )\n",
|
||||
" for item, original_item in zip(holes.items(), self.children):\n",
|
||||
" original_item.location = item[1].location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "8318ccca",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class CoincellDeck(Deck):\n",
|
||||
" \"\"\"纽扣电池组装工作站台面类\"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" name: str = \"coin_cell_deck\",\n",
|
||||
" size_x: float = 1620.0, # 3.66m\n",
|
||||
" size_y: float = 1270.0, # 1.23m\n",
|
||||
" size_z: float = 500.0,\n",
|
||||
" origin: Coordinate = Coordinate(0, 0, 0),\n",
|
||||
" category: str = \"coin_cell_deck\",\n",
|
||||
" ):\n",
|
||||
" \"\"\"初始化纽扣电池组装工作站台面\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" name: 台面名称\n",
|
||||
" size_x: 长度 (mm) - 3.66m\n",
|
||||
" size_y: 宽度 (mm) - 1.23m\n",
|
||||
" size_z: 高度 (mm)\n",
|
||||
" origin: 原点坐标\n",
|
||||
" category: 类别\n",
|
||||
" \"\"\"\n",
|
||||
" super().__init__(\n",
|
||||
" name=name,\n",
|
||||
" size_x=size_x,\n",
|
||||
" size_y=size_y,\n",
|
||||
" size_z=size_z,\n",
|
||||
" origin=origin,\n",
|
||||
" category=category,\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "c73bae21",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "3369a1dd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def upload_resources_to_unilab(wuliao: List[Resource]):\n",
|
||||
" from unilabos.resources.graphio import convert_resources_from_type\n",
|
||||
" from unilabos.config.config import BasicConfig \n",
|
||||
" BasicConfig.ak = \"beb0c15f-2279-46a1-aba5-00eaf89aef55\"\n",
|
||||
" BasicConfig.sk = \"15d4f25e-3512-4f9c-9bfb-43ab85e7b561\"\n",
|
||||
" from unilabos.app.web.client import http_client\n",
|
||||
" resources = convert_resources_from_type(wuliao, [Resource])\n",
|
||||
" json.dump({\"nodes\": resources, \"links\": []}, open(\"button_battery_station_resources_unilab.json\", \"w\"), indent=2)\n",
|
||||
" \n",
|
||||
" #print(resources)\n",
|
||||
" http_client.remote_addr = \"https://uni-lab.test.bohrium.com/api/v1\"\n",
|
||||
" \n",
|
||||
" http_client.resource_add(resources)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"id": "1543ddab",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"liaopan1 = MaterialPlate(name=\"liaopan1\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "b732754a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"MaterialPlate(name=liaopan1, size_x=120.8, size_y=120.5, size_z=10.0, location=None)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(liaopan1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"id": "7e6e7252",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[MaterialHole(name=liaopan1_materialhole_0_0, location=Coordinate(012.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_1, location=Coordinate(012.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_2, location=Coordinate(012.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_0_3, location=Coordinate(012.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_0, location=Coordinate(036.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_1, location=Coordinate(036.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_2, location=Coordinate(036.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_1_3, location=Coordinate(036.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_0, location=Coordinate(060.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_1, location=Coordinate(060.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_2, location=Coordinate(060.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_2_3, location=Coordinate(060.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_0, location=Coordinate(084.400, 084.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_1, location=Coordinate(084.400, 060.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_2, location=Coordinate(084.400, 036.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole), MaterialHole(name=liaopan1_materialhole_3_3, location=Coordinate(084.400, 012.250, 010.000), size_x=16, size_y=16, size_z=16, category=material_hole)]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(liaopan1.children)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"id": "836ff68d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [15:15:08,950]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CoincellDeck(name=coin_cell_deck, location=Coordinate(000.000, 000.000, 000.000), size_x=1620.0, size_y=1270.0, size_z=500.0, category=coin_cell_deck)\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [15:15:09,218]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"deck = CoincellDeck()\n",
|
||||
"#创建一个4*4的物料板\n",
|
||||
"liaopan1 = MaterialPlate(name=\"liaopan1\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)\n",
|
||||
"#把物料板放到桌子上\n",
|
||||
"deck.assign_child_resource(liaopan1, Coordinate(x=0, y=0, z=0))\n",
|
||||
"#创建一个极片\n",
|
||||
"for i in range(16):\n",
|
||||
" jipian = ElectrodeSheet(name=f\"jipian_{i}\", size_x= 12, size_y=12, size_z=0.1)\n",
|
||||
" liaopan1.children[i].assign_child_resource(jipian, location=None)\n",
|
||||
"#创建一个4*4的物料板\n",
|
||||
"liaopan2 = MaterialPlate(name=\"liaopan2\", size_x=120.8, size_y=120.5, size_z=10.0, fill=True)\n",
|
||||
"#把物料板放到桌子上\n",
|
||||
"deck.assign_child_resource(liaopan2, Coordinate(x=500, y=0, z=0))\n",
|
||||
"#liaopan.children[3].assign_child_resource(jipian, location=None)\n",
|
||||
"print(deck)\n",
|
||||
"\n",
|
||||
"upload_resources_to_unilab([deck])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "00aab9cf",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"MaterialPlate(name=liaopan1, size_x=120.8, size_y=120.5, size_z=10.0, location=Coordinate(000.000, 000.000, 000.000))\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"liaopan1 = deck.get_resource(\"liaopan1\")\n",
|
||||
"print(liaopan1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7409969c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"liaopan1 = deck.get_resource(\"liaopan1\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "096dde04",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "5528df96",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [15:17:44,322]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ElectrodeSheet(name=jipian_1, location=None, size_x=12, size_y=12, size_z=0.1, category=electrode_sheet)\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [15:17:44,599]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#在台面上找到料盘和极片\n",
|
||||
"liaopan1 = deck.get_resource(\"liaopan1\")\n",
|
||||
"liaopan2 = deck.get_resource(\"liaopan2\")\n",
|
||||
"jipian1 = liaopan1.children[1].children[0]\n",
|
||||
"#\n",
|
||||
"print(jipian1)\n",
|
||||
"#把物料解绑后放到另一盘上\n",
|
||||
"jipian1.parent.unassign_child_resource(jipian1)\n",
|
||||
"liaopan2.children[1].assign_child_resource(jipian1, location=None)\n",
|
||||
"#print(jipian2.parent)\n",
|
||||
"upload_resources_to_unilab([deck])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "43736700",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [14:31:50,027]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mStarting new HTTPS connection (1): uni-lab.test.bohrium.com:443\u001b[37m [_new_conn:1049] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 electrode_sheet\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_hole\n",
|
||||
"转换pylabrobot的时候,出现未知类型 material_plate\n",
|
||||
"转换pylabrobot的时候,出现未知类型 coin_cell_deck\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[37m25-09-22 [14:31:50,358]\u001b[0m \u001b[1;36m[DEBUG]\u001b[0m \u001b[37mhttps://uni-lab.test.bohrium.com:443 \"POST /api/v1/lab/material HTTP/1.1\" 200 10\u001b[37m [_make_request:544] [urllib3.connectionpool.connectionpool]\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<Response [200]>"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "unilab",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,489 @@
|
||||
"""
|
||||
工作站基类
|
||||
Workstation Base Class - 简化版
|
||||
|
||||
基于PLR Deck的简化工作站架构
|
||||
专注于核心物料系统和工作流管理
|
||||
"""
|
||||
|
||||
import collections
|
||||
import time
|
||||
from typing import Dict, Any, List, Optional, Union
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from pylabrobot.resources import Deck, Plate, Resource as PLRResource
|
||||
|
||||
from pylabrobot.resources.coordinate import Coordinate
|
||||
from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
|
||||
|
||||
from unilabos.utils.log import logger
|
||||
|
||||
|
||||
class WorkflowStatus(Enum):
|
||||
"""工作流状态"""
|
||||
|
||||
IDLE = "idle"
|
||||
INITIALIZING = "initializing"
|
||||
RUNNING = "running"
|
||||
PAUSED = "paused"
|
||||
STOPPING = "stopping"
|
||||
STOPPED = "stopped"
|
||||
ERROR = "error"
|
||||
COMPLETED = "completed"
|
||||
|
||||
|
||||
@dataclass
|
||||
class WorkflowInfo:
|
||||
"""工作流信息"""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
estimated_duration: float # 预估持续时间(秒)
|
||||
required_materials: List[str] # 所需物料类型
|
||||
output_product: str # 输出产品类型
|
||||
parameters_schema: Dict[str, Any] # 参数架构
|
||||
|
||||
|
||||
class WorkStationContainer(Plate):
|
||||
"""
|
||||
WorkStation 专用 Container 类,继承自 Plate和TipRack
|
||||
注意这个物料必须通过plr_additional_res_reg.py注册到edge,才能正常序列化
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
size_x: float,
|
||||
size_y: float,
|
||||
size_z: float,
|
||||
category: str,
|
||||
ordering: collections.OrderedDict,
|
||||
model: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
这里的初始化入参要和plr的保持一致
|
||||
"""
|
||||
super().__init__(name, size_x, size_y, size_z, category=category, ordering=ordering, model=model)
|
||||
self._unilabos_state = {} # 必须有此行,自己的类描述的是物料的
|
||||
|
||||
def load_state(self, state: Dict[str, Any]) -> None:
|
||||
"""从给定的状态加载工作台信息。"""
|
||||
super().load_state(state)
|
||||
self._unilabos_state = state
|
||||
|
||||
def serialize_state(self) -> Dict[str, Dict[str, Any]]:
|
||||
data = super().serialize_state()
|
||||
data.update(
|
||||
self._unilabos_state
|
||||
) # Container自身的信息,云端物料将保存这一data,本地也通过这里的data进行读写,当前类用来表示这个物料的长宽高大小的属性,而data(state用来表示物料的内容,细节等)
|
||||
return data
|
||||
|
||||
|
||||
def get_workstation_plate_resource(name: str) -> PLRResource: # 要给定一个返回plr的方法
|
||||
"""
|
||||
用于获取一些模板,例如返回一个带有特定信息/子物料的 Plate,这里需要到注册表注册,例如unilabos/registry/resources/organic/workstation.yaml
|
||||
可以直接运行该函数或者利用注册表补全机制,来检查是否资源出错
|
||||
:param name: 资源名称
|
||||
:return: Resource对象
|
||||
"""
|
||||
plate = WorkStationContainer(
|
||||
name, size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()
|
||||
)
|
||||
tip_rack = WorkStationContainer(
|
||||
"tip_rack_inside_plate",
|
||||
size_x=50,
|
||||
size_y=50,
|
||||
size_z=10,
|
||||
category="tip_rack",
|
||||
ordering=collections.OrderedDict(),
|
||||
)
|
||||
plate.assign_child_resource(tip_rack, Coordinate.zero())
|
||||
return plate
|
||||
|
||||
|
||||
class ResourceSynchronizer(ABC):
|
||||
"""资源同步器基类
|
||||
|
||||
负责与外部物料系统的同步,并对 self.deck 做修改
|
||||
"""
|
||||
|
||||
def __init__(self, workstation: "WorkstationBase"):
|
||||
self.workstation = workstation
|
||||
|
||||
@abstractmethod
|
||||
async def sync_from_external(self) -> bool:
|
||||
"""从外部系统同步物料到本地deck"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def sync_to_external(self, plr_resource: PLRResource) -> bool:
|
||||
"""将本地物料同步到外部系统"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def handle_external_change(self, change_info: Dict[str, Any]) -> bool:
|
||||
"""处理外部系统的变更通知"""
|
||||
pass
|
||||
|
||||
|
||||
class WorkstationBase(ABC):
|
||||
"""工作站基类 - 简化版
|
||||
|
||||
核心功能:
|
||||
1. 基于 PLR Deck 的物料系统,支持格式转换
|
||||
2. 可选的资源同步器支持外部物料系统
|
||||
3. 简化的工作流管理
|
||||
"""
|
||||
|
||||
_ros_node: ROS2WorkstationNode
|
||||
|
||||
@property
|
||||
def _children(self) -> Dict[str, Any]: # 不要删除这个下划线,不然会自动导入注册表,后面改成装饰器识别
|
||||
return self._ros_node.children
|
||||
|
||||
async def update_resource_example(self):
|
||||
return await self._ros_node.update_resource([get_workstation_plate_resource("test")])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
station_resource: PLRResource,
|
||||
*args,
|
||||
**kwargs, # 必须有kwargs
|
||||
):
|
||||
# 基本配置
|
||||
print(station_resource)
|
||||
self.deck_config = station_resource
|
||||
|
||||
# PLR 物料系统
|
||||
self.deck: Optional[Deck] = None
|
||||
self.plr_resources: Dict[str, PLRResource] = {}
|
||||
|
||||
# 资源同步器(可选)
|
||||
# self.resource_synchronizer = ResourceSynchronizer(self) # 要在driver中自行初始化,只有workstation用
|
||||
|
||||
# 硬件接口
|
||||
self.hardware_interface: Union[Any, str] = None
|
||||
|
||||
# 工作流状态
|
||||
self.current_workflow_status = WorkflowStatus.IDLE
|
||||
self.current_workflow_info = None
|
||||
self.workflow_start_time = None
|
||||
self.workflow_parameters = {}
|
||||
|
||||
# 支持的工作流(静态预定义)
|
||||
self.supported_workflows: Dict[str, WorkflowInfo] = {}
|
||||
|
||||
# 初始化物料系统
|
||||
self._initialize_material_system()
|
||||
|
||||
# 注册支持的工作流
|
||||
# self._register_supported_workflows()
|
||||
|
||||
# logger.info(f"工作站 {device_id} 初始化完成(简化版)")
|
||||
|
||||
def _initialize_material_system(self):
|
||||
"""初始化物料系统 - 使用 graphio 转换"""
|
||||
try:
|
||||
from unilabos.resources.graphio import resource_ulab_to_plr
|
||||
|
||||
# # 1. 合并 deck_config 和 children 创建完整的资源树
|
||||
# complete_resource_config = self._create_complete_resource_config()
|
||||
|
||||
# # 2. 使用 graphio 转换为 PLR 资源
|
||||
# self.deck = resource_ulab_to_plr(complete_resource_config, plr_model=True)
|
||||
|
||||
# # 3. 建立资源映射
|
||||
# self._build_resource_mappings(self.deck)
|
||||
|
||||
# # 4. 如果有资源同步器,执行初始同步
|
||||
# if self.resource_synchronizer:
|
||||
# # 这里可以异步执行,暂时跳过
|
||||
# pass
|
||||
|
||||
# logger.info(f"工作站 {self.device_id} 物料系统初始化成功,创建了 {len(self.plr_resources)} 个资源")
|
||||
pass
|
||||
except Exception as e:
|
||||
# logger.error(f"工作站 {self.device_id} 物料系统初始化失败: {e}")
|
||||
raise
|
||||
|
||||
def _create_complete_resource_config(self) -> Dict[str, Any]:
|
||||
"""创建完整的资源配置 - 合并 deck_config 和 children"""
|
||||
# 创建主 deck 配置
|
||||
deck_resource = {
|
||||
"id": f"{self.device_id}_deck",
|
||||
"name": f"{self.device_id}_deck",
|
||||
"type": "deck",
|
||||
"position": {"x": 0, "y": 0, "z": 0},
|
||||
"config": {
|
||||
"size_x": self.deck_config.get("size_x", 1000.0),
|
||||
"size_y": self.deck_config.get("size_y", 1000.0),
|
||||
"size_z": self.deck_config.get("size_z", 100.0),
|
||||
**{k: v for k, v in self.deck_config.items() if k not in ["size_x", "size_y", "size_z"]},
|
||||
},
|
||||
"data": {},
|
||||
"children": [],
|
||||
"parent": None,
|
||||
}
|
||||
|
||||
# 添加子资源
|
||||
if self._children:
|
||||
children_list = []
|
||||
for child_id, child_config in self._children.items():
|
||||
child_resource = self._normalize_child_resource(child_id, child_config, deck_resource["id"])
|
||||
children_list.append(child_resource)
|
||||
deck_resource["children"] = children_list
|
||||
|
||||
return deck_resource
|
||||
|
||||
def _normalize_child_resource(self, resource_id: str, config: Dict[str, Any], parent_id: str) -> Dict[str, Any]:
|
||||
"""标准化子资源配置"""
|
||||
return {
|
||||
"id": resource_id,
|
||||
"name": config.get("name", resource_id),
|
||||
"type": config.get("type", "container"),
|
||||
"position": self._normalize_position(config.get("position", {})),
|
||||
"config": config.get("config", {}),
|
||||
"data": config.get("data", {}),
|
||||
"children": [], # 简化版本:只支持一层子资源
|
||||
"parent": parent_id,
|
||||
}
|
||||
|
||||
def _normalize_position(self, position: Any) -> Dict[str, float]:
|
||||
"""标准化位置信息"""
|
||||
if isinstance(position, dict):
|
||||
return {
|
||||
"x": float(position.get("x", 0)),
|
||||
"y": float(position.get("y", 0)),
|
||||
"z": float(position.get("z", 0)),
|
||||
}
|
||||
elif isinstance(position, (list, tuple)) and len(position) >= 2:
|
||||
return {
|
||||
"x": float(position[0]),
|
||||
"y": float(position[1]),
|
||||
"z": float(position[2]) if len(position) > 2 else 0.0,
|
||||
}
|
||||
else:
|
||||
return {"x": 0.0, "y": 0.0, "z": 0.0}
|
||||
|
||||
def _build_resource_mappings(self, deck: Deck):
|
||||
"""递归构建资源映射"""
|
||||
|
||||
def add_resource_recursive(resource: PLRResource):
|
||||
if hasattr(resource, "name"):
|
||||
self.plr_resources[resource.name] = resource
|
||||
|
||||
if hasattr(resource, "children"):
|
||||
for child in resource.children:
|
||||
add_resource_recursive(child)
|
||||
|
||||
add_resource_recursive(deck)
|
||||
|
||||
# ============ 硬件接口管理 ============
|
||||
|
||||
def set_hardware_interface(self, hardware_interface: Union[Any, str]):
|
||||
"""设置硬件接口"""
|
||||
self.hardware_interface = hardware_interface
|
||||
logger.info(f"工作站 {self.device_id} 硬件接口设置: {type(hardware_interface).__name__}")
|
||||
|
||||
def set_workstation_node(self, workstation_node: "ROS2WorkstationNode"):
|
||||
"""设置协议节点引用(用于代理模式)"""
|
||||
self._ros_node = workstation_node
|
||||
logger.info(f"工作站 {self.device_id} 关联协议节点")
|
||||
|
||||
# ============ 设备操作接口 ============
|
||||
|
||||
def call_device_method(self, method: str, *args, **kwargs) -> Any:
|
||||
"""调用设备方法的统一接口"""
|
||||
# 1. 代理模式:通过协议节点转发
|
||||
if isinstance(self.hardware_interface, str) and self.hardware_interface.startswith("proxy:"):
|
||||
if not self._ros_node:
|
||||
raise RuntimeError("代理模式需要设置workstation_node")
|
||||
|
||||
device_id = self.hardware_interface[6:] # 移除 "proxy:" 前缀
|
||||
return self._ros_node.call_device_method(device_id, method, *args, **kwargs)
|
||||
|
||||
# 2. 直接模式:直接调用硬件接口方法
|
||||
elif self.hardware_interface and hasattr(self.hardware_interface, method):
|
||||
return getattr(self.hardware_interface, method)(*args, **kwargs)
|
||||
|
||||
else:
|
||||
raise AttributeError(f"硬件接口不支持方法: {method}")
|
||||
|
||||
def get_device_status(self) -> Dict[str, Any]:
|
||||
"""获取设备状态"""
|
||||
try:
|
||||
return self.call_device_method("get_status")
|
||||
except AttributeError:
|
||||
# 如果设备不支持get_status方法,返回基础状态
|
||||
return {
|
||||
"status": "unknown",
|
||||
"interface_type": type(self.hardware_interface).__name__,
|
||||
"timestamp": time.time(),
|
||||
}
|
||||
|
||||
def is_device_available(self) -> bool:
|
||||
"""检查设备是否可用"""
|
||||
try:
|
||||
self.get_device_status()
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
# ============ 物料系统接口 ============
|
||||
|
||||
def get_deck(self) -> Deck:
|
||||
"""获取主 Deck"""
|
||||
return self.deck
|
||||
|
||||
def get_all_resources(self) -> Dict[str, PLRResource]:
|
||||
"""获取所有 PLR 资源"""
|
||||
return self.plr_resources.copy()
|
||||
|
||||
def find_resource_by_name(self, name: str) -> Optional[PLRResource]:
|
||||
"""按名称查找资源"""
|
||||
return self.plr_resources.get(name)
|
||||
|
||||
def find_resources_by_type(self, resource_type: type) -> List[PLRResource]:
|
||||
"""按类型查找资源"""
|
||||
return [res for res in self.plr_resources.values() if isinstance(res, resource_type)]
|
||||
|
||||
async def sync_with_external_system(self) -> bool:
|
||||
"""与外部物料系统同步"""
|
||||
if not self.resource_synchronizer:
|
||||
logger.info(f"工作站 {self.device_id} 没有配置资源同步器")
|
||||
return True
|
||||
|
||||
try:
|
||||
success = await self.resource_synchronizer.sync_from_external()
|
||||
if success:
|
||||
logger.info(f"工作站 {self.device_id} 外部同步成功")
|
||||
else:
|
||||
logger.warning(f"工作站 {self.device_id} 外部同步失败")
|
||||
return success
|
||||
except Exception as e:
|
||||
logger.error(f"工作站 {self.device_id} 外部同步异常: {e}")
|
||||
return False
|
||||
|
||||
# ============ 简化的工作流控制 ============
|
||||
|
||||
def execute_workflow(self, workflow_name: str, parameters: Dict[str, Any]) -> bool:
|
||||
"""执行工作流"""
|
||||
try:
|
||||
# 设置工作流状态
|
||||
self.current_workflow_status = WorkflowStatus.INITIALIZING
|
||||
self.workflow_parameters = parameters
|
||||
self.workflow_start_time = time.time()
|
||||
|
||||
# 委托给子类实现
|
||||
success = self._execute_workflow_impl(workflow_name, parameters)
|
||||
|
||||
if success:
|
||||
self.current_workflow_status = WorkflowStatus.RUNNING
|
||||
logger.info(f"工作站 {self.device_id} 工作流 {workflow_name} 启动成功")
|
||||
else:
|
||||
self.current_workflow_status = WorkflowStatus.ERROR
|
||||
logger.error(f"工作站 {self.device_id} 工作流 {workflow_name} 启动失败")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
self.current_workflow_status = WorkflowStatus.ERROR
|
||||
logger.error(f"工作站 {self.device_id} 执行工作流失败: {e}")
|
||||
return False
|
||||
|
||||
def stop_workflow(self, emergency: bool = False) -> bool:
|
||||
"""停止工作流"""
|
||||
try:
|
||||
if self.current_workflow_status in [WorkflowStatus.IDLE, WorkflowStatus.STOPPED]:
|
||||
logger.warning(f"工作站 {self.device_id} 没有正在运行的工作流")
|
||||
return True
|
||||
|
||||
self.current_workflow_status = WorkflowStatus.STOPPING
|
||||
|
||||
# 委托给子类实现
|
||||
success = self._stop_workflow_impl(emergency)
|
||||
|
||||
if success:
|
||||
self.current_workflow_status = WorkflowStatus.STOPPED
|
||||
logger.info(f"工作站 {self.device_id} 工作流停止成功 (紧急: {emergency})")
|
||||
else:
|
||||
self.current_workflow_status = WorkflowStatus.ERROR
|
||||
logger.error(f"工作站 {self.device_id} 工作流停止失败")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
self.current_workflow_status = WorkflowStatus.ERROR
|
||||
logger.error(f"工作站 {self.device_id} 停止工作流失败: {e}")
|
||||
return False
|
||||
|
||||
# ============ 状态属性 ============
|
||||
|
||||
@property
|
||||
def workflow_status(self) -> WorkflowStatus:
|
||||
"""获取当前工作流状态"""
|
||||
return self.current_workflow_status
|
||||
|
||||
@property
|
||||
def is_busy(self) -> bool:
|
||||
"""检查工作站是否忙碌"""
|
||||
return self.current_workflow_status in [
|
||||
WorkflowStatus.INITIALIZING,
|
||||
WorkflowStatus.RUNNING,
|
||||
WorkflowStatus.STOPPING,
|
||||
]
|
||||
|
||||
@property
|
||||
def workflow_runtime(self) -> float:
|
||||
"""获取工作流运行时间(秒)"""
|
||||
if self.workflow_start_time is None:
|
||||
return 0.0
|
||||
return time.time() - self.workflow_start_time
|
||||
|
||||
# ============ 抽象方法 - 子类必须实现 ============
|
||||
|
||||
# @abstractmethod
|
||||
# def _register_supported_workflows(self):
|
||||
# """注册支持的工作流 - 子类必须实现"""
|
||||
# pass
|
||||
|
||||
# @abstractmethod
|
||||
# def _execute_workflow_impl(self, workflow_name: str, parameters: Dict[str, Any]) -> bool:
|
||||
# """执行工作流的具体实现 - 子类必须实现"""
|
||||
# pass
|
||||
|
||||
# @abstractmethod
|
||||
# def _stop_workflow_impl(self, emergency: bool = False) -> bool:
|
||||
# """停止工作流的具体实现 - 子类必须实现"""
|
||||
# pass
|
||||
|
||||
class WorkstationExample(WorkstationBase):
|
||||
"""工作站示例实现"""
|
||||
|
||||
def _register_supported_workflows(self):
|
||||
"""注册支持的工作流"""
|
||||
self.supported_workflows["example_workflow"] = WorkflowInfo(
|
||||
name="example_workflow",
|
||||
description="这是一个示例工作流",
|
||||
estimated_duration=300.0,
|
||||
required_materials=["sample_plate"],
|
||||
output_product="processed_plate",
|
||||
parameters_schema={"param1": "string", "param2": "integer"},
|
||||
)
|
||||
|
||||
def _execute_workflow_impl(self, workflow_name: str, parameters: Dict[str, Any]) -> bool:
|
||||
"""执行工作流的具体实现"""
|
||||
if workflow_name not in self.supported_workflows:
|
||||
logger.error(f"工作站 {self.device_id} 不支持工作流: {workflow_name}")
|
||||
return False
|
||||
|
||||
# 这里添加实际的工作流逻辑
|
||||
logger.info(f"工作站 {self.device_id} 正在执行工作流: {workflow_name} with parameters {parameters}")
|
||||
return True
|
||||
|
||||
def _stop_workflow_impl(self, emergency: bool = False) -> bool:
|
||||
"""停止工作流的具体实现"""
|
||||
# 这里添加实际的停止逻辑
|
||||
logger.info(f"工作站 {self.device_id} 正在停止工作流 (紧急: {emergency})")
|
||||
return True
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user