solax-py-library 1.0.0.2521__py3-none-any.whl → 1.0.0.2602__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- solax_py_library/device/types/device.py +26 -0
- solax_py_library/smart_scene/constant/message_entry.py +13 -1
- solax_py_library/smart_scene/core/condition/cabinet_condition.py +17 -17
- solax_py_library/smart_scene/types/condition.py +9 -2
- solax_py_library/smart_scene/types/condition_value.py +30 -0
- solax_py_library/test/test_smart_scene/test_condition.py +57 -2
- {solax_py_library-1.0.0.2521.dist-info → solax_py_library-1.0.0.2602.dist-info}/METADATA +1 -1
- {solax_py_library-1.0.0.2521.dist-info → solax_py_library-1.0.0.2602.dist-info}/RECORD +9 -7
- {solax_py_library-1.0.0.2521.dist-info → solax_py_library-1.0.0.2602.dist-info}/WHEEL +0 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
from enum import IntEnum
|
2
|
+
|
3
|
+
|
4
|
+
class DeviceType(IntEnum):
|
5
|
+
EMS_TYPE = 100
|
6
|
+
PCS_TYPE = 1
|
7
|
+
BMS_TYPE = 2 # 电池簇
|
8
|
+
ELM_TYPE = 3
|
9
|
+
EVC_TYPE = 4
|
10
|
+
IO_TYPE = 5
|
11
|
+
ESS_TYPE = 6 # 机柜
|
12
|
+
CELL_TYPE = 7 # 单体
|
13
|
+
AIRCONDITIONER_TYPE = 501
|
14
|
+
FIRE_SAFETY_TYPE = 502
|
15
|
+
COLD_TYPE = 503
|
16
|
+
DEHUMIDIFY_TYPE = 504
|
17
|
+
|
18
|
+
def __str__(self):
|
19
|
+
return {
|
20
|
+
DeviceType.PCS_TYPE: "pcs",
|
21
|
+
DeviceType.BMS_TYPE: "bms",
|
22
|
+
DeviceType.ELM_TYPE: "elm",
|
23
|
+
DeviceType.IO_TYPE: "io",
|
24
|
+
DeviceType.AIRCONDITIONER_TYPE: "air_conditioner",
|
25
|
+
DeviceType.COLD_TYPE: "liquid_cooling_unit",
|
26
|
+
}.get(self)
|
@@ -170,10 +170,22 @@ MESSAGE_ENTRY = {
|
|
170
170
|
"EMERGENCY": {"zh_CN": "紧急告警", "en_US": "Emergency alarm"},
|
171
171
|
"TIPS": {"zh_CN": "状态提醒", "en_US": "State Tips"},
|
172
172
|
"NORMAL": {"zh_CN": "普通告警", "en_US": "Normal alarm"},
|
173
|
-
"cabinetAlarm": {
|
173
|
+
"cabinetAlarm": {
|
174
|
+
"zh_CN": "机柜下属({})设备发生{}",
|
175
|
+
"en_US": "The equipments({}) under the cabinet occurs {}",
|
176
|
+
},
|
174
177
|
"OR": {"zh_CN": "满足任一条件", "en_US": "Meet any of the conditions"},
|
175
178
|
"AND": {"zh_CN": "满足所有条件", "en_US": "Meet all conditions"},
|
176
179
|
"tips_alarm": {"zh_CN": "状态提醒", "en_US": "Alarm tips"},
|
177
180
|
"normal_alarm": {"zh_CN": "普通告警", "en_US": "Normal alarm"},
|
178
181
|
"emergency_alarm": {"zh_CN": "紧急告警", "en_US": "Emergency alarm"},
|
182
|
+
"pcs": {"zh_CN": "逆变器", "en_US": "Inverter"},
|
183
|
+
"bms": {"zh_CN": "电池", "en_US": "Battery"},
|
184
|
+
"elm": {
|
185
|
+
"zh_CN": "电表",
|
186
|
+
"en_US": "Meter",
|
187
|
+
},
|
188
|
+
"io": {"zh_CN": "IO模块", "en_US": "IO Module"},
|
189
|
+
"air_conditioner": {"zh_CN": "空调", "en_US": "Air conditioner"},
|
190
|
+
"liquid_cooling_unit": {"zh_CN": "液冷机组", "en_US": "Liquid Cooling Unit"},
|
179
191
|
}
|
@@ -6,7 +6,7 @@ from solax_py_library.smart_scene.types.condition import (
|
|
6
6
|
CabinetConditionType,
|
7
7
|
ConditionType,
|
8
8
|
)
|
9
|
-
from solax_py_library.
|
9
|
+
from solax_py_library.smart_scene.types.condition_value import CabinetValue
|
10
10
|
|
11
11
|
|
12
12
|
class CabinetCondition(BaseCondition):
|
@@ -14,31 +14,31 @@ class CabinetCondition(BaseCondition):
|
|
14
14
|
|
15
15
|
def __init__(self, update_value_function, **kwargs):
|
16
16
|
super().__init__(update_value_function, **kwargs)
|
17
|
-
self.value = defaultdict(
|
18
|
-
lambda: {
|
19
|
-
"soc": 0,
|
20
|
-
"alarm_level": {
|
21
|
-
AlarmLevel.EMERGENCY: False,
|
22
|
-
AlarmLevel.NORMAL: False,
|
23
|
-
AlarmLevel.TIPS: False,
|
24
|
-
},
|
25
|
-
}
|
26
|
-
)
|
17
|
+
self.value = defaultdict(lambda: CabinetValue)
|
27
18
|
|
28
19
|
def meet_func(self, data: CabinetConditionItemData, ctx):
|
29
20
|
if not self.value:
|
30
21
|
return False
|
31
22
|
cabinet = ctx["cabinet"] or []
|
23
|
+
condition_data = data.childData.data
|
32
24
|
for cabinet_sn in cabinet:
|
25
|
+
cabinet_value = self.value[cabinet_sn]
|
26
|
+
if not cabinet_value:
|
27
|
+
continue
|
33
28
|
if data.childType == CabinetConditionType.cabinetSoc:
|
34
|
-
if self.value[cabinet_sn]
|
35
|
-
|
29
|
+
if self.value[cabinet_sn].soc is None:
|
30
|
+
continue
|
36
31
|
if data.childData.function.function()(
|
37
|
-
compare_value=self.value[cabinet_sn]
|
38
|
-
base_value=
|
32
|
+
compare_value=self.value[cabinet_sn].soc,
|
33
|
+
base_value=condition_data[0],
|
39
34
|
):
|
40
35
|
return True
|
41
36
|
elif data.childType == CabinetConditionType.cabinetAlarm:
|
42
|
-
|
43
|
-
|
37
|
+
alarm_type = condition_data[-1]
|
38
|
+
for device_type in condition_data[:-1]:
|
39
|
+
alarm_info = cabinet_value.alarm_info(device_type)
|
40
|
+
if not alarm_info:
|
41
|
+
continue
|
42
|
+
if alarm_info[alarm_type - 1] is True:
|
43
|
+
return True
|
44
44
|
return False
|
@@ -5,6 +5,7 @@ from typing import Optional, List, Union, Any
|
|
5
5
|
from pydantic import BaseModel, validator, root_validator
|
6
6
|
|
7
7
|
from solax_py_library.device.types.alarm import AlarmLevel
|
8
|
+
from solax_py_library.device.types.device import DeviceType
|
8
9
|
from solax_py_library.smart_scene.constant.message_entry import MESSAGE_ENTRY
|
9
10
|
|
10
11
|
|
@@ -163,7 +164,7 @@ class CabinetConditionItemData(BaseModel):
|
|
163
164
|
def _check_child_data(cls, value, values):
|
164
165
|
child_type = values.get("childType")
|
165
166
|
if child_type == CabinetConditionType.cabinetAlarm:
|
166
|
-
assert value.data[
|
167
|
+
assert value.data[-1] in {
|
167
168
|
AlarmLevel.TIPS,
|
168
169
|
AlarmLevel.NORMAL,
|
169
170
|
AlarmLevel.EMERGENCY,
|
@@ -181,7 +182,13 @@ class CabinetConditionItemData(BaseModel):
|
|
181
182
|
)
|
182
183
|
elif self.childType == CabinetConditionType.cabinetAlarm:
|
183
184
|
return MESSAGE_ENTRY[self.childType][lang].format(
|
184
|
-
|
185
|
+
",".join(
|
186
|
+
[
|
187
|
+
MESSAGE_ENTRY[str(DeviceType(device_type))][lang]
|
188
|
+
for device_type in data[:-1]
|
189
|
+
]
|
190
|
+
),
|
191
|
+
MESSAGE_ENTRY[str(AlarmLevel(data[-1]))][lang],
|
185
192
|
)
|
186
193
|
|
187
194
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
from solax_py_library.device.types.device import DeviceType
|
6
|
+
|
7
|
+
|
8
|
+
class CabinetValue(BaseModel):
|
9
|
+
soc: int = None
|
10
|
+
cabinet_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
11
|
+
pcs_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
12
|
+
io_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
13
|
+
bms_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
14
|
+
air_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
15
|
+
liquid_alarm: List[bool] = Field(default_factory=lambda: [False, False, False])
|
16
|
+
|
17
|
+
def alarm_info(self, device_type):
|
18
|
+
if device_type == DeviceType.EMS_TYPE:
|
19
|
+
return self.cabinet_alarm
|
20
|
+
elif device_type == DeviceType.PCS_TYPE:
|
21
|
+
return self.pcs_alarm
|
22
|
+
elif device_type == DeviceType.IO_TYPE:
|
23
|
+
return self.io_alarm
|
24
|
+
elif device_type == DeviceType.BMS_TYPE:
|
25
|
+
return self.bms_alarm
|
26
|
+
elif device_type == DeviceType.AIRCONDITIONER_TYPE:
|
27
|
+
return self.air_alarm
|
28
|
+
elif device_type == DeviceType.COLD_TYPE:
|
29
|
+
return self.liquid_alarm
|
30
|
+
return None
|
@@ -1,11 +1,66 @@
|
|
1
1
|
from unittest import TestCase
|
2
2
|
|
3
|
-
from solax_py_library.
|
3
|
+
from solax_py_library.device.types.device import DeviceType
|
4
|
+
from solax_py_library.smart_scene.core.condition import (
|
5
|
+
DateCondition,
|
6
|
+
BaseCondition,
|
7
|
+
CabinetCondition,
|
8
|
+
)
|
9
|
+
from solax_py_library.smart_scene.types.condition import (
|
10
|
+
CabinetConditionItemData,
|
11
|
+
CabinetConditionType,
|
12
|
+
ConditionItemChildData,
|
13
|
+
)
|
14
|
+
from solax_py_library.smart_scene.types.condition_value import CabinetValue
|
4
15
|
|
5
16
|
|
6
17
|
class TestCondition(TestCase):
|
7
|
-
def
|
18
|
+
def test_condition_build(self):
|
8
19
|
date_condition = DateCondition(
|
9
20
|
update_value_function=lambda: 1,
|
10
21
|
)
|
11
22
|
assert isinstance(date_condition, BaseCondition)
|
23
|
+
|
24
|
+
def test_cabinet_condition_to_text(self):
|
25
|
+
cabinet_condition = CabinetConditionItemData(
|
26
|
+
childType=CabinetConditionType.cabinetAlarm,
|
27
|
+
childData=ConditionItemChildData(
|
28
|
+
data=[DeviceType.IO_TYPE, DeviceType.COLD_TYPE, 1]
|
29
|
+
),
|
30
|
+
)
|
31
|
+
print(cabinet_condition.to_text(lang="zh_CN", unit="嘻嘻"))
|
32
|
+
|
33
|
+
def test_cabinet_condition_check(self):
|
34
|
+
cabinet_condition = CabinetCondition(
|
35
|
+
update_value_function=lambda: {
|
36
|
+
"SN1": CabinetValue(
|
37
|
+
soc=0,
|
38
|
+
io_alarm=[False, True, False],
|
39
|
+
),
|
40
|
+
},
|
41
|
+
)
|
42
|
+
cabinet_condition.update_value()
|
43
|
+
assert (
|
44
|
+
cabinet_condition.meet_func(
|
45
|
+
data=CabinetConditionItemData(
|
46
|
+
childType=CabinetConditionType.cabinetAlarm,
|
47
|
+
childData=ConditionItemChildData(
|
48
|
+
data=[DeviceType.IO_TYPE, DeviceType.COLD_TYPE, 1]
|
49
|
+
),
|
50
|
+
),
|
51
|
+
ctx={"cabinet": ["SN1"]},
|
52
|
+
)
|
53
|
+
is False
|
54
|
+
)
|
55
|
+
assert (
|
56
|
+
cabinet_condition.meet_func(
|
57
|
+
data=CabinetConditionItemData(
|
58
|
+
childType=CabinetConditionType.cabinetAlarm,
|
59
|
+
childData=ConditionItemChildData(
|
60
|
+
data=[DeviceType.IO_TYPE, DeviceType.COLD_TYPE, 2]
|
61
|
+
),
|
62
|
+
),
|
63
|
+
ctx={"cabinet": ["SN1"]},
|
64
|
+
)
|
65
|
+
is True
|
66
|
+
)
|
@@ -8,12 +8,13 @@ solax_py_library/device/core/interver/__init__.py,sha256=RKye2D6NawSGdL4YUp_H-Lm
|
|
8
8
|
solax_py_library/device/core/interver/base.py,sha256=2TXHsjigMcIvGDLF3ZD4dw6UDrRRAk9Mq6sdBKRvydc,7191
|
9
9
|
solax_py_library/device/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
solax_py_library/device/types/alarm.py,sha256=kartXs_iRSV9Y3weFSsh9wMXU1_FxHZa6inHThyQCOk,358
|
11
|
+
solax_py_library/device/types/device.py,sha256=oGnuJXPpoOFUc3LgrwCMJSAXKX6VQYEjEd_VmU6zcBA,667
|
11
12
|
solax_py_library/device/types/inverter_config.py,sha256=qCInNPbgsWf6yQjSw59kfQtJJWilMYUhvx_qo5qwRlU,912
|
12
13
|
solax_py_library/device/types/modbus_point.py,sha256=YmXe92gWXL_voVXDJE5zzNzr6dpPs7Ff3ciOAW-LgPs,580
|
13
14
|
solax_py_library/exception.py,sha256=ygAccdTqJctRrdt9bu6-vqZP5KadfKVS_1tjt4KcRn8,257
|
14
15
|
solax_py_library/smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
16
|
solax_py_library/smart_scene/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
solax_py_library/smart_scene/constant/message_entry.py,sha256=
|
17
|
+
solax_py_library/smart_scene/constant/message_entry.py,sha256=oHlNTujzetiIBBjhMgO43Os6pK-guNJ1rY0BVEw9-IA,9653
|
17
18
|
solax_py_library/smart_scene/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
19
|
solax_py_library/smart_scene/core/action/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
20
|
solax_py_library/smart_scene/core/action/base.py,sha256=CCYrlCZeb3CfGZgTWQN673VJmuYNsTbEtdZ4ERUV7RA,395
|
@@ -21,7 +22,7 @@ solax_py_library/smart_scene/core/action/ems_action.py,sha256=sML6qasFoqOktTvEcH
|
|
21
22
|
solax_py_library/smart_scene/core/action/system_action.py,sha256=oGXq3yXS9nKcGjJActjk0R2Wr3AoO9uoyRPyuiM053g,204
|
22
23
|
solax_py_library/smart_scene/core/condition/__init__.py,sha256=1nN-N52Oq7LKdn6ApKGtSZq5fB1qJzJq8BOKOumfQvY,475
|
23
24
|
solax_py_library/smart_scene/core/condition/base.py,sha256=saj7dc0Su2Wi_Lx04cesHFgIPDyQUwvHuDElcaDOIHU,596
|
24
|
-
solax_py_library/smart_scene/core/condition/cabinet_condition.py,sha256=
|
25
|
+
solax_py_library/smart_scene/core/condition/cabinet_condition.py,sha256=HhOmFGs6srnC4oO5h1p3Z09Y9LPeywi1KaL5dG0pJf8,1724
|
25
26
|
solax_py_library/smart_scene/core/condition/date_condition.py,sha256=Xhca6VjoM8Bq-I-dFj1RPLTTzbBL81ORkBnR8D-YqUw,772
|
26
27
|
solax_py_library/smart_scene/core/condition/price_condition.py,sha256=IkgoB5YhpMxgFVkabilcBXtkjsqae01kkjF3tH10CK0,4006
|
27
28
|
solax_py_library/smart_scene/core/condition/system_condition.py,sha256=q5KDQdK6wjEvq0__WwBR4Sk-59yA2aIAgxTf1xjxJQk,1338
|
@@ -34,7 +35,8 @@ solax_py_library/smart_scene/exceptions/smart_scene.py,sha256=69khvoFm1Eki4NBT45
|
|
34
35
|
solax_py_library/smart_scene/exceptions/weather.py,sha256=bJl1VwiIXEpLQ9VjlVrDoTAIMFqVZdRCas7dtR7eAJc,133
|
35
36
|
solax_py_library/smart_scene/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
37
|
solax_py_library/smart_scene/types/action.py,sha256=cYICnxLfLRWFAlOGWpS2HBw-PyaB6TNlNuEmSsme26k,5723
|
37
|
-
solax_py_library/smart_scene/types/condition.py,sha256=
|
38
|
+
solax_py_library/smart_scene/types/condition.py,sha256=K6XVaXLyqQfSLeq7m14vvS0KP-jN-13rmAfC0XfiAQk,9837
|
39
|
+
solax_py_library/smart_scene/types/condition_value.py,sha256=by5R3sVNOJCrghLLaNT54jiTqZYT7YvQQ4q9ovIXkqQ,1242
|
38
40
|
solax_py_library/smart_scene/types/smart_scene_content.py,sha256=C8H17QEicmDBbxN-m550njwaZyUhAL2hUhlLg3Qj1zM,6061
|
39
41
|
solax_py_library/snap_shot/__init__.py,sha256=Ex12q6BCkdU-3OP-f-ehGCetJJWnoZ7KxhEDd_lXh6M,81
|
40
42
|
solax_py_library/snap_shot/constant/__init__.py,sha256=UNfjAlx1wovXc1oH74af9oIe2TljwCCiTzNXzWgtUms,65
|
@@ -50,7 +52,7 @@ solax_py_library/snap_shot/types/__init__.py,sha256=g9ybB88TntvAMGIhLgJ31Xxn26zl
|
|
50
52
|
solax_py_library/snap_shot/types/address.py,sha256=JhyB-t2OnKuE8akKk120sojCNXv4_OlLLuWsl5ChFZ8,1148
|
51
53
|
solax_py_library/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
54
|
solax_py_library/test/test_smart_scene/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
|
-
solax_py_library/test/test_smart_scene/test_condition.py,sha256=
|
55
|
+
solax_py_library/test/test_smart_scene/test_condition.py,sha256=du1vqtwmDFPY__SNqQ-RcDjrDO6e2ZnBjNbPxWpihI4,2209
|
54
56
|
solax_py_library/test/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
57
|
solax_py_library/test/test_utils/test_cloud_client.py,sha256=gOrHGXkFXpFV4kXTnjhmyJGem8VaGKw8OmXyW884oJ0,395
|
56
58
|
solax_py_library/upload/__init__.py,sha256=XhZar7BKaRN0XcdPl4QffWr488L3UWvuq5syT8nX2OU,93
|
@@ -75,6 +77,6 @@ solax_py_library/utils/cloud_client.py,sha256=5dZrc5fzrNFSXqTPZd7oHt-Y9Jj6RCigB7
|
|
75
77
|
solax_py_library/utils/common.py,sha256=bfnZcX9uM-PjJrYAFv1UMmZgt6bGR7MaOd7jRPNHGxw,1238
|
76
78
|
solax_py_library/utils/struct_util.py,sha256=pL6L80GXIHasy1ZDIj89-5BzXW1BWI3TPitH7thGGIE,1577
|
77
79
|
solax_py_library/utils/time_util.py,sha256=bY5kj9dmyOuLEQ6uYGQK7jU7y1RMiHZgevEKnkcQcSU,1461
|
78
|
-
solax_py_library-1.0.0.
|
79
|
-
solax_py_library-1.0.0.
|
80
|
-
solax_py_library-1.0.0.
|
80
|
+
solax_py_library-1.0.0.2602.dist-info/METADATA,sha256=Yic-tstahVn-z-IIHWS3zh1_mzhYYyOno7GkFiTsK1Y,1827
|
81
|
+
solax_py_library-1.0.0.2602.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
82
|
+
solax_py_library-1.0.0.2602.dist-info/RECORD,,
|
File without changes
|