solax-py-library 1.0.0.2502__py3-none-any.whl → 1.0.0.2504__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.
Files changed (23) hide show
  1. solax_py_library/device/constant/cabinet.py +2 -0
  2. solax_py_library/device/types/alarm.py +16 -0
  3. solax_py_library/smart_scene/constant/message_entry.py +174 -336
  4. solax_py_library/smart_scene/core/action/base.py +9 -0
  5. solax_py_library/smart_scene/core/action/ems_action.py +19 -0
  6. solax_py_library/smart_scene/core/action/system_action.py +241 -0
  7. solax_py_library/smart_scene/core/condition/base.py +8 -7
  8. solax_py_library/smart_scene/core/condition/cabinet_condition.py +11 -77
  9. solax_py_library/smart_scene/core/condition/date_condition.py +9 -9
  10. solax_py_library/smart_scene/core/condition/price_condition.py +27 -33
  11. solax_py_library/smart_scene/core/condition/system_condition.py +14 -21
  12. solax_py_library/smart_scene/core/condition/weather_condition.py +13 -22
  13. solax_py_library/smart_scene/core/service/__init__.py +0 -0
  14. solax_py_library/smart_scene/core/service/smart_scene_service.py +411 -0
  15. solax_py_library/smart_scene/types/action.py +3 -3
  16. solax_py_library/smart_scene/types/condition.py +32 -26
  17. solax_py_library/smart_scene/types/smart_scene_content.py +9 -9
  18. solax_py_library/test/test_utils/test_cloud_client.py +1 -1
  19. solax_py_library/utils/cloud_client.py +2 -2
  20. solax_py_library/utils/time_util.py +33 -0
  21. {solax_py_library-1.0.0.2502.dist-info → solax_py_library-1.0.0.2504.dist-info}/METADATA +1 -1
  22. {solax_py_library-1.0.0.2502.dist-info → solax_py_library-1.0.0.2504.dist-info}/RECORD +23 -16
  23. {solax_py_library-1.0.0.2502.dist-info → solax_py_library-1.0.0.2504.dist-info}/WHEEL +0 -0
