foxesscloud 2.7.4__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 -16
- foxesscloud/openapi.py +24 -20
- {foxesscloud-2.7.4.dist-info → foxesscloud-2.7.6.dist-info}/METADATA +7 -2
- foxesscloud-2.7.6.dist-info/RECORD +7 -0
- foxesscloud-2.7.4.dist-info/RECORD +0 -7
- {foxesscloud-2.7.4.dist-info → foxesscloud-2.7.6.dist-info}/LICENCE +0 -0
- {foxesscloud-2.7.4.dist-info → foxesscloud-2.7.6.dist-info}/WHEEL +0 -0
- {foxesscloud-2.7.4.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
|
@@ -1249,9 +1250,6 @@ def get_flag():
|
|
1249
1250
|
return None
|
1250
1251
|
result = response.json().get('result')
|
1251
1252
|
if result is None:
|
1252
|
-
errno = response.json().get('errno')
|
1253
|
-
if errno == 40256:
|
1254
|
-
output(f"** get_flag(), not suported on this device")
|
1255
1253
|
return None
|
1256
1254
|
if schedule is None:
|
1257
1255
|
schedule = {'enable': None, 'support': None, 'pollcy': None}
|
@@ -3067,7 +3065,7 @@ def charge_needed(forecast=None, update_settings=0, timed_mode=None, show_data=N
|
|
3067
3065
|
output(f"full_charge = {full_charge}")
|
3068
3066
|
if test_soc is not None:
|
3069
3067
|
current_soc = test_soc
|
3070
|
-
capacity = 14.
|
3068
|
+
capacity = 14.36
|
3071
3069
|
residual = test_soc * capacity / 100
|
3072
3070
|
bat_volt = 317.4
|
3073
3071
|
bat_power = 0.0
|
@@ -3919,7 +3917,7 @@ def get_pvoutput(d = None, tou = 0):
|
|
3919
3917
|
export_tou = ',,,'
|
3920
3918
|
# process list of report_data values (no TOU)
|
3921
3919
|
for var in report_data:
|
3922
|
-
wh = int(var['total'] * 1000)
|
3920
|
+
wh = int(var['total'] * 1000) if var['total'] is not None else 0
|
3923
3921
|
if var['variable'] == 'feedin':
|
3924
3922
|
export_wh = wh
|
3925
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
|
@@ -1006,8 +1012,6 @@ def get_flag():
|
|
1006
1012
|
return None
|
1007
1013
|
result = response.json().get('result')
|
1008
1014
|
if result is None:
|
1009
|
-
if errno == 40256:
|
1010
|
-
output(f"** get_flag(), not suported on this device")
|
1011
1015
|
return None
|
1012
1016
|
if schedule is None:
|
1013
1017
|
schedule = {'enable': None, 'support': None, 'periods': None}
|
@@ -2732,7 +2736,7 @@ def charge_needed(forecast=None, update_settings=0, timed_mode=None, show_data=N
|
|
2732
2736
|
output(f"full_charge = {full_charge}")
|
2733
2737
|
if test_soc is not None:
|
2734
2738
|
current_soc = test_soc
|
2735
|
-
capacity = 14.
|
2739
|
+
capacity = 14.36
|
2736
2740
|
residual = test_soc * capacity / 100
|
2737
2741
|
bat_volt = 317.4
|
2738
2742
|
bat_power = 0.0
|
@@ -3585,7 +3589,7 @@ def get_pvoutput(d = None, tou = 0):
|
|
3585
3589
|
export_tou = ',,,'
|
3586
3590
|
# process list of report_data values (no TOU)
|
3587
3591
|
for var in report_data:
|
3588
|
-
wh = int(var['total'] * 1000)
|
3592
|
+
wh = int(var['total'] * 1000) if var['total'] is not None else 0
|
3589
3593
|
if var['variable'] == 'feedin':
|
3590
3594
|
export_wh = wh
|
3591
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,7 +807,12 @@ This setting can be:
|
|
807
807
|
|
808
808
|
# Version Info
|
809
809
|
|
810
|
-
2.7.
|
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
|
+
|
815
|
+
2.7.5<br>
|
811
816
|
Update to support T series inverters.
|
812
817
|
|
813
818
|
2.7.3<br>
|
@@ -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=-StB3jyYKQc0dIdzx0vZK8eBHgThZMwT9rquaXo6gh4,222979
|
2
|
-
foxesscloud/openapi.py,sha256=tcc83zs1e_Z9aKc0l9r5LYA5Mi0-c1i-hlaR-vOnfVU,207126
|
3
|
-
foxesscloud-2.7.4.dist-info/LICENCE,sha256=-3xv8CElCJV8Bc8PbAsg3iyxMpAK8MoJneM3rXigxqI,1074
|
4
|
-
foxesscloud-2.7.4.dist-info/METADATA,sha256=A8wIra0loiQQ0DuliBSRn_BcmmcDGw3j8VLTuB2h2S8,62438
|
5
|
-
foxesscloud-2.7.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
6
|
-
foxesscloud-2.7.4.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
|
7
|
-
foxesscloud-2.7.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|