foxesscloud 2.9.8__tar.gz → 2.9.9__tar.gz
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.
- {foxesscloud-2.9.8/src/foxesscloud.egg-info → foxesscloud-2.9.9}/PKG-INFO +7 -2
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/README.md +6 -1
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/pyproject.toml +1 -1
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/src/foxesscloud/openapi.py +56 -5
- {foxesscloud-2.9.8 → foxesscloud-2.9.9/src/foxesscloud.egg-info}/PKG-INFO +7 -2
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/LICENCE +0 -0
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/setup.cfg +0 -0
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/src/foxesscloud/foxesscloud.py +0 -0
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/src/foxesscloud.egg-info/SOURCES.txt +0 -0
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/src/foxesscloud.egg-info/dependency_links.txt +0 -0
- {foxesscloud-2.9.8 → foxesscloud-2.9.9}/src/foxesscloud.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: foxesscloud
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.9
|
|
4
4
|
Summary: library for accessing Fox ESS cloud data using Open API
|
|
5
5
|
Author-email: Tony Matthews <tony@quasair.co.uk>
|
|
6
6
|
Project-URL: Homepage, https://github.com/TonyM1958/FoxESS-Cloud
|
|
@@ -116,7 +116,7 @@ f.get_charge()
|
|
|
116
116
|
f.get_min()
|
|
117
117
|
f.get_peakshaving()
|
|
118
118
|
f.get_flag()
|
|
119
|
-
f.get_schedule()
|
|
119
|
+
f.get_schedule(filter)
|
|
120
120
|
f.get_named_settings(name)
|
|
121
121
|
f.get_heating()
|
|
122
122
|
|
|
@@ -143,6 +143,7 @@ get_flag() returns the current scheduler enable / support / maxsoc flags. By def
|
|
|
143
143
|
+ f.schedule['properties'] details the parameters supported in Mode Scheduler for the current inverter.
|
|
144
144
|
|
|
145
145
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
|
146
|
+
+ filter: 1 = remove Remain Time period (00:00-23:59) from results. 0 = don't remove. Default 1.
|
|
146
147
|
|
|
147
148
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
|
148
149
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
|
@@ -833,6 +834,10 @@ This setting can be:
|
|
|
833
834
|
|
|
834
835
|
# Version Info
|
|
835
836
|
|
|
837
|
+
2.9.9 - 2026/04/03<br>
|
|
838
|
+
Add 'isRemainMode' flag to time periods (not currently processed by Open API).
|
|
839
|
+
Add 'filter' to f.get_schedule() to drop Remain Time period (00:00-23:59) to avoid overlap with other time periods.
|
|
840
|
+
|
|
836
841
|
2.9.8 - 2026/03/22<br>
|
|
837
842
|
** potential breaking changes **
|
|
838
843
|
Update to use Mode Scheduler API v3.
|
|
@@ -102,7 +102,7 @@ f.get_charge()
|
|
|
102
102
|
f.get_min()
|
|
103
103
|
f.get_peakshaving()
|
|
104
104
|
f.get_flag()
|
|
105
|
-
f.get_schedule()
|
|
105
|
+
f.get_schedule(filter)
|
|
106
106
|
f.get_named_settings(name)
|
|
107
107
|
f.get_heating()
|
|
108
108
|
|
|
@@ -129,6 +129,7 @@ get_flag() returns the current scheduler enable / support / maxsoc flags. By def
|
|
|
129
129
|
+ f.schedule['properties'] details the parameters supported in Mode Scheduler for the current inverter.
|
|
130
130
|
|
|
131
131
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
|
132
|
+
+ filter: 1 = remove Remain Time period (00:00-23:59) from results. 0 = don't remove. Default 1.
|
|
132
133
|
|
|
133
134
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
|
134
135
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
|
@@ -819,6 +820,10 @@ This setting can be:
|
|
|
819
820
|
|
|
820
821
|
# Version Info
|
|
821
822
|
|
|
823
|
+
2.9.9 - 2026/04/03<br>
|
|
824
|
+
Add 'isRemainMode' flag to time periods (not currently processed by Open API).
|
|
825
|
+
Add 'filter' to f.get_schedule() to drop Remain Time period (00:00-23:59) to avoid overlap with other time periods.
|
|
826
|
+
|
|
822
827
|
2.9.8 - 2026/03/22<br>
|
|
823
828
|
** potential breaking changes **
|
|
824
829
|
Update to use Mode Scheduler API v3.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
##################################################################################################
|
|
2
2
|
"""
|
|
3
3
|
Module: Fox ESS Cloud using Open API
|
|
4
|
-
Updated:
|
|
4
|
+
Updated: 03 April 2026
|
|
5
5
|
By: Tony Matthews
|
|
6
6
|
"""
|
|
7
7
|
##################################################################################################
|
|
@@ -10,7 +10,7 @@ By: Tony Matthews
|
|
|
10
10
|
# ALL RIGHTS ARE RESERVED © Tony Matthews 2024
|
|
11
11
|
##################################################################################################
|
|
12
12
|
|
|
13
|
-
version = "2.9.
|
|
13
|
+
version = "2.9.9"
|
|
14
14
|
print(f"FoxESS-Cloud Open API version {version}")
|
|
15
15
|
|
|
16
16
|
debug_setting = 1
|
|
@@ -1144,6 +1144,51 @@ def set_work_mode(mode, force = 0):
|
|
|
1144
1144
|
work_mode = mode
|
|
1145
1145
|
return work_mode
|
|
1146
1146
|
|
|
1147
|
+
##################################################################################################
|
|
1148
|
+
# Modbus Commands
|
|
1149
|
+
##################################################################################################
|
|
1150
|
+
|
|
1151
|
+
slave_address = 247
|
|
1152
|
+
modbus_timeout = 10
|
|
1153
|
+
|
|
1154
|
+
def modbus_data(function, register, value=None):
|
|
1155
|
+
return None
|
|
1156
|
+
|
|
1157
|
+
def get_modbus(register, slave=None, function=None, timeout=None):
|
|
1158
|
+
global device_sn, modbus_timeout
|
|
1159
|
+
function = 4 if function is None else function
|
|
1160
|
+
output(f"\nGetting Modbus: {mode}", 1)
|
|
1161
|
+
packet = modbus_data(function, register)
|
|
1162
|
+
body = {'sn': device_sn, 'timeout': modbus_timeout, 'data': packet}
|
|
1163
|
+
response = signed_post(path="/op/v0/module/modbus/commands", body=body)
|
|
1164
|
+
if response.status_code != 200:
|
|
1165
|
+
output(f"** get_modbus() got response code {response.status_code}: {response.reason}")
|
|
1166
|
+
return None
|
|
1167
|
+
errno = response.json().get('errno')
|
|
1168
|
+
if errno != 0:
|
|
1169
|
+
output(f"** get_modbus(), {errno_message(response)}")
|
|
1170
|
+
return None
|
|
1171
|
+
result = response.json().get('result')
|
|
1172
|
+
return result
|
|
1173
|
+
|
|
1174
|
+
def set_modbus(register, value, slave=None, function=None, timeout=None):
|
|
1175
|
+
global device_sn, modbus_timeout
|
|
1176
|
+
function = 16 if type(value) is list else 6
|
|
1177
|
+
output(f"\nSetting Modbus: {mode}", 1)
|
|
1178
|
+
packet = modbus_data(function, register, value)
|
|
1179
|
+
body = {'sn': device_sn, 'timeout': modbus_timeout, 'data': packet}
|
|
1180
|
+
setting_delay()
|
|
1181
|
+
response = signed_post(path="/op/v0/module/modbus/commands", body=body)
|
|
1182
|
+
if response.status_code != 200:
|
|
1183
|
+
output(f"** get_modbus() got response code {response.status_code}: {response.reason}")
|
|
1184
|
+
return None
|
|
1185
|
+
errno = response.json().get('errno')
|
|
1186
|
+
if errno != 0:
|
|
1187
|
+
output(f"** get_modbus(), {errno_message(response)}")
|
|
1188
|
+
return None
|
|
1189
|
+
result = response.json().get('result')
|
|
1190
|
+
return result
|
|
1191
|
+
|
|
1147
1192
|
|
|
1148
1193
|
##################################################################################################
|
|
1149
1194
|
# get flag
|
|
@@ -1197,7 +1242,7 @@ def get_flag():
|
|
|
1197
1242
|
##################################################################################################
|
|
1198
1243
|
|
|
1199
1244
|
# get the current schedule
|
|
1200
|
-
def get_schedule():
|
|
1245
|
+
def get_schedule(filter=1):
|
|
1201
1246
|
global device_sn, schedule, debug_setting, work_modes
|
|
1202
1247
|
if get_flag() is None:
|
|
1203
1248
|
return None
|
|
@@ -1222,7 +1267,10 @@ def get_schedule():
|
|
|
1222
1267
|
# remove invalid work mode from periods
|
|
1223
1268
|
for g in result['groups']:
|
|
1224
1269
|
if g['workMode'] in work_modes:
|
|
1225
|
-
|
|
1270
|
+
remain_mode = g['startHour'] == 0 and g['startMinute'] == 0 and g['endHour'] == 23 and g['endMinute'] == 59
|
|
1271
|
+
g['isRemainMode'] = remain_mode
|
|
1272
|
+
if not remain_mode or filter == 0:
|
|
1273
|
+
schedule['periods'].append(g)
|
|
1226
1274
|
return schedule
|
|
1227
1275
|
|
|
1228
1276
|
# build strategy using current schedule
|
|
@@ -1276,6 +1324,7 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
|
1276
1324
|
if start is None or end is None or start >= end:
|
|
1277
1325
|
output(f"set_period(): ** invalid period times: {hours_time(start)}-{hours_time(end)}")
|
|
1278
1326
|
return None
|
|
1327
|
+
remain_mode = start == 0 and end == 24
|
|
1279
1328
|
end = round_time(end - 1/60)
|
|
1280
1329
|
mode = 'SelfUse' if mode is None else mode
|
|
1281
1330
|
if mode not in work_modes:
|
|
@@ -1301,10 +1350,12 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
|
1301
1350
|
s += f", importLimit {int(import_limit)}W" if import_limit is not None else ""
|
|
1302
1351
|
s += f", pvLimit {int(pv_limit)}W" if pv_limit is not None else ""
|
|
1303
1352
|
s += f", {price:.2f}p/kWh" if price is not None else ""
|
|
1353
|
+
s += f", Remain Mode" if remain_mode else ""
|
|
1304
1354
|
output(s, 1)
|
|
1305
1355
|
start_hour, start_minute = split_hours(start)
|
|
1306
1356
|
end_hour, end_minute = split_hours(end)
|
|
1307
|
-
period = {'startHour': start_hour, 'startMinute': start_minute, 'endHour': end_hour, 'endMinute': end_minute, 'workMode': mode, '
|
|
1357
|
+
period = {'startHour': start_hour, 'startMinute': start_minute, 'endHour': end_hour, 'endMinute': end_minute, 'workMode': mode, 'isRemainMode': remain_mode
|
|
1358
|
+
, 'extraParam': {'minSocOnGrid': min_soc}}
|
|
1308
1359
|
if max_soc is not None:
|
|
1309
1360
|
period['extraParam']['maxSoc'] = max_soc
|
|
1310
1361
|
if fdsoc is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: foxesscloud
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.9
|
|
4
4
|
Summary: library for accessing Fox ESS cloud data using Open API
|
|
5
5
|
Author-email: Tony Matthews <tony@quasair.co.uk>
|
|
6
6
|
Project-URL: Homepage, https://github.com/TonyM1958/FoxESS-Cloud
|
|
@@ -116,7 +116,7 @@ f.get_charge()
|
|
|
116
116
|
f.get_min()
|
|
117
117
|
f.get_peakshaving()
|
|
118
118
|
f.get_flag()
|
|
119
|
-
f.get_schedule()
|
|
119
|
+
f.get_schedule(filter)
|
|
120
120
|
f.get_named_settings(name)
|
|
121
121
|
f.get_heating()
|
|
122
122
|
|
|
@@ -143,6 +143,7 @@ get_flag() returns the current scheduler enable / support / maxsoc flags. By def
|
|
|
143
143
|
+ f.schedule['properties'] details the parameters supported in Mode Scheduler for the current inverter.
|
|
144
144
|
|
|
145
145
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
|
146
|
+
+ filter: 1 = remove Remain Time period (00:00-23:59) from results. 0 = don't remove. Default 1.
|
|
146
147
|
|
|
147
148
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
|
148
149
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
|
@@ -833,6 +834,10 @@ This setting can be:
|
|
|
833
834
|
|
|
834
835
|
# Version Info
|
|
835
836
|
|
|
837
|
+
2.9.9 - 2026/04/03<br>
|
|
838
|
+
Add 'isRemainMode' flag to time periods (not currently processed by Open API).
|
|
839
|
+
Add 'filter' to f.get_schedule() to drop Remain Time period (00:00-23:59) to avoid overlap with other time periods.
|
|
840
|
+
|
|
836
841
|
2.9.8 - 2026/03/22<br>
|
|
837
842
|
** potential breaking changes **
|
|
838
843
|
Update to use Mode Scheduler API v3.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|