@@ -0,0 +1,241 @@
1
+ # from solax_py_library.smart_scene.core.action.base import BaseAction
2
+ # from solax_py_library.smart_scene.types.action import SystemActionType
3
+ # from solax_py_library.smart_scene.types.condition import SystemConditionItemData
4
+ #
5
+ #
6
+ # class SystemAction(BaseAction):
7
+ # def __init__(self, smart_scene_service, app_log):
8
+ # super().__init__(smart_scene_service)
9
+ # self.log = app_log
10
+ # self.do_func = self.do_system_action
11
+ # self.cabinet_type = None
12
+ #
13
+ # def do_system_action(self, scene_id, data: SystemConditionItemData):
14
+ # child_data = data.childData
15
+ # child_type = data.childType
16
+ # data = child_data.data
17
+ # if self.cabinet_type is None:
18
+ # self.cabinet_type = self.smart_scene_service.get_cabinet_type()
19
+ # if child_type == SystemActionType.systemSwitch:
20
+ # return self.system_switch(data[0], scene_id)
21
+ # elif child_type == SystemActionType.exportControl:
22
+ # return self.export_control(data, scene_id)
23
+ # elif child_type == SystemActionType.importControl:
24
+ # return self.import_control(data, scene_id)
25
+ # elif child_type == SystemActionType.workMode:
26
+ # return self.work_mode(data, scene_id)
27
+ # return False
28
+ #
29
+ #
30
+ # class SystemSwitchAction(SystemAction):
31
+ # def system_switch(self, value, scene_id) -> bool:
32
+ # """系统开关机"""
33
+ # if value not in [0, 1]:
34
+ # value = 1
35
+ # if self.cabinet_type in ["TRENE"]:
36
+ # self.ems_tcp_service.set_trene_switch(value)
37
+ # return True
38
+ # else:
39
+ # master_sn = self.device_service.get_master_inv_by_device()
40
+ # # 如果为AELIO,则只需要操控主机
41
+ # if master_sn:
42
+ # data = {"sn": master_sn, "switch": value}
43
+ # self.log.info(f"执行: 系统开关机, data: {data}")
44
+ # t = threading.Thread(
45
+ # target=self.smart_scene_service.request_local_server,
46
+ # args=("setSystemSwitch", data, scene_id),
47
+ # daemon=True,
48
+ # )
49
+ # t.start()
50
+ # return True
51
+ #
52
+ #
53
+ # class ExportControlAction(SystemAction):
54
+ # def export_control(self, value, scene_id) -> bool:
55
+ # """零输出控制"""
56
+ # if len(value) != 4:
57
+ # value.extend([1, 0, 1])
58
+ # data = {
59
+ # "isEnable": value[0],
60
+ # "controlMode": value[1],
61
+ # "exportValue": value[2],
62
+ # "unitType": value[3],
63
+ # }
64
+ # self.log.info(f"执行: 馈网控制, data: {data}")
65
+ # ret = self.smart_scene_service.request_local_server(
66
+ # "editOutputControl", data, scene_id
67
+ # )
68
+ # if not ret or ret["success"] is False:
69
+ # return False
70
+ # return True
71
+ #
72
+ #
73
+ # class ImportControlAction(SystemAction):
74
+ # def import_control(self, value, scene_id) -> bool:
75
+ # """需量控制"""
76
+ # if self.cabinet_type in ["TRENE"]:
77
+ # if len(value) != 3:
78
+ # value.extend([1, 0])
79
+ # data = {
80
+ # "isAllowDischarge": value[1],
81
+ # "demandLimitValue": value[2],
82
+ # "isEnable": value[0],
83
+ # }
84
+ # else:
85
+ # if len(value) != 2:
86
+ # value.append(0)
87
+ # data = {
88
+ # "isAllowDischarge": 1,
89
+ # "demandLimitValue": value[1],
90
+ # "isEnable": value[0],
91
+ # }
92
+ # self.log.info(f"执行: 需量控制, data: {data}")
93
+ # ret = self.smart_scene_service.request_local_server(
94
+ # "editDemandControl", data, scene_id
95
+ # )
96
+ # if not ret or ret["success"] is False:
97
+ # return False
98
+ # return True
99
+ #
100
+ #
101
+ # class WorkModeAction(SystemAction):
102
+ # def work_mode(self, value, scene_id) -> bool:
103
+ # # 0: self use; 1: 并网优先; 2: 备用模式; 3: 手动; 4: 削峰填谷 5: TOU(暂不用); 16: VPP
104
+ # if value[0] not in [0, 1, 2, 3, 4, 16]:
105
+ # return False
106
+ # data = None
107
+ # if self.cabinet_type in ["AELIO"]:
108
+ # if value[0] in [0, 1, 2, 3, 4]:
109
+ # data = {"useMode": value[0]}
110
+ # elif self.cabinet_type in ["TRENE"]:
111
+ # if value[0] in [0, 1, 3, 4]:
112
+ # data = {"useMode": value[0]}
113
+ # else:
114
+ # return False
115
+ # if data is not None: # 普通模式
116
+ # self.log.info(f"普通模式控制 data: {data}")
117
+ # # 手动模式
118
+ # if data["useMode"] == 3:
119
+ # if value[1] == 5:
120
+ # value.extend([0, 10])
121
+ # self.smart_scene_service.set_manual_mode(
122
+ # value[1], value[2], value[3], self.cabinet_type
123
+ # )
124
+ # else:
125
+ # self.smart_scene_service.request_local_server(
126
+ # "setAelioUseMode", data, scene_id
127
+ # )
128
+ # else: # VPP模式
129
+ # if self.cabinet_type in ["AELIO"]:
130
+ # if value[1] == 1:
131
+ # reg_value_list = [1]
132
+ # # 有功功率
133
+ # reg_value_list.extend(
134
+ # self.smart_scene_service.struct_transform(
135
+ # value[2] * 1000, "int32", "little"
136
+ # )
137
+ # )
138
+ # # 无功功率
139
+ # reg_value_list.extend(
140
+ # self.smart_scene_service.struct_transform(
141
+ # value[3] * 1000, "int32", "little"
142
+ # )
143
+ # )
144
+ # # 持续时间35秒, 控制超时 35s,控制类型为set
145
+ # reg_value_list.extend([35, 35, 1])
146
+ # elif value[1] == 2:
147
+ # reg_value_list = [2, 1]
148
+ # # 能量目标
149
+ # reg_value_list.extend(
150
+ # self.smart_scene_service.struct_transform(
151
+ # value[2] * 1000, "uint32", "little"
152
+ # )
153
+ # )
154
+ # # 功率目标
155
+ # reg_value_list.extend(
156
+ # self.smart_scene_service.struct_transform(
157
+ # value[3] * 1000, "int32", "little"
158
+ # )
159
+ # )
160
+ # # 控制超时 35s
161
+ # reg_value_list.extend([35])
162
+ # elif value[1] == 3:
163
+ # # 控制类型为set,SOC:value[2]
164
+ # reg_value_list = [3, 1, value[2]]
165
+ # # 充放电功率目标
166
+ # reg_value_list.extend(
167
+ # self.smart_scene_service.struct_transform(
168
+ # value[3] * 1000, "int32", "little"
169
+ # )
170
+ # )
171
+ # # 控制超时 35s
172
+ # reg_value_list.extend([35])
173
+ # elif value[1] == 4:
174
+ # reg_value_list = [4]
175
+ # # 电池功率目标
176
+ # reg_value_list.extend(
177
+ # self.smart_scene_service.struct_transform(
178
+ # value[2] * 1000, "int32", "little"
179
+ # )
180
+ # )
181
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
182
+ # reg_value_list.extend([35, 0xA0])
183
+ # elif value[1] == 5:
184
+ # reg_value_list = [5]
185
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
186
+ # reg_value_list.extend([35, 0xA0])
187
+ # elif value[1] == 6:
188
+ # reg_value_list = [6]
189
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
190
+ # reg_value_list.extend([35, 0xA0])
191
+ # elif value[1] == 7:
192
+ # reg_value_list = [7]
193
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
194
+ # reg_value_list.extend([35, 0xA0])
195
+ # elif value[1] == 8:
196
+ # # 控制类型为set,
197
+ # reg_value_list = [8, 1]
198
+ # # PV功率限制
199
+ # reg_value_list.extend(
200
+ # self.smart_scene_service.struct_transform(
201
+ # value[2] * 1000, "uint32", "little"
202
+ # )
203
+ # )
204
+ # # 电池功率限制
205
+ # reg_value_list.extend(
206
+ # self.smart_scene_service.struct_transform(
207
+ # value[3] * 1000, "int32", "little"
208
+ # )
209
+ # )
210
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
211
+ # reg_value_list.extend([35, 0xA0])
212
+ # elif value[1] == 9:
213
+ # # 控制类型为set,
214
+ # reg_value_list = [9, 1]
215
+ # # PV功率限制
216
+ # reg_value_list.extend(
217
+ # self.smart_scene_service.struct_transform(
218
+ # value[2] * 1000, "uint32", "little"
219
+ # )
220
+ # )
221
+ # # 电池功率限制
222
+ # reg_value_list.extend(
223
+ # self.smart_scene_service.struct_transform(
224
+ # value[3] * 1000, "int32", "little"
225
+ # )
226
+ # )
227
+ # # 控制超时 35s, # 远程控制超时后需设备执行的模式 0xA0 关闭VPP,0xA1 默认的VPP模式
228
+ # reg_value_list.extend([value[4], 35, 0xA0])
229
+ # else:
230
+ # reg_value_list = []
231
+ # func_name = PCSOperateFunctionName.SET_AELIO_VPP_MODE
232
+ # channel = options.REDIS_WRITE_SERIAL_DEVICE
233
+ # future_data = {}
234
+ # future_data["func_name"] = func_name
235
+ # future_data["operationMode"] = Enumeration.SINGLE_DEVICE_MODE
236
+ # future_data["data"] = {"value_list": reg_value_list}
237
+ # app_log.info(f"VPP模式控制 data: {future_data}")
238
+ # self.smart_scene_service.request_local_redis(
239
+ # channel, json.dumps(future_data)
240
+ # )
241
+ # return True
@@ -1,12 +1,13 @@
1
1
  class BaseCondition(object):
