foxesscloud 2.8.2__py3-none-any.whl → 2.8.4__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.
@@ -1,7 +1,7 @@
1
1
  ##################################################################################################
2
2
  """
3
3
  Module: Fox ESS Cloud
4
- Updated: 09 April 2025
4
+ Updated: 21 May 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.4"
13
+ version = "1.9.6"
14
14
  print(f"FoxESS-Cloud version {version}")
15
15
 
16
16
  debug_setting = 1
@@ -971,6 +971,7 @@ merge_settings = { # keys to add
971
971
  'h115__': 'operation_mode__work_mode',
972
972
  'h116__': 'operation_mode__work_mode',
973
973
  'h117__': 'operation_mode__work_mode',
974
+ 'h118__': 'operation_mode__work_mode',
974
975
  # 'k106__': 'operation_mode__work_mode',
975
976
  # 'k110__': 'operation_mode__work_mode',
976
977
  },
@@ -979,6 +980,7 @@ merge_settings = { # keys to add
979
980
  'h115__': 'basic2__05',
980
981
  'h116__': 'basic2__05',
981
982
  'h117__': 'basic2__05',
983
+ 'h118__': 'basic2__05',
982
984
  # 'k106__': 'basic2__05',
983
985
  # 'k1110__': 'basic2__05',
984
986
  },
@@ -987,6 +989,7 @@ merge_settings = { # keys to add
987
989
  'h115__': ['h115__14', 'h115__15', 'h115__16'],
988
990
  'h116__': ['h116__15', 'h116__16', 'h116__17'],
989
991
  'h117__': ['h117__15', 'h117__16', 'h117__17'],
992
+ 'h118__': ['h118__15', 'h118__16', 'h118__17'],
990
993
  # 'k106__': ['k106__xx', 'k106__xx', 'k106__xx'],
991
994
  # 'k110__': ['k110__xx', 'k110__xx', 'k110__xx'],
992
995
  },
@@ -997,6 +1000,7 @@ merge_settings = { # keys to add
997
1000
  'h115__': 'h115__17',
998
1001
  'h116__': 'h116__18',
999
1002
  'h117__': 'h117__18',
1003
+ 'h118__': 'h118__18',
1000
1004
  # 'k106__': 'k106__xx',
1001
1005
  # 'k110__': 'k110__xx',
1002
1006
  },
@@ -1005,6 +1009,13 @@ merge_settings = { # keys to add
1005
1009
  'unit': '℃'},
1006
1010
  }
1007
1011
 
1012
+ # change named settings, if required, so names match between Fox API and Open API
1013
+ translate_names = {
1014
+ 'MaxSoc': 'MaximumSoC',
1015
+ 'MinSoc': 'MinimumSoC',
1016
+ 'MinSocOnGrid': 'MinimumSoC-OnGrid'
1017
+ }
1018
+
1008
1019
  def get_ui():
1009
1020
  global device_id, debug_setting, messages, remote_settings, named_settings, merge_settings
1010
1021
  if get_device() is None:
@@ -1069,7 +1080,7 @@ def get_ui():
1069
1080
  return remote_settings
1070
1081
 
1071
1082
  def get_remote_settings(key):
1072
- global device_id, debug_setting, messages
1083
+ global device_id, debug_setting, messages, translate_settings
1073
1084
  if get_device() is None:
1074
1085
  return None
1075
1086
  output(f"getting remote settings", 2)
@@ -1101,7 +1112,7 @@ def get_remote_settings(key):
1101
1112
  return values
1102
1113
 
1103
1114
  def get_named_settings(name):
1104
- global named_settings
1115
+ global named_settings, translate_names
1105
1116
  if get_device() is None:
1106
1117
  return None
1107
1118
  if type(name) is list:
@@ -1109,10 +1120,11 @@ def get_named_settings(name):
1109
1120
  for n in name:
1110
1121
  result.append(get_named_settings(n))
1111
1122
  return result
1112
- if named_settings is None or named_settings.get(name) is None:
1123
+ key_name = translate_names[name] if translate_names.get(name) is not None else name
1124
+ if named_settings is None or named_settings.get(key_name) is None:
1113
1125
  output(f"** get_named_settings(): {name} was not recognised")
1114
1126
  return None
1115
- keys = named_settings[name].get('keys')
1127
+ keys = named_settings[key_name].get('keys')
1116
1128
  if keys is None:
1117
1129
  output(f"** get_named_settings(): no keys for name: {name}")
1118
1130
  return None
@@ -1121,8 +1133,8 @@ def get_named_settings(name):
1121
1133
  if result is None:
1122
1134
  output(f"** get_named_settings(): no result for {name} using key: {keys}")
1123
1135
  return None
1124
- result_type = named_settings[name].get('type')
1125
- value_type = named_settings[name].get('valueType')
1136
+ result_type = named_settings[key_name].get('type')
1137
+ value_type = named_settings[key_name].get('valueType')
1126
1138
  if result_type is None:
1127
1139
  v = result.get([k for k in result.keys()][0])
1128
1140
  return v if value_type is None else c_float(v) if value_type == 'float' else c_int(v)
@@ -1134,7 +1146,7 @@ def get_named_settings(name):
1134
1146
  return result
1135
1147
 
1136
1148
  def set_named_settings(name, value, force=0):
1137
- global named_settings
1149
+ global named_settings, translate_names
1138
1150
  if get_device() is None:
1139
1151
  return None
1140
1152
  if force == 1 and get_schedule().get('enable'):
@@ -1144,18 +1156,19 @@ def set_named_settings(name, value, force=0):
1144
1156
  for (n, v) in name:
1145
1157
  result.append(set_named_settings(name=n, value=v))
1146
1158
  return result
1147
- if named_settings is None or named_settings.get(name) is None:
1159
+ key_name = translate_names[name] if translate_names.get(name) is not None else name
1160
+ if named_settings is None or named_settings.get(key_name) is None:
1148
1161
  output(f"** set_named_settings(): {name} was not recognised")
1149
1162
  return None
1150
- keys = named_settings[name].get('keys')
1163
+ keys = named_settings[key_name].get('keys')
1151
1164
  if keys is None:
1152
1165
  output(f"** set_named_settings(): no keys for name: {name}")
1153
1166
  return None
1154
- item_type = named_settings[name].get('type')
1167
+ item_type = named_settings[key_name].get('type')
1155
1168
  if item_type is None:
1156
1169
  values = {keys: str(value)}
1157
1170
  elif item_type == 'block':
1158
- items = named_setting[name]['items']
1171
+ items = named_setting[key_name]['items']
1159
1172
  n = len(items)
1160
1173
  if type(value) is not list or n != len(value):
1161
1174
  output(f"** set_named_settings(): {name} requires list of {n} values")
@@ -3885,7 +3898,7 @@ def get_pvoutput(d = None, tou = 0):
3885
3898
  if type(d) is list:
3886
3899
  print(f"---------------- get_pvoutput ------------------")
3887
3900
  print(f"Date range {d[0]} to {d[-1]} has {len(d)} days")
3888
- if tou == 1:
3901
+ if tou == 1 and tariff is not None:
3889
3902
  print(f"Time of use: {tariff['name']}")
3890
3903
  elif tou == 2:
3891
3904
  print(f"All values integrated from power")
foxesscloud/openapi.py CHANGED
@@ -1,7 +1,7 @@
1
1
  ##################################################################################################
2
2
  """
