foxesscloud 2.7.5__py3-none-any.whl → 2.7.6__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 +14 -13
- foxesscloud/openapi.py +24 -18
- {foxesscloud-2.7.5.dist-info → foxesscloud-2.7.6.dist-info}/METADATA +6 -1
- foxesscloud-2.7.6.dist-info/RECORD +7 -0
- foxesscloud-2.7.5.dist-info/RECORD +0 -7
- {foxesscloud-2.7.5.dist-info → foxesscloud-2.7.6.dist-info}/LICENCE +0 -0
- {foxesscloud-2.7.5.dist-info → foxesscloud-2.7.6.dist-info}/WHEEL +0 -0
- {foxesscloud-2.7.5.dist-info → foxesscloud-2.7.6.dist-info}/top_level.txt +0 -0
foxesscloud/foxesscloud.py
CHANGED
@@ -10,7 +10,7 @@ By: Tony Matthews
|
|
10
10
|
# ALL RIGHTS ARE RESERVED © Tony Matthews 2023
|
11
11
|
##################################################################################################
|
12
12
|
|
13
|
-
version = "1.8.
|
13
|
+
version = "1.8.7"
|
14
14
|
print(f"FoxESS-Cloud version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -435,7 +435,7 @@ device_sn = None
|
|
435
435
|
var_list = None
|
436
436
|
raw_vars = var_list
|
437
437
|
|
438
|
-
def get_device(sn=None):
|
438
|
+
def get_device(sn=None, device_type=None):
|
439
439
|
global device_list, device, device_id, device_sn, firmware, battery, var_list, debug_setting, messages, flag, schedule, templates, remote_settings
|
440
440
|
if get_token() is None:
|
441
441
|
return None
|
@@ -490,31 +490,32 @@ def get_device(sn=None):
|
|
490
490
|
firmware = get_firmware()
|
491
491
|
remote_settings = get_ui()
|
492
492
|
# parse the model code to work out attributes
|
493
|
-
model_code = device['deviceType'].upper()
|
494
|
-
if model_code[
|
495
|
-
|
493
|
+
model_code = device['deviceType'].upper() if device_type is None else device_type
|
494
|
+
if model_code[0] in 'FGRST':
|
495
|
+
phase = '1' if model_code[0] in 'FGS' else '3'
|
496
|
+
model_code = model_code[0] + phase + '-' + model_code[1:]
|
496
497
|
elif model_code[:2] == 'KH':
|
497
498
|
model_code = 'KH-' + model_code[2:]
|
498
499
|
elif model_code[:4] == 'AIO-':
|
499
500
|
model_code = 'AIO' + model_code[4:]
|
500
|
-
device['eps'] = 'E' in model_code
|
501
|
+
device['eps'] = 'E' in model_code[2:]
|
501
502
|
parts = model_code.split('-')
|
502
503
|
model = parts[0]
|
503
|
-
if model not in ['T3', 'KH', 'H1', 'AC1', 'H3', 'AC3', 'AIOH1', 'AIOH3']:
|
504
|
+
if model not in ['F1', 'G1', 'R3', 'S1', 'T3', 'KH', 'H1', 'AC1', 'H3', 'AC3', 'AIOH1', 'AIOH3']:
|
504
505
|
output(f"** device model not recognised for deviceType: {device['deviceType']}")
|
505
506
|
return device
|
506
507
|
device['model'] = model
|
507
508
|
device['phase'] = 3 if model[-1:] == '3' else 1
|
508
509
|
for p in parts[1:]:
|
509
510
|
if p.replace('.','').isnumeric():
|
510
|
-
power = float(p)
|
511
|
-
if power >=
|
512
|
-
device['power'] =
|
511
|
+
power = float(p) / (1000 if model in ['F1', 'S1'] else 1.0)
|
512
|
+
if power >= 0.5 and power < 100.0:
|
513
|
+
device['power'] = power
|
513
514
|
break
|
514
515
|
if device.get('power') is None:
|
515
516
|
output(f"** device power not found for deviceType: {device['deviceType']}")
|
516
517
|
# set max charge current
|
517
|
-
if model in ['T3']:
|
518
|
+
if model in ['F1', 'G1', 'R3', 'S1', 'T3']:
|
518
519
|
device['max_charge_current'] = None
|
519
520
|
elif model in ['KH']:
|
520
521
|
device['max_charge_current'] = 50
|
@@ -3064,7 +3065,7 @@ def charge_needed(forecast=None, update_settings=0, timed_mode=None, show_data=N
|
|
3064
3065
|
output(f"full_charge = {full_charge}")
|
3065
3066
|
if test_soc is not None:
|
3066
3067
|
current_soc = test_soc
|
3067
|
-
capacity = 14.
|
3068
|
+
capacity = 14.36
|
3068
3069
|
residual = test_soc * capacity / 100
|
3069
3070
|
bat_volt = 317.4
|
3070
3071
|
bat_power = 0.0
|
@@ -3916,7 +3917,7 @@ def get_pvoutput(d = None, tou = 0):
|
|
3916
3917
|
export_tou = ',,,'
|
3917
3918
|
# process list of report_data values (no TOU)
|
3918
3919
|
for var in report_data:
|
3919
|
-
wh = int(var['total'] * 1000)
|
3920
|
+
wh = int(var['total'] * 1000) if var['total'] is not None else 0
|
3920
3921
|
if var['variable'] == 'feedin':
|
3921
3922
|
export_wh = wh
|
3922
3923
|
export = f"{wh},"
|
foxesscloud/openapi.py
CHANGED
@@ -10,7 +10,7 @@ By: Tony Matthews
|
|
10
10
|
# ALL RIGHTS ARE RESERVED © Tony Matthews 2024
|
11
11
|
##################################################################################################
|
12
12
|
|
13
|
-
version = "2.7.
|
13
|
+
version = "2.7.6"
|
14
14
|
print(f"FoxESS-Cloud Open API version {version}")
|
15
15
|
|
16
16
|
debug_setting = 1
|
@@ -419,7 +419,7 @@ device_list = None
|
|
419
419
|
device = None
|
420
420
|
device_sn = None
|
421
421
|
|
422
|
-
def get_device(sn=None):
|
422
|
+
def get_device(sn=None, device_type=None):
|
423
423
|
global device_list, device, device_sn, battery, debug_setting, schedule, remote_settings
|
424
424
|
if get_vars() is None:
|
425
425
|
return None
|
@@ -480,31 +480,32 @@ def get_device(sn=None):
|
|
480
480
|
get_generation()
|
481
481
|
# remote_settings = get_ui()
|
482
482
|
# parse the model code to work out attributes
|
483
|
-
model_code = device['deviceType'].upper()
|
484
|
-
if model_code[
|
485
|
-
|
486
|
-
|
483
|
+
model_code = device['deviceType'].upper() if device_type is None else device_type
|
484
|
+
if model_code[0] in 'FGRST':
|
485
|
+
phase = '1' if model_code[0] in 'FGS' else '3'
|
486
|
+
model_code = model_code[0] + phase + '-' + model_code[1:]
|
487
|
+
elif model_code[:2] == 'KH':
|
487
488
|
model_code = 'KH-' + model_code[2:]
|
488
489
|
elif model_code[:4] == 'AIO-':
|
489
490
|
model_code = 'AIO' + model_code[4:]
|
490
|
-
device['eps'] = 'E' in model_code
|
491
|
+
device['eps'] = 'E' in model_code[2:]
|
491
492
|
parts = model_code.split('-')
|
492
493
|
model = parts[0]
|
493
|
-
if model not in ['T3', 'KH', 'H1', 'AC1', 'H3', 'AC3', 'AIOH1', 'AIOH3']:
|
494
|
+
if model not in ['F1', 'G1', 'R3', 'S1', 'T3', 'KH', 'H1', 'AC1', 'H3', 'AC3', 'AIOH1', 'AIOH3']:
|
494
495
|
output(f"** device model not recognised for deviceType: {device['deviceType']}")
|
495
496
|
return device
|
496
497
|
device['model'] = model
|
497
498
|
device['phase'] = 3 if model[-1:] == '3' else 1
|
498
499
|
for p in parts[1:]:
|
499
500
|
if p.replace('.','').isnumeric():
|
500
|
-
power = float(p)
|
501
|
-
if power >=
|
502
|
-
device['power'] =
|
501
|
+
power = float(p) / (1000 if model in ['F1', 'S1'] else 1.0)
|
502
|
+
if power >= 0.5 and power < 100.0:
|
503
|
+
device['power'] = power
|
503
504
|
break
|
504
505
|
if device.get('power') is None:
|
505
506
|
output(f"** device power not found for deviceType: {device['deviceType']}")
|
506
507
|
# set max charge current
|
507
|
-
if model in ['T3']:
|
508
|
+
if model in ['F1', 'G1', 'R3', 'S1', 'T3']:
|
508
509
|
device['max_charge_current'] = None
|
509
510
|
elif model in ['KH']:
|
510
511
|
device['max_charge_current'] = 50
|
@@ -842,7 +843,7 @@ def get_settings():
|
|
842
843
|
named_settings = {}
|
843
844
|
|
844
845
|
def get_remote_settings(name):
|
845
|
-
global device_sn, debug_setting, messages, name_data
|
846
|
+
global device_sn, debug_setting, messages, name_data, named_settings
|
846
847
|
if get_device() is None:
|
847
848
|
return None
|
848
849
|
output(f"getting remote settings", 2)
|
@@ -878,7 +879,7 @@ def get_named_settings(name):
|
|
878
879
|
return get_remote_settings(name)
|
879
880
|
|
880
881
|
def set_named_settings(name, value, force=0):
|
881
|
-
global device_sn, debug_setting
|
882
|
+
global device_sn, debug_setting, named_settings
|
882
883
|
if get_device() is None:
|
883
884
|
return None
|
884
885
|
if force == 1 and get_schedule().get('enable'):
|
@@ -888,6 +889,10 @@ def set_named_settings(name, value, force=0):
|
|
888
889
|
for (n, v) in name:
|
889
890
|
result.append(set_named_settings(name=n, value=v))
|
890
891
|
return result
|
892
|
+
if named_settings.get(name) is None:
|
893
|
+
result = get_named_settings(name)
|
894
|
+
if result is None:
|
895
|
+
return None
|
891
896
|
output(f"\nSetting {name} to {value}", 1)
|
892
897
|
body = {'sn': device_sn, 'key': name, 'value': f"{value}"}
|
893
898
|
setting_delay()
|
@@ -901,8 +906,9 @@ def set_named_settings(name, value, force=0):
|
|
901
906
|
output(f"** cannot update {name} when schedule is active")
|
902
907
|
else:
|
903
908
|
output(f"** set_named_settings(): ({name}, {value}) {errno_message(response)}")
|
904
|
-
return
|
905
|
-
|
909
|
+
return None
|
910
|
+
named_settings[name]['value'] = f"{value}"
|
911
|
+
return value
|
906
912
|
|
907
913
|
##################################################################################################
|
908
914
|
# wrappers for named settings
|
@@ -2730,7 +2736,7 @@ def charge_needed(forecast=None, update_settings=0, timed_mode=None, show_data=N
|
|
2730
2736
|
output(f"full_charge = {full_charge}")
|
2731
2737
|
if test_soc is not None:
|
2732
2738
|
current_soc = test_soc
|
2733
|
-
capacity = 14.
|
2739
|
+
capacity = 14.36
|
2734
2740
|
residual = test_soc * capacity / 100
|
2735
2741
|
bat_volt = 317.4
|
2736
2742
|
bat_power = 0.0
|
@@ -3583,7 +3589,7 @@ def get_pvoutput(d = None, tou = 0):
|
|
3583
3589
|
export_tou = ',,,'
|
3584
3590
|
# process list of report_data values (no TOU)
|
3585
3591
|
for var in report_data:
|
3586
|
-
wh = int(var['total'] * 1000)
|
3592
|
+
wh = int(var['total'] * 1000) if var['total'] is not None else 0
|
3587
3593
|
if var['variable'] == 'feedin':
|
3588
3594
|
export_wh = wh
|
3589
3595
|
export = f"{wh},"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foxesscloud
|
3
|
-
Version: 2.7.
|
3
|
+
Version: 2.7.6
|
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
|
@@ -807,6 +807,11 @@ This setting can be:
|
|
807
807
|
|
808
808
|
# Version Info
|
809
809
|
|
810
|
+
2.7.6<br>
|
811
|
+
Updates to support F, G, R and S series inverters.
|
812
|
+
Updates to set_named_settings() to load metadata if not already done and save new value.
|
813
|
+
Fix divide by zero error when using pvoutput with solar only inverters.
|
814
|
+
|
810
815
|
2.7.5<br>
|
811
816
|
Update to support T series inverters.
|
812
817
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
foxesscloud/foxesscloud.py,sha256=rveGdZDyv3zwQmjw6UzJJKtw_L_lXA2fQFFqMI0lvWI,223108
|
2
|
+
foxesscloud/openapi.py,sha256=GTiyfeMke5i_mLgdYb35pJ0JiCMsFXaMGSXMsqiQ5RI,207522
|
3
|
+
foxesscloud-2.7.6.dist-info/LICENCE,sha256=-3xv8CElCJV8Bc8PbAsg3iyxMpAK8MoJneM3rXigxqI,1074
|
4
|
+
foxesscloud-2.7.6.dist-info/METADATA,sha256=7g3S1fNFk8eL-TiZncUO_2hVIeOod8m5hLm5jEaxMCE,62666
|
5
|
+
foxesscloud-2.7.6.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
6
|
+
foxesscloud-2.7.6.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
|
7
|
+
foxesscloud-2.7.6.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
foxesscloud/foxesscloud.py,sha256=b7DcJs3Ms538CPyMvl8llTile5-gYR6bi31Jf7linqQ,222841
|
2
|
-
foxesscloud/openapi.py,sha256=wn3dJhTth0IKNOT8Uv4bMYxiB5W1WVTEVJhNQqu7pMw,207033
|
3
|
-
foxesscloud-2.7.5.dist-info/LICENCE,sha256=-3xv8CElCJV8Bc8PbAsg3iyxMpAK8MoJneM3rXigxqI,1074
|
4
|
-
foxesscloud-2.7.5.dist-info/METADATA,sha256=NaUsXWSxDtnQFURfkVYYjTQ4eIqYsze3CKg1rvgIpno,62438
|
5
|
-
foxesscloud-2.7.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
6
|
-
foxesscloud-2.7.5.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
|
7
|
-
foxesscloud-2.7.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|