2
- def __init__(self):
3
- # 子条件类型
4
- self.child_type_list = []
5
- # 各子条件的值
2
+ def __init__(self, update_value_function, **kwargs):
6
3
  self.value = {}
7
- # 判断是否满足条件的子条件-判断函数的映射
8
- self.meet_func_dict = {}
4
+ if callable(update_value_function):
5
+ raise ValueError("update_value_function must be callable")
6
+ self.update_value_function = update_value_function
9
7
 
10
8
  def update_value(self):
11
- """更新条件值"""
9
+ self.update_value_function()
10
+ print(self.value)
11
+
12
+ def meet_func(self, data, ctx):
12
13
  ...
@@ -1,11 +1,16 @@
1
+ from collections import defaultdict
2
+
3
+ from solax_py_library.smart_scene.core.condition.base import BaseCondition
4
+ from solax_py_library.smart_scene.types.condition import CabinetConditionItemData, CabinetConditionType
5
+ from solax_py_library.device.types.alarm import AlarmLevel
6
+
1
7
 
2
8
  class CabinetCondition(BaseCondition):
3
- def __init__(self, smart_scene_service):
4
- super().__init__(smart_scene_service)
5
- self.type = IF_ELE_TYPE
9
+ def __init__(self, update_value_function, **kwargs):
10
+ super().__init__(update_value_function, **kwargs)
6
11
  self.value = defaultdict(
7
12
  lambda: {
8
- "soc": None,
13
+ "soc": 0,
9
14
  "alarm_level": {
10
15
  AlarmLevel.EMERGENCY: False,
11
16
  AlarmLevel.NORMAL: False,
@@ -13,78 +18,8 @@ class CabinetCondition(BaseCondition):
13
18
  },
14
19
  }
15
20
  )