3
3
  Module: Fox ESS Cloud using Open API
4
- Updated: 09 April 2025
4
+ Updated: 20 May 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.2"
13
+ version = "2.8.4"
14
14
  print(f"FoxESS-Cloud Open API version {version}")
15
15
 
16
16
  debug_setting = 1
@@ -861,6 +861,7 @@ def get_remote_settings(name):
861
861
  values[x] = v[x]
862
862
  return values
863
863
  body = {'sn': device_sn, 'key': name}
864
+ setting_delay()
864
865
  response = signed_post(path="/op/v0/device/setting/get", body=body)
865
866
  if response.status_code != 200:
866
867
  output(f"** get_remote_settings() got response code {response.status_code}: {response.reason}")
@@ -1016,10 +1017,9 @@ def get_flag():
1016
1017
  if result is None:
1017
1018
  return None
1018
1019
  if schedule is None:
1019
- schedule = {'enable': None, 'support': None, 'periods': None}
1020
+ schedule = {'enable': None, 'support': None, 'periods': None, 'maxsoc': False}
1020
1021
  schedule['enable'] = result.get('enable')
1021
1022
  schedule['support'] = result.get('support')
1022
- schedule['maxsoc'] = False
1023
1023
  if device.get('function') is not None and device['function'].get('scheduler') is not None:
