foxesscloud 2.8.0__py3-none-any.whl → 2.8.2__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.
- foxesscloud/foxesscloud.py +13 -7
- foxesscloud/openapi.py +6 -8
- {foxesscloud-2.8.0.dist-info → foxesscloud-2.8.2.dist-info}/METADATA +17 -2
- foxesscloud-2.8.2.dist-info/RECORD +7 -0
- foxesscloud-2.8.0.dist-info/RECORD +0 -7
- {foxesscloud-2.8.0.dist-info → foxesscloud-2.8.2.dist-info}/LICENCE +0 -0
- {foxesscloud-2.8.0.dist-info → foxesscloud-2.8.2.dist-info}/WHEEL +0 -0
- {foxesscloud-2.8.0.dist-info → foxesscloud-2.8.2.dist-info}/top_level.txt +0 -0
foxesscloud/foxesscloud.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud
|
4
|
-
Updated:
|
4
|
+
Updated: 09 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.4"
|
14
14
|
print(f"FoxESS-Cloud version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -656,7 +656,9 @@ def get_battery(info=1, rated=None, count=None):
|
|
656
656
|
battery['residual_handling'] = residual_handling
|
657
657
|
battery['soh'] = None
|
658
658
|
battery['soh_supported'] = False
|
659
|
-
if battery.get('status') is None
|
659
|
+
if battery.get('status') is None:
|
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:
|
660
662
|
output(f"** get_battery(): battery status not available")
|
661
663
|
return None
|
662
664
|
if battery.get('residual') is not None:
|
@@ -733,7 +735,7 @@ def get_batteries(info=1, rated=None, count=None):
|
|
733
735
|
while len(count) < len(batteries):
|
734
736
|
count.append(None)
|
735
737
|
for i,b in enumerate(batteries):
|
736
|
-
if b.get('status') is None or b['status']
|
738
|
+
if b.get('status') is None or b['status'] == 0:
|
737
739
|
output(f"** get_batteries(): battery {i+1} status not available")
|
738
740
|
continue
|
739
741
|
b['residual_handling'] = residual_handling
|
@@ -752,7 +754,7 @@ def get_batteries(info=1, rated=None, count=None):
|
|
752
754
|
b['soh'] = int(soh) if soh.isnumeric() and int(soh) > 10 else None
|
753
755
|
b['soh_supported'] = b['soh'] is not None
|
754
756
|
for i, b in enumerate(batteries):
|
755
|
-
if b.get('status') is None or b['status']
|
757
|
+
if b.get('status') is None or b['status'] == 0:
|
756
758
|
continue
|
757
759
|
if i == 0:
|
758
760
|
residual_handling = b['residual_handling']
|
@@ -970,6 +972,7 @@ merge_settings = { # keys to add
|
|
970
972
|
'h116__': 'operation_mode__work_mode',
|
971
973
|
'h117__': 'operation_mode__work_mode',
|
972
974
|
# 'k106__': 'operation_mode__work_mode',
|
975
|
+
# 'k110__': 'operation_mode__work_mode',
|
973
976
|
},
|
974
977
|
'values': ['SelfUse', 'Feedin', 'Backup']},
|
975
978
|
'ExportLimit': {'keys': {
|
@@ -977,6 +980,7 @@ merge_settings = { # keys to add
|
|
977
980
|
'h116__': 'basic2__05',
|
978
981
|
'h117__': 'basic2__05',
|
979
982
|
# 'k106__': 'basic2__05',
|
983
|
+
# 'k1110__': 'basic2__05',
|
980
984
|
},
|
981
985
|
'valueType': 'int'},
|
982
986
|
'BatteryVolt': {'keys': {
|
@@ -984,6 +988,7 @@ merge_settings = { # keys to add
|
|
984
988
|
'h116__': ['h116__15', 'h116__16', 'h116__17'],
|
985
989
|
'h117__': ['h117__15', 'h117__16', 'h117__17'],
|
986
990
|
# 'k106__': ['k106__xx', 'k106__xx', 'k106__xx'],
|
991
|
+
# 'k110__': ['k110__xx', 'k110__xx', 'k110__xx'],
|
987
992
|
},
|
988
993
|
'type': 'list',
|
989
994
|
'valueType': 'float',
|
@@ -993,6 +998,7 @@ merge_settings = { # keys to add
|
|
993
998
|
'h116__': 'h116__18',
|
994
999
|
'h117__': 'h117__18',
|
995
1000
|
# 'k106__': 'k106__xx',
|
1001
|
+
# 'k110__': 'k110__xx',
|
996
1002
|
},
|
997
1003
|
'type': 'list',
|
998
1004
|
'valueType': 'int',
|
@@ -3086,7 +3092,7 @@ def charge_needed(forecast=None, consumption=None, update_settings=0, timed_mode
|
|
3086
3092
|
else:
|
3087
3093
|
# get device and battery info from inverter
|
3088
3094
|
get_battery()
|
3089
|
-
if battery is None or battery['status']
|
3095
|
+
if battery is None or battery['status'] == 0:
|
3090
3096
|
return None
|
3091
3097
|
current_soc = battery['soc']
|
3092
3098
|
bat_volt = battery['volt']
|
@@ -4482,7 +4488,7 @@ class Solar :
|
|
4482
4488
|
if debug_setting > 0 and not quiet:
|
4483
4489
|
print(f"Getting data for {name} array")
|
4484
4490
|
path = f"{a['lat']}/{a['lon']}/{a['dec']}/{a['az']}/{a['kwp']}"
|
4485
|
-
params = {'
|
4491
|
+
params = {'no_sun': 1, 'damping': a['dam'], 'inverter': a['inv'], 'horizon': a['hor']}
|
4486
4492
|
response = requests.get(solar_url + self.api_key + 'estimate/' + path, params = params)
|
4487
4493
|
if response.status_code != 200:
|
4488
4494
|
if response.status_code == 429:
|
foxesscloud/openapi.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
##################################################################################################
|
2
2
|
"""
|
3
3
|
Module: Fox ESS Cloud using Open API
|
4
|
-
Updated:
|
4
|
+
Updated: 09 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.2"
|
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']
|
@@ -2756,7 +2754,7 @@ def charge_needed(forecast=None, consumption=None, update_settings=0, timed_mode
|
|
2756
2754
|
else:
|
2757
2755
|
# get device and battery info from inverter
|
2758
2756
|
get_battery()
|
2759
|
-
if battery is None or battery['status']
|
2757
|
+
if battery is None or battery['status'] == 0:
|
2760
2758
|
return None
|
2761
2759
|
current_soc = battery['soc']
|
2762
2760
|
bat_volt = battery['volt']
|
@@ -4153,7 +4151,7 @@ class Solar :
|
|
4153
4151
|
if debug_setting > 0 and not quiet:
|
4154
4152
|
print(f"Getting data for {name} array")
|
4155
4153
|
path = f"{a['lat']}/{a['lon']}/{a['dec']}/{a['az']}/{a['kwp']}"
|
4156
|
-
params = {'
|
4154
|
+
params = {'no_sun': 1, 'damping': a['dam'], 'inverter': a['inv'], 'horizon': a['hor']}
|
4157
4155
|
response = requests.get(solar_url + self.api_key + 'estimate/' + path, params = params)
|
4158
4156
|
if response.status_code != 200:
|
4159
4157
|
if response.status_code == 429:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foxesscloud
|
3
|
-
Version: 2.8.
|
3
|
+
Version: 2.8.2
|
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
|
@@ -620,6 +620,17 @@ Plunge pricing allows for the automatic configuration of charging periods when A
|
|
620
620
|
# PV Output
|
621
621
|
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
622
|
|
623
|
+
## Calibration
|
624
|
+
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:
|
625
|
+
|
626
|
+
```
|
627
|
+
f.pv_calibration = 0.98
|
628
|
+
f.ct2_calibration = 0.92
|
629
|
+
```
|
630
|
+
* 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
|
631
|
+
|
632
|
+
* 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.
|
633
|
+
|
623
634
|
|
624
635
|
## Get PV Output Data
|
625
636
|
|
@@ -809,7 +820,11 @@ This setting can be:
|
|
809
820
|
|
810
821
|
# Version Info
|
811
822
|
|
812
|
-
2.8.
|
823
|
+
2.8.2<br>
|
824
|
+
Fix forecast.solar (after change to start parameter processing).
|
825
|
+
Change logic around battery status so 0 is offline and others values are online.
|
826
|
+
|
827
|
+
2.8.1<br>
|
813
828
|
Update from v0 to v1 for scheduler API.
|
814
829
|
PVEnergyTotal added to report variables.
|
815
830
|
Fix residual if capacity is specified for charge_needed().
|
@@ -0,0 +1,7 @@
|
|
1
|
+
foxesscloud/foxesscloud.py,sha256=vX5EffYUgLaeeHJImRVBPaQCCykthPBaT8AyyuoeoJM,224362
|
2
|
+
foxesscloud/openapi.py,sha256=LuB2NpQZKQ1TSWWQ-8DAnDZ4CuBHjj6EH8Q0PnHmyGI,208392
|
3
|
+
foxesscloud-2.8.2.dist-info/LICENCE,sha256=8JF-24QkE8UfdII-g6RaIEvM-PZ9zwaEcxlwYUDMt-4,1079
|
4
|
+
foxesscloud-2.8.2.dist-info/METADATA,sha256=W_DdQjHq-w_8eLQ8aI9AdDKUq2LY-Wnxt_BTmuRpGWE,64767
|
5
|
+
foxesscloud-2.8.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
6
|
+
foxesscloud-2.8.2.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
|
7
|
+
foxesscloud-2.8.2.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
foxesscloud/foxesscloud.py,sha256=_lR2MAYUx-7A6h8JuYwiYp8Ley7p_NUCdEYe2CsHaBE,224079
|
2
|
-
foxesscloud/openapi.py,sha256=xrR5fxenKnDbJmU7HGq3j-JBtB9yu-P0EcsTlE1ZhQw,208461
|
3
|
-
foxesscloud-2.8.0.dist-info/LICENCE,sha256=8JF-24QkE8UfdII-g6RaIEvM-PZ9zwaEcxlwYUDMt-4,1079
|
4
|
-
foxesscloud-2.8.0.dist-info/METADATA,sha256=cn1q40MOrSrZJhbDCZgjZ0-Pi3u1mRmBHV3XDCKC7jE,63522
|
5
|
-
foxesscloud-2.8.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
6
|
-
foxesscloud-2.8.0.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
|
7
|
-
foxesscloud-2.8.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|