16
- self.meet_func = self.meet_cabinet_condition
17
-
18
- def update_value(self):
19
- # 查询实时数据
20
- cabinet_sns = [c.SN for c in self.db_service.get_all_cabinet()]
21
- self._update_cabinet_soc(cabinet_sns)
22
- self._update_cabinet_alarm(cabinet_sns)
23
-
24
- def _update_cabinet_alarm(self, cabinet_sns):
25
- all_alarm_code = self.redis_service.get_all_device_alarm_code()
26
- if not all_alarm_code:
27
- return
28
-
29
- cabinet_sn_pcs_sn_map = defaultdict(list)
30
- for pcs in self.db_service.get_pcs_by_cabinet(cabinet_sns):
31
- cabinet_sn_pcs_sn_map[pcs.cabinetSN].append(pcs.SN)
32
-
33
- cabinet_sn_bms_sn_map = defaultdict(list)
34
- for bms in self.db_service.get_bms_by_cabinet(cabinet_sns):
35
- cabinet_sn_bms_sn_map[bms.cabinetSN].append(bms.SN)
36
-
37
- cabinet_sn_io_sn_map = defaultdict(list)
38
- for io in self.db_service.get_io_by_cabinet(cabinet_sns):
39
- cabinet_sn_io_sn_map[io.cabinetSN].append(io.SN)
40
-
41
- for sn in cabinet_sns:
42
- cabinet_alarm = set(all_alarm_code.get(sn, []))
43
- pcs_alarm = set()
44
- for pcs_sn in cabinet_sn_pcs_sn_map.get(sn, []):
45
- pcs_alarm.update(all_alarm_code.get(pcs_sn, []))
46
-
47
- bms_alarm = set()
48
- for bms_sn in cabinet_sn_bms_sn_map.get(sn, []):
49
- bms_alarm.update(all_alarm_code.get(bms_sn, []))
50
-
51
- io_alarm = set()
52
- for io_sn in cabinet_sn_io_sn_map.get(sn, []):
53
- io_alarm.update(all_alarm_code.get(io_sn, []))
54
-
55
- self.value[sn]["alarm_level"][AlarmLevel.TIPS] = any(
56
- [
57
- bool(cabinet_alarm & set(AlarmPointInfo.CABINET_TIPS_ALARM_DATA)),
58
- bool(pcs_alarm & set(AlarmPointInfo.PCS_TIPS_ALARM_DATA)),
59
- bool(bms_alarm & set(AlarmPointInfo.BMS_TIPS_ALARM_DATA)),
60
- bool(io_alarm & set(AlarmPointInfo.IO_TIPS_ALARM_DATA)),
61
- ]
62
- )
63
- self.value[sn]["alarm_level"][AlarmLevel.NORMAL] = any(
64
- [
65
- bool(cabinet_alarm & set(AlarmPointInfo.CABINET_NORMAL_ALARM_DATA)),
66
- bool(pcs_alarm & set(AlarmPointInfo.PCS_NORMAL_ALARM_DATA)),
67
- bool(bms_alarm & set(AlarmPointInfo.BMS_NORMAL_ALARM_DATA)),
68
- bool(io_alarm & set(AlarmPointInfo.IO_NORMAL_ALARM_DATA)),
69
- ]
70
- )
71
- self.value[sn]["alarm_level"][AlarmLevel.EMERGENCY] = any(
72
- [
73
- bool(
74
- cabinet_alarm & set(AlarmPointInfo.CABINET_EMERGENCY_ALARM_DATA)
75
- ),
76
- bool(pcs_alarm & set(AlarmPointInfo.PCS_EMERGENCY_ALARM_DATA)),
77
- bool(bms_alarm & set(AlarmPointInfo.BMS_EMERGENCY_ALARM_DATA)),
78
- bool(io_alarm & set(AlarmPointInfo.IO_EMERGENCY_ALARM_DATA)),
79
- ]
80
- )
81
-
82
- def _update_cabinet_soc(self, cabinet_sns):
83
- for sn in cabinet_sns or []:
84
- result = self.smart_scene_service.redis_service.get_bms_current_data(sn)
85
- self.value[sn]["soc"] = result[14] if result else 0
86
21
 