1024
1024
  device['function']['scheduler'] = schedule['support']
1025
1025
  return schedule
@@ -1055,6 +1055,8 @@ def get_schedule():
1055
1055
  for g in result['groups']:
1056
1056
  if g['enable'] == 1 and g['workMode'] in work_modes:
1057
1057
  schedule['periods'].append(g)
1058
+ if g.get('maxSoc') is not None:
1059
+ schedule['maxsoc'] = True
1058
1060
  return schedule
1059
1061
 
1060
1062
  # build strategy using current schedule
@@ -3548,7 +3550,7 @@ def get_pvoutput(d = None, tou = 0):
3548
3550
  if type(d) is list:
3549
3551
  print(f"---------------- get_pvoutput ------------------")
3550
3552
  print(f"Date range {d[0]} to {d[-1]} has {len(d)} days")
3551
- if tou == 1:
3553
+ if tou == 1 and tariff is not None:
3552
3554
  print(f"Time of use: {tariff['name']}")
3553
3555
  elif tou == 2:
3554
3556
  print(f"All values integrated from power")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foxesscloud
3
- Version: 2.8.2
3
+ Version: 2.8.4
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
- + the only name currently supported by Fox is 'ExportLimit' and this is only available for H3 inverters.
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
- + A return value of 1 is success. 0 means setting failed. None is another error e.g. device not found, invalid name or value.
198
- + the only 'name' currently supported is 'ExportLimit'
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
@@ -820,6 +821,12 @@ This setting can be:
820
821
 
821
822
  # Version Info
822
823
 
824
+ 2.8.4<br>
825
+ Fix exception when calling pvoutput with tou=1 but no tariff set.
826
+
827
+ 2.8.3<br>
828
+ Update to support setting Max Soc in schedules now this is supported by Fox using Open API.
829
+
823
830
  2.8.2<br>
824
831
  Fix forecast.solar (after change to start parameter processing).
825
832
  Change logic around battery status so 0 is offline and others values are online.
@@ -0,0 +1,7 @@
1
+ foxesscloud/foxesscloud.py,sha256=_Su3Dcs0CSM2TlbAmCtouM4LkhYfYZ2Bk70eVgZqBJg,225011
2
+ foxesscloud/openapi.py,sha256=HNpg7Uh1PNoNI9Tvq3-bng7dX7_h9Woz2VTh0lL68R4,208505
3
+ foxesscloud-2.8.4.dist-info/LICENCE,sha256=8JF-24QkE8UfdII-g6RaIEvM-PZ9zwaEcxlwYUDMt-4,1079
4
+ foxesscloud-2.8.4.dist-info/METADATA,sha256=nzqI_BgDTsAYr8rFWDKd7kX8sCBf9yy1IvmSbFc8bZ0,65259
5
+ foxesscloud-2.8.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
6
+ foxesscloud-2.8.4.dist-info/top_level.txt,sha256=IWOrKSNZCLU6IDXSX_b4_bqCfbZoWAT4CC0w0Lg7PuU,12
7
+ foxesscloud-2.8.4.dist-info/RECORD,,
@@ -1,7 +0,0 @@
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,,