foxesscloud 2.8.6__tar.gz → 2.8.7__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.8.6/src/foxesscloud.egg-info → foxesscloud-2.8.7}/PKG-INFO +17 -17
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/README.md +16 -16
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/pyproject.toml +1 -1
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/src/foxesscloud/foxesscloud.py +12 -6
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/src/foxesscloud/openapi.py +39 -10
- {foxesscloud-2.8.6 → foxesscloud-2.8.7/src/foxesscloud.egg-info}/PKG-INFO +17 -17
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/LICENCE +0 -0
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/setup.cfg +0 -0
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/src/foxesscloud.egg-info/SOURCES.txt +0 -0
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/src/foxesscloud.egg-info/dependency_links.txt +0 -0
- {foxesscloud-2.8.6 → foxesscloud-2.8.7}/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.8.
|
3
|
+
Version: 2.8.7
|
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
|
@@ -63,13 +63,14 @@ For example, replace _my.fox_api_key_ with the API key. Add you inverter serial
|
|
63
63
|
Residual handling configures how battery residual energy reported by Fox is handled:
|
64
64
|
+ 1: Fox returns the current battery residual energy and battery capacity is calculated using soc
|
65
65
|
+ 2: Fox returns the current battery capacity and battery residual is calculated using soc
|
66
|
+
+ 3: Fox returns the residual capacity per battery (Mira)
|
66
67
|
|
67
68
|
If a value is set for f.plot_file, any charts created will also be saved to an image file:
|
68
69
|
+ f.plot_file: the file name to use. The file extension determines the format - .png, .pdf or .svg. If you provide just a filename, each chart will over-write the file. The default is None and disables saving.
|
69
70
|
+ f.plot_no: if the file name contains ###, this will be replaced by 3 digit plot number that increases for each chart created. The default is 0.
|
70
71
|
+ f.plot_dpi: sets the image resolution. The default is 150. Reducing this value produces smaller, lower resolution images. Increasing this value produces larger, highe resolution images
|
71
72
|
|
72
|
-
If you set f.pushover_user_key to your user_key for pushover.net, a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
73
|
+
If you set f.pushover_user_key to your user_key for [pushover.net](https://pushover.net), a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
73
74
|
|
74
75
|
You can set 'f.storage' to a path to save files to a different location such as cloud storage. The default is to use the current working directory.
|
75
76
|
|
@@ -90,6 +91,7 @@ Load information about a site, data logger or inverter (device):
|
|
90
91
|
```
|
91
92
|
f.get_site()
|
92
93
|
f.get_logger()
|
94
|
+
f.get_signal()
|
93
95
|
f.get_device()
|
94
96
|
```
|
95
97
|
|
@@ -98,7 +100,9 @@ By default, this will load the first item in the list provided by the cloud. If
|
|
98
100
|
+ Logger: full or partial serial number
|
99
101
|
+ Inverter: full or partial serial number
|
100
102
|
|
101
|
-
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively)
|
103
|
+
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively).
|
104
|
+
|
105
|
+
get_signal() is ancillary to get_logger() and returns the current data logger signal strength and time stamp.
|
102
106
|
|
103
107
|
Once an inverter is selected, you can make other calls to get information:
|
104
108
|
|
@@ -142,7 +146,7 @@ get_schedule() returns the current work mode / soc schedule settings. The result
|
|
142
146
|
|
143
147
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
144
148
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
145
|
-
+ named_settings
|
149
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
146
150
|
|
147
151
|
|
148
152
|
## Inverter Settings
|
@@ -152,7 +156,6 @@ You can change inverter settings using:
|
|
152
156
|
f.set_min(minSocOnGrid, minSoc)
|
153
157
|
f.set_charge(ch1, st1, en1, ch2, st2, en2, enable)
|
154
158
|
f.set_period(start, end, mode, min_soc, max_soc, fdsoc, fdpwr, price, segment)
|
155
|
-
f.charge_periods(st0, en0, st1, en1, st2, en2, min_soc, target_soc, start_soc)
|
156
159
|
f.set_schedule(periods, enable)
|
157
160
|
f.set_named_settings(name, value, force)
|
158
161
|
```
|
@@ -180,16 +183,7 @@ set_period() returns a period structure that can be used to build a list for set
|
|
180
183
|
+ enable: sets whether this time segment is enable (1) or disabled (0). The default is enabled.
|
181
184
|
+ segment: optional, allows the parameters for the period to be passed as a dictionary instead of individual values.
|
182
185
|
|
183
|
-
|
184
|
-
+ st0: the start time for period 0 when you don't want the battery to discharge before charging
|
185
|
-
+ en0: the end time for period 0
|
186
|
-
+ st1: the start time for the period when the battery charges from the grid
|
187
|
-
+ en1: the end time for period 1
|
188
|
-
+ st2: the start time for period 2 when you don't want the batteru to discharge after charging
|
189
|
-
+ en2: the end time for period 2
|
190
|
-
+ min_soc: the min_soc to use when building the strategy
|
191
|
-
+ start_soc: the min_soc to use for period 0
|
192
|
-
+ target_soc: the max_soc to set during period 1 and min_soc to use for period 2
|
186
|
+
Before calling set_period(), do at least one call to get_schedule(). This will inspect the schedule result to check if max_soc is supported and set the flag f.schedule['maxsoc'] to enable or disable this field as appropriate.
|
193
187
|
|
194
188
|
set_schedule() configures a list of scheduled work mode / soc changes with enable=1. If called with enable=0, any existing schedules are disabled. To enable a schedule, you must provide a list of time segments
|
195
189
|
+ periods: a time segment or list of time segments created using f.set_period().
|
@@ -199,7 +193,7 @@ set_named_settings() sets the 'name' setting to 'value'.
|
|
199
193
|
+ 'name' may also be a list of (name, value) pairs.
|
200
194
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
201
195
|
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
202
|
-
+ named_settings
|
196
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
203
197
|
|
204
198
|
|
205
199
|
## Real Time Data
|
@@ -826,7 +820,13 @@ This setting can be:
|
|
826
820
|
|
827
821
|
# Version Info
|
828
822
|
|
829
|
-
2.8.
|
823
|
+
2.8.7<br>
|
824
|
+
Added f.get_signal().
|
825
|
+
Updated set_period so you don't have to call get_schedule before.
|
826
|
+
Update set_period() to pass fdpwr and fdsoc for ForceCharge and display value.
|
827
|
+
Increase max value of fdpwr from 6000 to 30000.
|
828
|
+
|
829
|
+
2.8.6<br>
|
830
830
|
Update to charge_needed() to get current work mode.
|
831
831
|
|
832
832
|
2.8.5<br>
|
@@ -49,13 +49,14 @@ For example, replace _my.fox_api_key_ with the API key. Add you inverter serial
|
|
49
49
|
Residual handling configures how battery residual energy reported by Fox is handled:
|
50
50
|
+ 1: Fox returns the current battery residual energy and battery capacity is calculated using soc
|
51
51
|
+ 2: Fox returns the current battery capacity and battery residual is calculated using soc
|
52
|
+
+ 3: Fox returns the residual capacity per battery (Mira)
|
52
53
|
|
53
54
|
If a value is set for f.plot_file, any charts created will also be saved to an image file:
|
54
55
|
+ f.plot_file: the file name to use. The file extension determines the format - .png, .pdf or .svg. If you provide just a filename, each chart will over-write the file. The default is None and disables saving.
|
55
56
|
+ f.plot_no: if the file name contains ###, this will be replaced by 3 digit plot number that increases for each chart created. The default is 0.
|
56
57
|
+ f.plot_dpi: sets the image resolution. The default is 150. Reducing this value produces smaller, lower resolution images. Increasing this value produces larger, highe resolution images
|
57
58
|
|
58
|
-
If you set f.pushover_user_key to your user_key for pushover.net, a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
59
|
+
If you set f.pushover_user_key to your user_key for [pushover.net](https://pushover.net), a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
59
60
|
|
60
61
|
You can set 'f.storage' to a path to save files to a different location such as cloud storage. The default is to use the current working directory.
|
61
62
|
|
@@ -76,6 +77,7 @@ Load information about a site, data logger or inverter (device):
|
|
76
77
|
```
|
77
78
|
f.get_site()
|
78
79
|
f.get_logger()
|
80
|
+
f.get_signal()
|
79
81
|
f.get_device()
|
80
82
|
```
|
81
83
|
|
@@ -84,7 +86,9 @@ By default, this will load the first item in the list provided by the cloud. If
|
|
84
86
|
+ Logger: full or partial serial number
|
85
87
|
+ Inverter: full or partial serial number
|
86
88
|
|
87
|
-
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively)
|
89
|
+
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively).
|
90
|
+
|
91
|
+
get_signal() is ancillary to get_logger() and returns the current data logger signal strength and time stamp.
|
88
92
|
|
89
93
|
Once an inverter is selected, you can make other calls to get information:
|
90
94
|
|
@@ -128,7 +132,7 @@ get_schedule() returns the current work mode / soc schedule settings. The result
|
|
128
132
|
|
129
133
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
130
134
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
131
|
-
+ named_settings
|
135
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
132
136
|
|
133
137
|
|
134
138
|
## Inverter Settings
|
@@ -138,7 +142,6 @@ You can change inverter settings using:
|
|
138
142
|
f.set_min(minSocOnGrid, minSoc)
|
139
143
|
f.set_charge(ch1, st1, en1, ch2, st2, en2, enable)
|
140
144
|
f.set_period(start, end, mode, min_soc, max_soc, fdsoc, fdpwr, price, segment)
|
141
|
-
f.charge_periods(st0, en0, st1, en1, st2, en2, min_soc, target_soc, start_soc)
|
142
145
|
f.set_schedule(periods, enable)
|
143
146
|
f.set_named_settings(name, value, force)
|
144
147
|
```
|
@@ -166,16 +169,7 @@ set_period() returns a period structure that can be used to build a list for set
|
|
166
169
|
+ enable: sets whether this time segment is enable (1) or disabled (0). The default is enabled.
|
167
170
|
+ segment: optional, allows the parameters for the period to be passed as a dictionary instead of individual values.
|
168
171
|
|
169
|
-
|
170
|
-
+ st0: the start time for period 0 when you don't want the battery to discharge before charging
|
171
|
-
+ en0: the end time for period 0
|
172
|
-
+ st1: the start time for the period when the battery charges from the grid
|
173
|
-
+ en1: the end time for period 1
|
174
|
-
+ st2: the start time for period 2 when you don't want the batteru to discharge after charging
|
175
|
-
+ en2: the end time for period 2
|
176
|
-
+ min_soc: the min_soc to use when building the strategy
|
177
|
-
+ start_soc: the min_soc to use for period 0
|
178
|
-
+ target_soc: the max_soc to set during period 1 and min_soc to use for period 2
|
172
|
+
Before calling set_period(), do at least one call to get_schedule(). This will inspect the schedule result to check if max_soc is supported and set the flag f.schedule['maxsoc'] to enable or disable this field as appropriate.
|
179
173
|
|
180
174
|
set_schedule() configures a list of scheduled work mode / soc changes with enable=1. If called with enable=0, any existing schedules are disabled. To enable a schedule, you must provide a list of time segments
|
181
175
|
+ periods: a time segment or list of time segments created using f.set_period().
|
@@ -185,7 +179,7 @@ set_named_settings() sets the 'name' setting to 'value'.
|
|
185
179
|
+ 'name' may also be a list of (name, value) pairs.
|
186
180
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
187
181
|
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
188
|
-
+ named_settings
|
182
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
189
183
|
|
190
184
|
|
191
185
|
## Real Time Data
|
@@ -812,7 +806,13 @@ This setting can be:
|
|
812
806
|
|
813
807
|
# Version Info
|
814
808
|
|
815
|
-
2.8.
|
809
|
+
2.8.7<br>
|
810
|
+
Added f.get_signal().
|
811
|
+
Updated set_period so you don't have to call get_schedule before.
|
812
|
+
Update set_period() to pass fdpwr and fdsoc for ForceCharge and display value.
|
813
|
+
Increase max value of fdpwr from 6000 to 30000.
|
814
|
+
|
815
|
+
2.8.6<br>
|
816
816
|
Update to charge_needed() to get current work mode.
|
817
817
|
|
818
818
|
2.8.5<br>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud
|
4
|
-
Updated:
|
4
|
+
Updated: 15 September 2025
|
5
5
|
By: Tony Matthews
|
6
6
|
"""
|
7
7
|
##################################################################################################
|
@@ -10,7 +10,7 @@ By: Tony Matthews
|
|
10
10
|
# ALL RIGHTS ARE RESERVED © Tony Matthews 2023
|
11
11
|
##################################################################################################
|
12
12
|
|
13
|
-
version = "1.9.
|
13
|
+
version = "1.9.7"
|
14
14
|
print(f"FoxESS-Cloud version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -653,6 +653,8 @@ def get_battery(info=1, rated=None, count=None):
|
|
653
653
|
residual_handling = 2
|
654
654
|
elif battery['info']['masterSN'][:7] == '60MBB01' and battery['info']['masterVersion'] >= '1.014':
|
655
655
|
residual_handling = 3
|
656
|
+
if debug_setting > 1:
|
657
|
+
print(f"raw battery = {battery}")
|
656
658
|
battery['residual_handling'] = residual_handling
|
657
659
|
battery['soh'] = None
|
658
660
|
battery['soh_supported'] = False
|
@@ -1417,7 +1419,7 @@ def find_template(name):
|
|
1417
1419
|
|
1418
1420
|
# create a period structure. Note: end time is exclusive.
|
1419
1421
|
def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdsoc=None, fdpwr=None, price=None, segment=None, quiet=1):
|
1420
|
-
global schedule
|
1422
|
+
global schedule, device
|
1421
1423
|
if schedule is None and get_flag() is None:
|
1422
1424
|
return None
|
1423
1425
|
if segment is not None and type(segment) is dict:
|
@@ -1442,7 +1444,11 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1442
1444
|
return None
|
1443
1445
|
min_soc = 10 if min_soc is None else min_soc
|
1444
1446
|
max_soc = None if schedule.get('maxsoc') is None or schedule['maxsoc'] == False else 100 if max_soc is None else max_soc
|
1447
|
+
if mode == 'ForceCharge' and fdsoc is None:
|
1448
|
+
fdsoc = max_soc if max_soc is not None else 100
|
1445
1449
|
fdsoc = min_soc if fdsoc is None else fdsoc
|
1450
|
+
power = (device['power'] * 1000) if device.get('power') is not None else None
|
1451
|
+
fdpwr = power if fdpwr is None and power is not None and mode in ['ForceCharge', 'ForceDischarge'] else fdpwr
|
1446
1452
|
fdpwr = 0 if fdpwr is None else fdpwr
|
1447
1453
|
if min_soc < 10 or min_soc > 100:
|
1448
1454
|
output(f"set_period(): ** min_soc must be between 10 and 100")
|
@@ -1450,8 +1456,8 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1450
1456
|
if max_soc is not None and (max_soc < 10 or max_soc > 100):
|
1451
1457
|
output(f"set_period(): ** max_soc must be between 10 and 100")
|
1452
1458
|
return None
|
1453
|
-
if fdpwr < 0 or fdpwr >
|
1454
|
-
output(f"set_period(): ** fdpwr must be between 0 and
|
1459
|
+
if fdpwr < 0 or fdpwr > 30000:
|
1460
|
+
output(f"set_period(): ** fdpwr must be between 0 and 30000")
|
1455
1461
|
return None
|
1456
1462
|
if fdsoc < min_soc or fdsoc > 100:
|
1457
1463
|
output(f"set_period(): ** fdsoc must between {min_soc} and 100")
|
@@ -1459,7 +1465,7 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1459
1465
|
if quiet == 0:
|
1460
1466
|
s = f" {hours_time(start)}-{hours_time(end)} {mode}, minsoc {min_soc}%"
|
1461
1467
|
s += f", maxsoc {max_soc}%" if max_soc is not None and mode == 'ForceCharge' else ""
|
1462
|
-
s += f", fdPwr {fdpwr}W, fdSoC {fdsoc}%" if mode
|
1468
|
+
s += f", fdPwr {fdpwr}W, fdSoC {fdsoc}%" if mode in ['ForceCharge', 'ForceDischarge'] else ""
|
1463
1469
|
s += f", {price:.2f}p/kWh" if price is not None else ""
|
1464
1470
|
output(s, 1)
|
1465
1471
|
start_h, start_m = split_hours(start)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud using Open API
|
4
|
-
Updated:
|
4
|
+
Updated: 15 September 2025
|
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.8.
|
13
|
+
version = "2.8.7"
|
14
14
|
print(f"FoxESS-Cloud Open API version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -371,9 +371,10 @@ def get_site(name=None):
|
|
371
371
|
|
372
372
|
logger_list = None
|
373
373
|
logger = None
|
374
|
+
logger_sn = None
|
374
375
|
|
375
376
|
def get_logger(sn=None):
|
376
|
-
global logger_list, logger, debug_setting
|
377
|
+
global logger_list, logger, logger_sn, debug_setting
|
377
378
|
if get_vars() is None:
|
378
379
|
return None
|
379
380
|
if logger is not None and sn is None:
|
@@ -408,8 +409,30 @@ def get_logger(sn=None):
|
|
408
409
|
else:
|
409
410
|
n = 0
|
410
411
|
logger = logger_list[n]
|
412
|
+
logger_sn = logger.get('moduleSN')
|
411
413
|
return logger
|
412
414
|
|
415
|
+
def get_signal(sn=None):
|
416
|
+
global logger_list, logger, logger_sn, debug_setting
|
417
|
+
if get_vars() is None:
|
418
|
+
return None
|
419
|
+
if sn is None:
|
420
|
+
if logger_sn is None:
|
421
|
+
get_logger()
|
422
|
+
sn = logger_sn
|
423
|
+
if sn is None:
|
424
|
+
return None
|
425
|
+
output(f"getting signal", 2)
|
426
|
+
body = {'sn': sn}
|
427
|
+
response = signed_post(path="/op/v0/module/getSignal", body=body)
|
428
|
+
if response.status_code != 200:
|
429
|
+
output(f"** get_signal() got response code {response.status_code}: {response.reason}")
|
430
|
+
return None
|
431
|
+
result = response.json().get('result')
|
432
|
+
if result is None:
|
433
|
+
output(f"** get_signal(), no result data, {errno_message(response)}")
|
434
|
+
return None
|
435
|
+
return result
|
413
436
|
|
414
437
|
##################################################################################################
|
415
438
|
# get list of devices and select one, using the serial number if there is more than 1
|
@@ -593,6 +616,8 @@ def get_battery(info=0, v=None, rated=None, count=None):
|
|
593
616
|
battery = {}
|
594
617
|
for i in range(0, len(battery_vars)):
|
595
618
|
battery[battery_data[i]] = result[i].get('value')
|
619
|
+
if debug_setting > 1:
|
620
|
+
print(f"raw battery = {battery}")
|
596
621
|
battery['residual_handling'] = residual_handling
|
597
622
|
battery['soh'] = None
|
598
623
|
battery['soh_supported'] = False
|
@@ -1108,9 +1133,9 @@ def build_strategy_from_schedule():
|
|
1108
1133
|
|
1109
1134
|
# create time segment structure. Note: end time is exclusive.
|
1110
1135
|
def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdsoc=None, fdpwr=None, price=None, segment=None, enable=1, quiet=1):
|
1111
|
-
global schedule
|
1112
|
-
if schedule is None
|
1113
|
-
|
1136
|
+
global schedule, device
|
1137
|
+
if schedule is None:
|
1138
|
+
get_schedule()
|
1114
1139
|
if segment is not None and type(segment) is dict:
|
1115
1140
|
start = segment.get('start')
|
1116
1141
|
end = segment.get('end')
|
@@ -1132,8 +1157,12 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1132
1157
|
output(f"** mode must be one of {work_modes}")
|
1133
1158
|
return None
|
1134
1159
|
min_soc = 10 if min_soc is None else min_soc
|
1135
|
-
max_soc = None if schedule.get('maxsoc') is None or schedule['maxsoc'] == False else 100 if max_soc is None else max_soc
|
1160
|
+
max_soc = None if schedule is None or schedule.get('maxsoc') is None or schedule['maxsoc'] == False else 100 if max_soc is None else max_soc
|
1161
|
+
if mode == 'ForceCharge' and fdsoc is None:
|
1162
|
+
fdsoc = max_soc if max_soc is not None else 100
|
1136
1163
|
fdsoc = min_soc if fdsoc is None else fdsoc
|
1164
|
+
power = (device['power'] * 1000) if device.get('power') is not None else None
|
1165
|
+
fdpwr = power if fdpwr is None and device.get('power') is not None and mode in ['ForceCharge', 'ForceDischarge'] else fdpwr
|
1137
1166
|
fdpwr = 0 if fdpwr is None else fdpwr
|
1138
1167
|
if min_soc < 10 or min_soc > 100:
|
1139
1168
|
output(f"set_period(): ** min_soc must be between 10 and 100")
|
@@ -1141,8 +1170,8 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1141
1170
|
if max_soc is not None and (max_soc < 10 or max_soc > 100):
|
1142
1171
|
output(f"set_period(): ** max_soc must be between 10 and 100")
|
1143
1172
|
return None
|
1144
|
-
if fdpwr < 0 or fdpwr >
|
1145
|
-
output(f"set_period(): ** fdpwr must be between 0 and
|
1173
|
+
if fdpwr < 0 or fdpwr > 30000:
|
1174
|
+
output(f"set_period(): ** fdpwr must be between 0 and 30000")
|
1146
1175
|
return None
|
1147
1176
|
if fdsoc < min_soc or fdsoc > 100:
|
1148
1177
|
output(f"set_period(): ** fdsoc must between {min_soc} and 100")
|
@@ -1150,7 +1179,7 @@ def set_period(start=None, end=None, mode=None, min_soc=None, max_soc=None, fdso
|
|
1150
1179
|
if quiet == 0:
|
1151
1180
|
s = f" {hours_time(start)}-{hours_time(end)} {mode}, minsoc {min_soc}%"
|
1152
1181
|
s += f", maxsoc {max_soc}%" if max_soc is not None and mode == 'ForceCharge' else ""
|
1153
|
-
s += f", fdPwr {fdpwr}W, fdSoC {fdsoc}%" if mode
|
1182
|
+
s += f", fdPwr {fdpwr}W, fdSoC {fdsoc}%" if mode in ['ForceCharge', 'ForceDischarge'] else ""
|
1154
1183
|
s += f", {price:.2f}p/kWh" if price is not None else ""
|
1155
1184
|
output(s, 1)
|
1156
1185
|
start_hour, start_minute = split_hours(start)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foxesscloud
|
3
|
-
Version: 2.8.
|
3
|
+
Version: 2.8.7
|
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
|
@@ -63,13 +63,14 @@ For example, replace _my.fox_api_key_ with the API key. Add you inverter serial
|
|
63
63
|
Residual handling configures how battery residual energy reported by Fox is handled:
|
64
64
|
+ 1: Fox returns the current battery residual energy and battery capacity is calculated using soc
|
65
65
|
+ 2: Fox returns the current battery capacity and battery residual is calculated using soc
|
66
|
+
+ 3: Fox returns the residual capacity per battery (Mira)
|
66
67
|
|
67
68
|
If a value is set for f.plot_file, any charts created will also be saved to an image file:
|
68
69
|
+ f.plot_file: the file name to use. The file extension determines the format - .png, .pdf or .svg. If you provide just a filename, each chart will over-write the file. The default is None and disables saving.
|
69
70
|
+ f.plot_no: if the file name contains ###, this will be replaced by 3 digit plot number that increases for each chart created. The default is 0.
|
70
71
|
+ f.plot_dpi: sets the image resolution. The default is 150. Reducing this value produces smaller, lower resolution images. Increasing this value produces larger, highe resolution images
|
71
72
|
|
72
|
-
If you set f.pushover_user_key to your user_key for pushover.net, a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
73
|
+
If you set f.pushover_user_key to your user_key for [pushover.net](https://pushover.net), a summary from set_tariff(), charge_needed(), set_pvoutput() and battery_info() will be sent to your pushover app.
|
73
74
|
|
74
75
|
You can set 'f.storage' to a path to save files to a different location such as cloud storage. The default is to use the current working directory.
|
75
76
|
|
@@ -90,6 +91,7 @@ Load information about a site, data logger or inverter (device):
|
|
90
91
|
```
|
91
92
|
f.get_site()
|
92
93
|
f.get_logger()
|
94
|
+
f.get_signal()
|
93
95
|
f.get_device()
|
94
96
|
```
|
95
97
|
|
@@ -98,7 +100,9 @@ By default, this will load the first item in the list provided by the cloud. If
|
|
98
100
|
+ Logger: full or partial serial number
|
99
101
|
+ Inverter: full or partial serial number
|
100
102
|
|
101
|
-
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively)
|
103
|
+
When an item is selected, the functions returns a dictionary containing item details and saves these to a global variable (f.site, f.logger, f.device respectively).
|
104
|
+
|
105
|
+
get_signal() is ancillary to get_logger() and returns the current data logger signal strength and time stamp.
|
102
106
|
|
103
107
|
Once an inverter is selected, you can make other calls to get information:
|
104
108
|
|
@@ -142,7 +146,7 @@ get_schedule() returns the current work mode / soc schedule settings. The result
|
|
142
146
|
|
143
147
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
144
148
|
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
145
|
-
+ named_settings
|
149
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
146
150
|
|
147
151
|
|
148
152
|
## Inverter Settings
|
@@ -152,7 +156,6 @@ You can change inverter settings using:
|
|
152
156
|
f.set_min(minSocOnGrid, minSoc)
|
153
157
|
f.set_charge(ch1, st1, en1, ch2, st2, en2, enable)
|
154
158
|
f.set_period(start, end, mode, min_soc, max_soc, fdsoc, fdpwr, price, segment)
|
155
|
-
f.charge_periods(st0, en0, st1, en1, st2, en2, min_soc, target_soc, start_soc)
|
156
159
|
f.set_schedule(periods, enable)
|
157
160
|
f.set_named_settings(name, value, force)
|
158
161
|
```
|
@@ -180,16 +183,7 @@ set_period() returns a period structure that can be used to build a list for set
|
|
180
183
|
+ enable: sets whether this time segment is enable (1) or disabled (0). The default is enabled.
|
181
184
|
+ segment: optional, allows the parameters for the period to be passed as a dictionary instead of individual values.
|
182
185
|
|
183
|
-
|
184
|
-
+ st0: the start time for period 0 when you don't want the battery to discharge before charging
|
185
|
-
+ en0: the end time for period 0
|
186
|
-
+ st1: the start time for the period when the battery charges from the grid
|
187
|
-
+ en1: the end time for period 1
|
188
|
-
+ st2: the start time for period 2 when you don't want the batteru to discharge after charging
|
189
|
-
+ en2: the end time for period 2
|
190
|
-
+ min_soc: the min_soc to use when building the strategy
|
191
|
-
+ start_soc: the min_soc to use for period 0
|
192
|
-
+ target_soc: the max_soc to set during period 1 and min_soc to use for period 2
|
186
|
+
Before calling set_period(), do at least one call to get_schedule(). This will inspect the schedule result to check if max_soc is supported and set the flag f.schedule['maxsoc'] to enable or disable this field as appropriate.
|
193
187
|
|
194
188
|
set_schedule() configures a list of scheduled work mode / soc changes with enable=1. If called with enable=0, any existing schedules are disabled. To enable a schedule, you must provide a list of time segments
|
195
189
|
+ periods: a time segment or list of time segments created using f.set_period().
|
@@ -199,7 +193,7 @@ set_named_settings() sets the 'name' setting to 'value'.
|
|
199
193
|
+ 'name' may also be a list of (name, value) pairs.
|
200
194
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
201
195
|
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
202
|
-
+ named_settings
|
196
|
+
+ named_settings currently supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode, WorkMode
|
203
197
|
|
204
198
|
|
205
199
|
## Real Time Data
|
@@ -826,7 +820,13 @@ This setting can be:
|
|
826
820
|
|
827
821
|
# Version Info
|
828
822
|
|
829
|
-
2.8.
|
823
|
+
2.8.7<br>
|
824
|
+
Added f.get_signal().
|
825
|
+
Updated set_period so you don't have to call get_schedule before.
|
826
|
+
Update set_period() to pass fdpwr and fdsoc for ForceCharge and display value.
|
827
|
+
Increase max value of fdpwr from 6000 to 30000.
|
828
|
+
|
829
|
+
2.8.6<br>
|
830
830
|
Update to charge_needed() to get current work mode.
|
831
831
|
|
832
832
|
2.8.5<br>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|