87
- def meet_cabinet_condition(self, data: CabinetConditionItemData, ctx):
22
+ def meet_func(self, data: CabinetConditionItemData, ctx):
88
23
  if not self.value:
89
24
  return False
90
25
  cabinet = ctx["cabinet"] or []
@@ -92,8 +27,7 @@ class CabinetCondition(BaseCondition):
92
27
  if data.childType == CabinetConditionType.cabinetSoc:
93
28
  if self.value[cabinet_sn]["soc"] is None:
94
29
  return False
95
- if self.smart_scene_service.compare_the_magnitudes(
96
- data.childData.function,
30
+ if data.childData.function.function()(
97
31
  compare_value=self.value[cabinet_sn]["soc"],
98
32
  base_value=data.childData.data[0],
99
33
  ):
@@ -1,15 +1,17 @@
1
1
  from datetime import datetime
2
2
 
3
3
  from solax_py_library.smart_scene.core.condition.base import BaseCondition
4
- from solax_py_library.smart_scene.types.condition import DateConditionItemData, DateConditionType
4
+ from solax_py_library.smart_scene.types.condition import (
5
+ DateConditionItemData,
6
+ DateConditionType,
7
+ )
5
8
 
6
9
 
7
10
  class DateCondition(BaseCondition):
8
- def __init__(self):
9
- super().__init__()
10
- self.value = {}
11
+ def __init__(self, update_value_function, **kwargs):
12
+ super().__init__(update_value_function, **kwargs)
11
13
 
12
- def update_value(self):
14
+ def _update_value(self):
13
15
  """获取time 类型需要的数据"""
14
16
  now = datetime.now()
15
17
  self.hour = now.hour
@@ -17,10 +19,8 @@ class DateCondition(BaseCondition):
17
19
 
18
20
  def meet_func(self, data: DateConditionItemData, ctx):
19
21
  if data.childType == DateConditionType.time:
20
- """判断是否满足日期时间类条件"""
21
22
  date = data.childData.data[0]
22
- hour = int(date.split(":")[0])
23
- minute = int(date.split(":")[1])
24
- if hour == self.hour and minute == self.minute:
23
+ hour, minute = date.split(":")
24
+ if int(hour) == self.hour and int(minute) == self.minute:
25
25
  return True
26
26
  return False
@@ -1,34 +1,31 @@
1
1
  from datetime import datetime
2
2
 
3
3
  from solax_py_library.smart_scene.core.condition.base import BaseCondition
4
- from solax_py_library.smart_scene.types.condition import PriceConditionItemData, PriceConditionType, SmartSceneUnit
4
+ from solax_py_library.smart_scene.types.condition import (
5
+ PriceConditionItemData,
6
+ PriceConditionType,
7
+ SmartSceneUnit,
8
+ ConditionFunc,
9
+ )
10
+ from solax_py_library.utils.time_util import (
11
+ trans_str_time_to_index,
12
+ get_highest_or_lowest_value,
13
+ )
5
14
 
6
15
 
7
16
  class ElePriceCondition(BaseCondition):
8
- def __init__(self):
9
- super().__init__()
10
- self.buy = True
11
- self.value = {}
17
+ def __init__(self, update_value_function, **kwargs):
18
+ super().__init__(update_value_function, **kwargs)
19
+ self.buy = None
12
20
  self.unit = None
13
21
 
14
- def update_value(self):
15
- """获取电价 类型需要的数据"""
16
- ele_info = self.smart_scene_service.get_electrovalence_data()
17
- if self.buy:
18
- self.value = ele_info.get("buy", [])
19
- else:
20
- self.value = ele_info.get("sell", [])
21
- self.unit = ele_info.get("ele_unit", " ")
22
-
23
- def meet_func_price(self, function_value, data_value, index) -> bool:
22
+ def meet_func_price(self, function_value: ConditionFunc, data_value, index) -> bool:
24
23
  """电价条件的判定"""
25
24
  if index < 0 or index > len(self.value):
26
25
  return False
27
26
  if self.value[index] is None:
28
27
  return False
29
- return self.smart_scene_service.compare_the_magnitudes(
30
- function_value, self.value[index], data_value[0]
31
- )
28
+ return function_value.function()(self.value[index], data_value[0])
32
29
 
33
30
  def meet_func_highest_price(self, data_value, index) -> bool:
34
31
  value, unit = data_value
@@ -56,16 +53,13 @@ class ElePriceCondition(BaseCondition):
56
53
  else:
57
54
  return False
58
55
 
59
- def meet_func_highest_or_lowest_hours(self, data_value, index, func) -> bool:
60
- sort_index, start_index = self.smart_scene_service.get_highest_or_lowest_price(
61
- data_value[0], data_value[1], data_value[2], self.value, func=func
56
+ def meet_func_highest_or_lowest_hours(self, data_value, index, reverse) -> bool:
57
+ sort_index, start_index = get_highest_or_lowest_value(
58
+ data_value[0], data_value[1], data_value[2], self.value, reverse=reverse
62
59
  )
63
- if not sort_index:
64
- return False
65
- if index - start_index in sort_index:
60
+ if sort_index and index - start_index in sort_index:
66
61
  return True
67
- else:
68
- return False
62
+ return False
69
63
 
70
64
  def meet_func(self, data: PriceConditionItemData, ctx):
71
65
  if not self.value:
@@ -75,7 +69,7 @@ class ElePriceCondition(BaseCondition):
75
69
  child_type = data.childType
76
70
  data_value = child_data.data
77
71
  now_time = datetime.strftime(datetime.now(), "%H:%M")
78
- index = self.smart_scene_service.trans_str_time_to_index(now_time)
72
+ index = trans_str_time_to_index(now_time)
79
73
  if child_type == PriceConditionType.price:
80
74
  return self.meet_func_price(child_data.function, data_value, index)
81
75
  elif child_type == PriceConditionType.lowerPrice:
@@ -84,22 +78,22 @@ class ElePriceCondition(BaseCondition):
84
78
  return self.meet_func_lowest_price(data_value, index)
85
79
  elif child_type == PriceConditionType.expensiveHours:
86
80
  return self.meet_func_highest_or_lowest_hours(
87
- data_value, index, "expensive_hours"
81
+ data_value, index, reverse=True
88
82
  )
89
83
  elif child_type == PriceConditionType.cheapestHours:
90
84
  return self.meet_func_highest_or_lowest_hours(
91
- data_value, index, "cheapest_hours"
85
+ data_value, index, reverse=False
92
86
  )
93
87
  return False
94
88
 
95
89
 
96
90
  class EleSellPriceCondition(ElePriceCondition):
97
- def __init__(self):
98
- super().__init__()
91
+ def __init__(self, update_value_function, **kwargs):
92
+ super().__init__(update_value_function, **kwargs)
99
93
  self.buy = False
100
94
 
101
95
 
102
96
  class ElsBuyPriceCondition(ElePriceCondition):
103
- def __init__(self):
104
- super().__init__()
97
+ def __init__(self, update_value_function, **kwargs):
98
+ super().__init__(update_value_function, **kwargs)
105
99
  self.buy = True
@@ -1,18 +1,15 @@
1
+ from solax_py_library.smart_scene.core.condition.base import BaseCondition
2
+ from solax_py_library.smart_scene.types.condition import (
3
+ SystemConditionItemData,
4
+ SystemConditionType,
5
+ )
1
6
 
2
7
 
3
8
  class SystemCondition(BaseCondition):
4
- def __init__(self, smart_scene_service):
5
- super().__init__(smart_scene_service)
6
- self.type = IF_ELE_TYPE
7
- self.value = {}
8
- self.meet_func = self.meet_system_condition
9
-
10
- def update_value(self):
11
- overview_statistic_data = (
12
- self.smart_scene_service.redis_service.get_overview_statistic_data()
13
- )
14
- self.value["grid_active_power"] = overview_statistic_data[8]
15
- self.value["system_soc"] = overview_statistic_data[16]
9
+ def __init__(self, update_value_function, **kwargs):
10
+ super().__init__(update_value_function, **kwargs)
11
+ self.grid_active_power = None
12
+ self.system_soc = None
16
13
 
17
14
  def meet_system_condition(self, data: SystemConditionItemData, ctx):
18
15
  if not self.value:
@@ -20,22 +17,18 @@ class SystemCondition(BaseCondition):
20
17
  child_data = data.childData
21
18
  function_value = child_data.function
22
19
  compare_value = None
23
- app_log.info(self.value)
24
20
  if data.childType == SystemConditionType.systemExportPower:
25
- compare_value = self.value["grid_active_power"]
21
+ compare_value = self.grid_active_power
26
22
  if compare_value < 0:
27
23
  return False
28
24
  elif data.childType == SystemConditionType.systemImportPower:
29
- compare_value = self.value["grid_active_power"]
25
+ compare_value = self.grid_active_power
30
26
  if compare_value > 0:
31
27
  return False
32
28
  elif data.childType == SystemConditionType.systemSoc:
33
- compare_value = self.value["system_soc"]
29
+ compare_value = self.system_soc
34
30
  if compare_value is None:
35
31
  return False
36
- return self.smart_scene_service.compare_the_magnitudes(
37
- function_value,
38
- compare_value=abs(compare_value),
39
- base_value=child_data.data[0],
32
+ return function_value.function()(
33
+ compare_value=abs(compare_value), base_value=child_data.data[0]
40
34
  )
41
-
@@ -1,18 +1,14 @@
1
+ from solax_py_library.smart_scene.core.condition.base import BaseCondition
2
+ from solax_py_library.smart_scene.types.condition import (
3
+ WeatherConditionItemData,
4
+ WeatherConditionType,
5
+ )
6
+ from solax_py_library.utils.time_util import get_rounded_times
1
7
 
2
- class WeatherCondition(BaseCondition):
3
- def __init__(self, smart_scene_service):
4
- super().__init__(smart_scene_service)
5
- self.type = IF_ELE_TYPE
6
- self.buy = True
7
- self.child_type_list = ["irradiance", "temperature"]
8
- self.value = {}
9
- self.unit = ""
10
- self.meet_func = self.meet_weather_condition
11
8
 
12
- def update_value(
13
- self,
14
- ):
15
- self.value = self.smart_scene_service.get_weather_data_from_redis()
9
+ class WeatherCondition(BaseCondition):
10
+ def __init__(self, update_value_function, **kwargs):
11
+ super().__init__(update_value_function, **kwargs)
16
12
 
17
13
  def meet_weather_condition(self, data: WeatherConditionItemData, ctx):
18
14
  if not self.value:
@@ -21,21 +17,16 @@ class WeatherCondition(BaseCondition):
21
17
  child_type = data.childType
22
18
  function_value = child_data.function
23
19
  data_value = child_data.data
24
- nearest_time, right_time = self.smart_scene_service.get_rounded_times()
20
+ nearest_time, right_time = get_rounded_times()
25
21
  if nearest_time not in self.value["timeList"]:
26
22
  time_now = right_time
27
23
  else:
28
24
  time_now = nearest_time
29
25
  index = self.value["timeList"].index(time_now)
30
- app_log.info(
31
- f"最近时间点为: {nearest_time}, 右侧时间点为: {right_time}, 数组索引为: {index}"
32
- )
33
26
  if child_type == WeatherConditionType.irradiance:
34
27
  return self.meet_func_irradiance(function_value, data_value, index)
35
28
  elif child_type == WeatherConditionType.temperature:
36
- app_log.info(f"当前实际值为: {self.value[child_type]['valueList'][index]}")
37
- return self.smart_scene_service.compare_the_magnitudes(
38
- function_value,
29
+ return function_value.function()(
39
30
  self.value[child_type]["valueList"][index],
40
31
  data_value[0],
41
32
  )
@@ -62,6 +53,6 @@ class WeatherCondition(BaseCondition):
62
53
  if not meet_flag:
63
54
  return False
64
55
  # 2. 再判断当前太阳辐照度
65
- return self.smart_scene_service.compare_the_magnitudes(
66
- function_value, self.value["irradiance"]["valueList"][index], irradiance
56
+ return function_value.function()(
57
+ self.value["irradiance"]["valueList"][index], irradiance
67
58
  )
File without changes