foxesscloud 2.8.1__tar.gz → 2.8.3__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.1 → foxesscloud-2.8.3}/PKG-INFO +25 -6
- foxesscloud-2.8.1/src/foxesscloud.egg-info/PKG-INFO → foxesscloud-2.8.3/README.md +24 -19
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/pyproject.toml +1 -1
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/src/foxesscloud/foxesscloud.py +32 -20
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/src/foxesscloud/openapi.py +10 -10
- foxesscloud-2.8.1/README.md → foxesscloud-2.8.3/src/foxesscloud.egg-info/PKG-INFO +38 -5
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/LICENCE +0 -0
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/setup.cfg +0 -0
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/src/foxesscloud.egg-info/SOURCES.txt +0 -0
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/src/foxesscloud.egg-info/dependency_links.txt +0 -0
- {foxesscloud-2.8.1 → foxesscloud-2.8.3}/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.3
|
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
|
@@ -132,13 +132,14 @@ Additional battery attributes provided include:
|
|
132
132
|
|
133
133
|
get_settings() will return the battery settings and is equivalent to get_charge() and get_min(). The results are stored in f.battery_settings. The settings include minSoc, minSocOnGrid, enable charge from grid and the charge times.
|
134
134
|
|
135
|
-
get_flag() returns the current scheduler enable / support / maxsoc flags
|
135
|
+
get_flag() returns the current scheduler enable / support / maxsoc flags. By default support for Max Soc is set to False.
|
136
136
|
|
137
137
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
138
|
+
+ if the schedule returned contains any values for 'maxSoc', the f.schedule['maxsoc'] is set to True to indicate that the current inverter supports setting Max Soc in schedules and Max Soc values are set by set_schedule().
|
138
139
|
|
139
140
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
140
|
-
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name.
|
141
|
-
+
|
141
|
+
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
142
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
142
143
|
|
143
144
|
|
144
145
|
## Inverter Settings
|
@@ -194,8 +195,8 @@ set_schedule() configures a list of scheduled work mode / soc changes with enabl
|
|
194
195
|
set_named_settings() sets the 'name' setting to 'value'.
|
195
196
|
+ 'name' may also be a list of (name, value) pairs.
|
196
197
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
197
|
-
+
|
198
|
-
+
|
198
|
+
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
199
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
199
200
|
|
200
201
|
|
201
202
|
## Real Time Data
|
@@ -620,6 +621,17 @@ Plunge pricing allows for the automatic configuration of charging periods when A
|
|
620
621
|
# PV Output
|
621
622
|
These functions produce CSV data for upload to [pvoutput.org](https://pvoutput.org) including PV generation, Export, Load and Grid consumption by day in Wh. The functions use the energy estimates created from the raw power data (see above). The estimates include PV energy generation that are not otherwise available from the Fox Cloud. Typically, the energy results are within 3% of the values reported by the meters built into the inverter.
|
622
623
|
|
624
|
+
## Calibration
|
625
|
+
PV generation data is created using the Riemann sum of the PV power and CT2 power as the history of the stats provided by the Fox cloud can be unreliable. You can change the calibration factors used:
|
626
|
+
|
627
|
+
```
|
628
|
+
f.pv_calibration = 0.98
|
629
|
+
f.ct2_calibration = 0.92
|
630
|
+
```
|
631
|
+
* pv_calibration is a DC calibration factor and is multiplied by the Riemann sum. The default calibration factor of 0.98 was derrived by comparing the total solar production calculated against the inverter generation data provided via Modbus over 12 months
|
632
|
+
|
633
|
+
* ct2_calibration is an AC calibration factor and is the divisor for the Riemann sum. CT2 measures the AC power output by the inverter and this factor converts this back to the DC power coming from the solar panels into the inverter, assuming an MPPT efficiency of 95% and DC-AC conversion efficiency of 97%. This aligns the solar panel generation with PV power, allowing the total solar generation from both primary (connected to the hybrid inverter) and secondary (connected via a separate solar inverter) panels to be combined correctly.
|
634
|
+
|
623
635
|
|
624
636
|
## Get PV Output Data
|
625
637
|
|
@@ -809,6 +821,13 @@ This setting can be:
|
|
809
821
|
|
810
822
|
# Version Info
|
811
823
|
|
824
|
+
2.8.3<br>
|
825
|
+
Update to support setting Max Soc in schedules now this is supported by Fox using Open API.
|
826
|
+
|
827
|
+
2.8.2<br>
|
828
|
+
Fix forecast.solar (after change to start parameter processing).
|
829
|
+
Change logic around battery status so 0 is offline and others values are online.
|
830
|
+
|
812
831
|
2.8.1<br>
|
813
832
|
Update from v0 to v1 for scheduler API.
|
814
833
|
PVEnergyTotal added to report variables.
|
@@ -1,17 +1,3 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: foxesscloud
|
3
|
-
Version: 2.8.1
|
4
|
-
Summary: library for accessing Fox ESS cloud data using Open API
|
5
|
-
Author-email: Tony Matthews <tony@quasair.co.uk>
|
6
|
-
Project-URL: Homepage, https://github.com/TonyM1958/FoxESS-Cloud
|
7
|
-
Project-URL: Bug Tracker, https://github.com/TonyM1958/FoxESS-Cloud/issues
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
10
|
-
Classifier: Operating System :: OS Independent
|
11
|
-
Requires-Python: >=3.7
|
12
|
-
Description-Content-Type: text/markdown
|
13
|
-
License-File: LICENCE
|
14
|
-
|
15
1
|
# FoxESS-Cloud
|
16
2
|
|
17
3
|
<a href="https://www.buymeacoffee.com/tonym1958" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174" align="right"></a>
|
@@ -132,13 +118,14 @@ Additional battery attributes provided include:
|
|
132
118
|
|
133
119
|
get_settings() will return the battery settings and is equivalent to get_charge() and get_min(). The results are stored in f.battery_settings. The settings include minSoc, minSocOnGrid, enable charge from grid and the charge times.
|
134
120
|
|
135
|
-
get_flag() returns the current scheduler enable / support / maxsoc flags
|
121
|
+
get_flag() returns the current scheduler enable / support / maxsoc flags. By default support for Max Soc is set to False.
|
136
122
|
|
137
123
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
124
|
+
+ if the schedule returned contains any values for 'maxSoc', the f.schedule['maxsoc'] is set to True to indicate that the current inverter supports setting Max Soc in schedules and Max Soc values are set by set_schedule().
|
138
125
|
|
139
126
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
140
|
-
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name.
|
141
|
-
+
|
127
|
+
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
128
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
142
129
|
|
143
130
|
|
144
131
|
## Inverter Settings
|
@@ -194,8 +181,8 @@ set_schedule() configures a list of scheduled work mode / soc changes with enabl
|
|
194
181
|
set_named_settings() sets the 'name' setting to 'value'.
|
195
182
|
+ 'name' may also be a list of (name, value) pairs.
|
196
183
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
197
|
-
+
|
198
|
-
+
|
184
|
+
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
185
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
199
186
|
|
200
187
|
|
201
188
|
## Real Time Data
|
@@ -620,6 +607,17 @@ Plunge pricing allows for the automatic configuration of charging periods when A
|
|
620
607
|
# PV Output
|
621
608
|
These functions produce CSV data for upload to [pvoutput.org](https://pvoutput.org) including PV generation, Export, Load and Grid consumption by day in Wh. The functions use the energy estimates created from the raw power data (see above). The estimates include PV energy generation that are not otherwise available from the Fox Cloud. Typically, the energy results are within 3% of the values reported by the meters built into the inverter.
|
622
609
|
|
610
|
+
## Calibration
|
611
|
+
PV generation data is created using the Riemann sum of the PV power and CT2 power as the history of the stats provided by the Fox cloud can be unreliable. You can change the calibration factors used:
|
612
|
+
|
613
|
+
```
|
614
|
+
f.pv_calibration = 0.98
|
615
|
+
f.ct2_calibration = 0.92
|
616
|
+
```
|
617
|
+
* pv_calibration is a DC calibration factor and is multiplied by the Riemann sum. The default calibration factor of 0.98 was derrived by comparing the total solar production calculated against the inverter generation data provided via Modbus over 12 months
|
618
|
+
|
619
|
+
* ct2_calibration is an AC calibration factor and is the divisor for the Riemann sum. CT2 measures the AC power output by the inverter and this factor converts this back to the DC power coming from the solar panels into the inverter, assuming an MPPT efficiency of 95% and DC-AC conversion efficiency of 97%. This aligns the solar panel generation with PV power, allowing the total solar generation from both primary (connected to the hybrid inverter) and secondary (connected via a separate solar inverter) panels to be combined correctly.
|
620
|
+
|
623
621
|
|
624
622
|
## Get PV Output Data
|
625
623
|
|
@@ -809,6 +807,13 @@ This setting can be:
|
|
809
807
|
|
810
808
|
# Version Info
|
811
809
|
|
810
|
+
2.8.3<br>
|
811
|
+
Update to support setting Max Soc in schedules now this is supported by Fox using Open API.
|
812
|
+
|
813
|
+
2.8.2<br>
|
814
|
+
Fix forecast.solar (after change to start parameter processing).
|
815
|
+
Change logic around battery status so 0 is offline and others values are online.
|
816
|
+
|
812
817
|
2.8.1<br>
|
813
818
|
Update from v0 to v1 for scheduler API.
|
814
819
|
PVEnergyTotal added to report variables.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud
|
4
|
-
Updated:
|
4
|
+
Updated: 16 April 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.5"
|
14
14
|
print(f"FoxESS-Cloud version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -657,11 +657,10 @@ def get_battery(info=1, rated=None, count=None):
|
|
657
657
|
battery['soh'] = None
|
658
658
|
battery['soh_supported'] = False
|
659
659
|
if battery.get('status') is None:
|
660
|
-
battery['status'] = 0 if battery.get('volt') is None or battery['volt'] <=
|
661
|
-
if battery.get('status') is None or battery['status']
|
660
|
+
battery['status'] = 0 if battery.get('volt') is None or battery['volt'] <= 10 else 1
|
661
|
+
if battery.get('status') is None or battery['status'] == 0:
|
662
662
|
output(f"** get_battery(): battery status not available")
|
663
663
|
return None
|
664
|
-
battery['status'] = 1
|
665
664
|
if battery.get('residual') is not None:
|
666
665
|
battery['residual'] *= residual_scale / 10
|
667
666
|
if battery['residual_handling'] == 2:
|
@@ -736,7 +735,7 @@ def get_batteries(info=1, rated=None, count=None):
|
|
736
735
|
while len(count) < len(batteries):
|
737
736
|
count.append(None)
|
738
737
|
for i,b in enumerate(batteries):
|
739
|
-
if b.get('status') is None or b['status']
|
738
|
+
if b.get('status') is None or b['status'] == 0:
|
740
739
|
output(f"** get_batteries(): battery {i+1} status not available")
|
741
740
|
continue
|
742
741
|
b['residual_handling'] = residual_handling
|
@@ -755,7 +754,7 @@ def get_batteries(info=1, rated=None, count=None):
|
|
755
754
|
b['soh'] = int(soh) if soh.isnumeric() and int(soh) > 10 else None
|
756
755
|
b['soh_supported'] = b['soh'] is not None
|
757
756
|
for i, b in enumerate(batteries):
|
758
|
-
if b.get('status') is None or b['status']
|
757
|
+
if b.get('status') is None or b['status'] == 0:
|
759
758
|
continue
|
760
759
|
if i == 0:
|
761
760
|
residual_handling = b['residual_handling']
|
@@ -973,6 +972,7 @@ merge_settings = { # keys to add
|
|
973
972
|
'h116__': 'operation_mode__work_mode',
|
974
973
|
'h117__': 'operation_mode__work_mode',
|
975
974
|
# 'k106__': 'operation_mode__work_mode',
|
975
|
+
# 'k110__': 'operation_mode__work_mode',
|
976
976
|
},
|
977
977
|
'values': ['SelfUse', 'Feedin', 'Backup']},
|
978
978
|
'ExportLimit': {'keys': {
|
@@ -980,6 +980,7 @@ merge_settings = { # keys to add
|
|
980
980
|
'h116__': 'basic2__05',
|
981
981
|
'h117__': 'basic2__05',
|
982
982
|
# 'k106__': 'basic2__05',
|
983
|
+
# 'k1110__': 'basic2__05',
|
983
984
|
},
|
984
985
|
'valueType': 'int'},
|
985
986
|
'BatteryVolt': {'keys': {
|
@@ -987,6 +988,7 @@ merge_settings = { # keys to add
|
|
987
988
|
'h116__': ['h116__15', 'h116__16', 'h116__17'],
|
988
989
|
'h117__': ['h117__15', 'h117__16', 'h117__17'],
|
989
990
|
# 'k106__': ['k106__xx', 'k106__xx', 'k106__xx'],
|
991
|
+
# 'k110__': ['k110__xx', 'k110__xx', 'k110__xx'],
|
990
992
|
},
|
991
993
|
'type': 'list',
|
992
994
|
'valueType': 'float',
|
@@ -996,12 +998,20 @@ merge_settings = { # keys to add
|
|
996
998
|
'h116__': 'h116__18',
|
997
999
|
'h117__': 'h117__18',
|
998
1000
|
# 'k106__': 'k106__xx',
|
1001
|
+
# 'k110__': 'k110__xx',
|
999
1002
|
},
|
1000
1003
|
'type': 'list',
|
1001
1004
|
'valueType': 'int',
|
1002
1005
|
'unit': '℃'},
|
1003
1006
|
}
|
1004
1007
|
|
1008
|
+
# change named settings, if required, so names match between Fox API and Open API
|
1009
|
+
translate_names = {
|
1010
|
+
'MaxSoc': 'MaximumSoC',
|
1011
|
+
'MinSoc': 'MinimumSoC',
|
1012
|
+
'MinSocOnGrid': 'MinimumSoC-OnGrid'
|
1013
|
+
}
|
1014
|
+
|
1005
1015
|
def get_ui():
|
1006
1016
|
global device_id, debug_setting, messages, remote_settings, named_settings, merge_settings
|
1007
1017
|
if get_device() is None:
|
@@ -1066,7 +1076,7 @@ def get_ui():
|
|
1066
1076
|
return remote_settings
|
1067
1077
|
|
1068
1078
|
def get_remote_settings(key):
|
1069
|
-
global device_id, debug_setting, messages
|
1079
|
+
global device_id, debug_setting, messages, translate_settings
|
1070
1080
|
if get_device() is None:
|
1071
1081
|
return None
|
1072
1082
|
output(f"getting remote settings", 2)
|
@@ -1098,7 +1108,7 @@ def get_remote_settings(key):
|
|
1098
1108
|
return values
|
1099
1109
|
|
1100
1110
|
def get_named_settings(name):
|
1101
|
-
global named_settings
|
1111
|
+
global named_settings, translate_names
|
1102
1112
|
if get_device() is None:
|
1103
1113
|
return None
|
1104
1114
|
if type(name) is list:
|
@@ -1106,10 +1116,11 @@ def get_named_settings(name):
|
|
1106
1116
|
for n in name:
|
1107
1117
|
result.append(get_named_settings(n))
|
1108
1118
|
return result
|
1109
|
-
|
1119
|
+
key_name = translate_names[name] if translate_names.get(name) is not None else name
|
1120
|
+
if named_settings is None or named_settings.get(key_name) is None:
|
1110
1121
|
output(f"** get_named_settings(): {name} was not recognised")
|
1111
1122
|
return None
|
1112
|
-
keys = named_settings[
|
1123
|
+
keys = named_settings[key_name].get('keys')
|
1113
1124
|
if keys is None:
|
1114
1125
|
output(f"** get_named_settings(): no keys for name: {name}")
|
1115
1126
|
return None
|
@@ -1118,8 +1129,8 @@ def get_named_settings(name):
|
|
1118
1129
|
if result is None:
|
1119
1130
|
output(f"** get_named_settings(): no result for {name} using key: {keys}")
|
1120
1131
|
return None
|
1121
|
-
result_type = named_settings[
|
1122
|
-
value_type = named_settings[
|
1132
|
+
result_type = named_settings[key_name].get('type')
|
1133
|
+
value_type = named_settings[key_name].get('valueType')
|
1123
1134
|
if result_type is None:
|
1124
1135
|
v = result.get([k for k in result.keys()][0])
|
1125
1136
|
return v if value_type is None else c_float(v) if value_type == 'float' else c_int(v)
|
@@ -1131,7 +1142,7 @@ def get_named_settings(name):
|
|
1131
1142
|
return result
|
1132
1143
|
|
1133
1144
|
def set_named_settings(name, value, force=0):
|
1134
|
-
global named_settings
|
1145
|
+
global named_settings, translate_names
|
1135
1146
|
if get_device() is None:
|
1136
1147
|
return None
|
1137
1148
|
if force == 1 and get_schedule().get('enable'):
|
@@ -1141,18 +1152,19 @@ def set_named_settings(name, value, force=0):
|
|
1141
1152
|
for (n, v) in name:
|
1142
1153
|
result.append(set_named_settings(name=n, value=v))
|
1143
1154
|
return result
|
1144
|
-
|
1155
|
+
key_name = translate_names[name] if translate_names.get(name) is not None else name
|
1156
|
+
if named_settings is None or named_settings.get(key_name) is None:
|
1145
1157
|
output(f"** set_named_settings(): {name} was not recognised")
|
1146
1158
|
return None
|
1147
|
-
keys = named_settings[
|
1159
|
+
keys = named_settings[key_name].get('keys')
|
1148
1160
|
if keys is None:
|
1149
1161
|
output(f"** set_named_settings(): no keys for name: {name}")
|
1150
1162
|
return None
|
1151
|
-
item_type = named_settings[
|
1163
|
+
item_type = named_settings[key_name].get('type')
|
1152
1164
|
if item_type is None:
|
1153
1165
|
values = {keys: str(value)}
|
1154
1166
|
elif item_type == 'block':
|
1155
|
-
items = named_setting[
|
1167
|
+
items = named_setting[key_name]['items']
|
1156
1168
|
n = len(items)
|
1157
1169
|
if type(value) is not list or n != len(value):
|
1158
1170
|
output(f"** set_named_settings(): {name} requires list of {n} values")
|
@@ -3089,7 +3101,7 @@ def charge_needed(forecast=None, consumption=None, update_settings=0, timed_mode
|
|
3089
3101
|
else:
|
3090
3102
|
# get device and battery info from inverter
|
3091
3103
|
get_battery()
|
3092
|
-
if battery is None or battery['status']
|
3104
|
+
if battery is None or battery['status'] == 0:
|
3093
3105
|
return None
|
3094
3106
|
current_soc = battery['soc']
|
3095
3107
|
bat_volt = battery['volt']
|
@@ -4485,7 +4497,7 @@ class Solar :
|
|
4485
4497
|
if debug_setting > 0 and not quiet:
|
4486
4498
|
print(f"Getting data for {name} array")
|
4487
4499
|
path = f"{a['lat']}/{a['lon']}/{a['dec']}/{a['az']}/{a['kwp']}"
|
4488
|
-
params = {'
|
4500
|
+
params = {'no_sun': 1, 'damping': a['dam'], 'inverter': a['inv'], 'horizon': a['hor']}
|
4489
4501
|
response = requests.get(solar_url + self.api_key + 'estimate/' + path, params = params)
|
4490
4502
|
if response.status_code != 200:
|
4491
4503
|
if response.status_code == 429:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud using Open API
|
4
|
-
Updated:
|
4
|
+
Updated: 16 April 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.3"
|
14
14
|
print(f"FoxESS-Cloud Open API version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -597,11 +597,10 @@ def get_battery(info=0, v=None, rated=None, count=None):
|
|
597
597
|
battery['soh'] = None
|
598
598
|
battery['soh_supported'] = False
|
599
599
|
if battery.get('status') is None:
|
600
|
-
battery['status'] = 0 if battery.get('volt') is None or battery['volt'] <=
|
601
|
-
if battery['status']
|
600
|
+
battery['status'] = 0 if battery.get('volt') is None or battery['volt'] <= 10 else 1
|
601
|
+
if battery['status'] == 0:
|
602
602
|
output(f"** get_battery(): battery status not available")
|
603
603
|
return None
|
604
|
-
battery['status'] = 1
|
605
604
|
if battery['residual_handling'] == 2:
|
606
605
|
capacity = battery.get('residual')
|
607
606
|
soc = battery.get('soc')
|
@@ -628,7 +627,6 @@ def get_battery(info=0, v=None, rated=None, count=None):
|
|
628
627
|
battery['ratedCapacity'] = rated
|
629
628
|
battery['capacity'] = round(capacity, 3)
|
630
629
|
battery['residual'] = round(residual, 3)
|
631
|
-
battery['status'] = 1
|
632
630
|
battery['charge_rate'] = None
|
633
631
|
params = battery_params[battery['residual_handling']]
|
634
632
|
battery['charge_loss'] = params['charge_loss']
|
@@ -863,6 +861,7 @@ def get_remote_settings(name):
|
|
863
861
|
values[x] = v[x]
|
864
862
|
return values
|
865
863
|
body = {'sn': device_sn, 'key': name}
|
864
|
+
setting_delay()
|
866
865
|
response = signed_post(path="/op/v0/device/setting/get", body=body)
|
867
866
|
if response.status_code != 200:
|
868
867
|
output(f"** get_remote_settings() got response code {response.status_code}: {response.reason}")
|
@@ -1018,10 +1017,9 @@ def get_flag():
|
|
1018
1017
|
if result is None:
|
1019
1018
|
return None
|
1020
1019
|
if schedule is None:
|
1021
|
-
schedule = {'enable': None, 'support': None, 'periods': None}
|
1020
|
+
schedule = {'enable': None, 'support': None, 'periods': None, 'maxsoc': False}
|
1022
1021
|
schedule['enable'] = result.get('enable')
|
1023
1022
|
schedule['support'] = result.get('support')
|
1024
|
-
schedule['maxsoc'] = False
|
1025
1023
|
if device.get('function') is not None and device['function'].get('scheduler') is not None:
|
1026
1024
|
device['function']['scheduler'] = schedule['support']
|
1027
1025
|
return schedule
|
@@ -1057,6 +1055,8 @@ def get_schedule():
|
|
1057
1055
|
for g in result['groups']:
|
1058
1056
|
if g['enable'] == 1 and g['workMode'] in work_modes:
|
1059
1057
|
schedule['periods'].append(g)
|
1058
|
+
if g.get('maxSoc') is not None:
|
1059
|
+
schedule['maxsoc'] = True
|
1060
1060
|
return schedule
|
1061
1061
|
|
1062
1062
|
# build strategy using current schedule
|
@@ -2756,7 +2756,7 @@ def charge_needed(forecast=None, consumption=None, update_settings=0, timed_mode
|
|
2756
2756
|
else:
|
2757
2757
|
# get device and battery info from inverter
|
2758
2758
|
get_battery()
|
2759
|
-
if battery is None or battery['status']
|
2759
|
+
if battery is None or battery['status'] == 0:
|
2760
2760
|
return None
|
2761
2761
|
current_soc = battery['soc']
|
2762
2762
|
bat_volt = battery['volt']
|
@@ -4153,7 +4153,7 @@ class Solar :
|
|
4153
4153
|
if debug_setting > 0 and not quiet:
|
4154
4154
|
print(f"Getting data for {name} array")
|
4155
4155
|
path = f"{a['lat']}/{a['lon']}/{a['dec']}/{a['az']}/{a['kwp']}"
|
4156
|
-
params = {'
|
4156
|
+
params = {'no_sun': 1, 'damping': a['dam'], 'inverter': a['inv'], 'horizon': a['hor']}
|
4157
4157
|
response = requests.get(solar_url + self.api_key + 'estimate/' + path, params = params)
|
4158
4158
|
if response.status_code != 200:
|
4159
4159
|
if response.status_code == 429:
|
@@ -1,3 +1,17 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: foxesscloud
|
3
|
+
Version: 2.8.3
|
4
|
+
Summary: library for accessing Fox ESS cloud data using Open API
|
5
|
+
Author-email: Tony Matthews <tony@quasair.co.uk>
|
6
|
+
Project-URL: Homepage, https://github.com/TonyM1958/FoxESS-Cloud
|
7
|
+
Project-URL: Bug Tracker, https://github.com/TonyM1958/FoxESS-Cloud/issues
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
10
|
+
Classifier: Operating System :: OS Independent
|
11
|
+
Requires-Python: >=3.7
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
License-File: LICENCE
|
14
|
+
|
1
15
|
# FoxESS-Cloud
|
2
16
|
|
3
17
|
<a href="https://www.buymeacoffee.com/tonym1958" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174" align="right"></a>
|
@@ -118,13 +132,14 @@ Additional battery attributes provided include:
|
|
118
132
|
|
119
133
|
get_settings() will return the battery settings and is equivalent to get_charge() and get_min(). The results are stored in f.battery_settings. The settings include minSoc, minSocOnGrid, enable charge from grid and the charge times.
|
120
134
|
|
121
|
-
get_flag() returns the current scheduler enable / support / maxsoc flags
|
135
|
+
get_flag() returns the current scheduler enable / support / maxsoc flags. By default support for Max Soc is set to False.
|
122
136
|
|
123
137
|
get_schedule() returns the current work mode / soc schedule settings. The result is stored in f.schedule.
|
138
|
+
+ if the schedule returned contains any values for 'maxSoc', the f.schedule['maxsoc'] is set to True to indicate that the current inverter supports setting Max Soc in schedules and Max Soc values are set by set_schedule().
|
124
139
|
|
125
140
|
get_named_settings() returns the value of a named setting. If 'name' is a list, it returns a list of values.
|
126
|
-
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name.
|
127
|
-
+
|
141
|
+
+ f.named_settings is updated. This is dictionary of information and current value, indexed by 'name'.
|
142
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
128
143
|
|
129
144
|
|
130
145
|
## Inverter Settings
|
@@ -180,8 +195,8 @@ set_schedule() configures a list of scheduled work mode / soc changes with enabl
|
|
180
195
|
set_named_settings() sets the 'name' setting to 'value'.
|
181
196
|
+ 'name' may also be a list of (name, value) pairs.
|
182
197
|
+ 'force': setting to 1 will disable Mode Scheduler, if enabled. Default is 0.
|
183
|
-
+
|
184
|
-
+
|
198
|
+
+ a return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
|
199
|
+
+ named_settings current supported include: ExportLimit, MinSoc, MinSocOnGrid, MaxSoc, GridCode
|
185
200
|
|
186
201
|
|
187
202
|
## Real Time Data
|
@@ -606,6 +621,17 @@ Plunge pricing allows for the automatic configuration of charging periods when A
|
|
606
621
|
# PV Output
|
607
622
|
These functions produce CSV data for upload to [pvoutput.org](https://pvoutput.org) including PV generation, Export, Load and Grid consumption by day in Wh. The functions use the energy estimates created from the raw power data (see above). The estimates include PV energy generation that are not otherwise available from the Fox Cloud. Typically, the energy results are within 3% of the values reported by the meters built into the inverter.
|
608
623
|
|
624
|
+
## Calibration
|
625
|
+
PV generation data is created using the Riemann sum of the PV power and CT2 power as the history of the stats provided by the Fox cloud can be unreliable. You can change the calibration factors used:
|
626
|
+
|
627
|
+
```
|
628
|
+
f.pv_calibration = 0.98
|
629
|
+
f.ct2_calibration = 0.92
|
630
|
+
```
|
631
|
+
* pv_calibration is a DC calibration factor and is multiplied by the Riemann sum. The default calibration factor of 0.98 was derrived by comparing the total solar production calculated against the inverter generation data provided via Modbus over 12 months
|
632
|
+
|
633
|
+
* ct2_calibration is an AC calibration factor and is the divisor for the Riemann sum. CT2 measures the AC power output by the inverter and this factor converts this back to the DC power coming from the solar panels into the inverter, assuming an MPPT efficiency of 95% and DC-AC conversion efficiency of 97%. This aligns the solar panel generation with PV power, allowing the total solar generation from both primary (connected to the hybrid inverter) and secondary (connected via a separate solar inverter) panels to be combined correctly.
|
634
|
+
|
609
635
|
|
610
636
|
## Get PV Output Data
|
611
637
|
|
@@ -795,6 +821,13 @@ This setting can be:
|
|
795
821
|
|
796
822
|
# Version Info
|
797
823
|
|
824
|
+
2.8.3<br>
|
825
|
+
Update to support setting Max Soc in schedules now this is supported by Fox using Open API.
|
826
|
+
|
827
|
+
2.8.2<br>
|
828
|
+
Fix forecast.solar (after change to start parameter processing).
|
829
|
+
Change logic around battery status so 0 is offline and others values are online.
|
830
|
+
|
798
831
|
2.8.1<br>
|
799
832
|
Update from v0 to v1 for scheduler API.
|
800
833
|
PVEnergyTotal added to report variables.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|