Skip to content

Commit

Permalink
refactor: Reuse ParameterParser between requests
Browse files Browse the repository at this point in the history
  • Loading branch information
davidrapan committed Aug 14, 2024
1 parent 02477b9 commit 6771447
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
13 changes: 5 additions & 8 deletions custom_components/solarman/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ async def load(self, name, mac, path, file):
self.lookup_file = file if file else "deye_hybrid.yaml"
self.model = self.lookup_file.replace(".yaml", "")
self.parameter_definition = await yaml_open(self.lookup_path + self.lookup_file)
self.profile = ParameterParser(self.parameter_definition)

if "info" in self.parameter_definition and "model" in self.parameter_definition["info"]:
info = self.parameter_definition["info"]
Expand Down Expand Up @@ -142,10 +143,7 @@ async def async_read(self, params, code, start, end) -> None:
params.parse(response, start, quantity)

def get_sensors(self):
if self.parameter_definition:
params = ParameterParser(self.parameter_definition)
return params.get_sensors()
return []
return self.profile.get_sensors() if self.parameter_definition else []

def get_connection_state(self):
if self.state > 0:
Expand Down Expand Up @@ -176,8 +174,7 @@ async def async_get_failed(self, message = None):
raise UpdateFailed(message)

async def async_get(self, runtime = 0):
params = ParameterParser(self.parameter_definition)
requests = params.get_requests(runtime)
requests = self.profile.get_requests(runtime)
requests_count = len(requests) if requests else 0
results = [0] * requests_count

Expand All @@ -199,7 +196,7 @@ async def async_get(self, runtime = 0):
attempts_left -= 1

try:
await self.async_read(params, code, start, end)
await self.async_read(self.profile, code, start, end)
results[i] = 1
except (V5FrameError, TimeoutError, Exception) as e:
results[i] = 0
Expand All @@ -215,7 +212,7 @@ async def async_get(self, runtime = 0):
break

if not 0 in results:
return self.get_result(params)
return self.get_result(self.profile)
else:
await self.async_get_failed(f"Querying {self.serial} at {self.address}:{self.port} failed.")

Expand Down
3 changes: 3 additions & 0 deletions custom_components/solarman/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ async def yaml_open(file):
async with aiofiles.open(file) as f:
return yaml.safe_load(await f.read())

def all_same(values):
return all(i == values[0] for i in values)

def group_when(iterable, predicate):
i, x, size = 0, 0, len(iterable)
while i < size - 1:
Expand Down
14 changes: 9 additions & 5 deletions custom_components/solarman/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ def __init__(self, profile):
for r in i["registers"]:
self._registers_table[r] = (i["code"] if isinstance(i["code"], int) else i["code"]["read"]) if "code" in i else (p["code"] if "code" in p else (requests_table[r] if r in requests_table else self._code))

self._lambda = lambda x, y: y - x > self._min_span
self._lambda_code_aware = lambda x, y: self._registers_table[x] != self._registers_table[y] or y - x > self._min_span

def flush_states(self):
self._result = {}

def parameters(self):
return self._profile["parameters"]

Expand Down Expand Up @@ -80,6 +86,8 @@ def get_sensors(self):
return result

def get_requests(self, runtime = 0):
self.flush_states()

if "requests" in self._profile and "requests_fine_control" in self._profile:
_LOGGER.debug("Fine control of request sets is enabled!")
return self._profile["requests"]
Expand All @@ -99,11 +107,7 @@ def get_requests(self, runtime = 0):

registers.sort()

registers_table_values = list(self._registers_table.values())

predicate = (lambda x, y: y - x > self._min_span) if all(i == registers_table_values[0] for i in registers_table_values) else (lambda x, y: self._registers_table[x] != self._registers_table[y] or y - x > self._min_span)

groups = group_when(registers, predicate)
groups = group_when(registers, self._lambda if all_same(list(self._registers_table.values())) else self._lambda_code_aware)

return [{ REQUEST_START: r[0], REQUEST_END: r[-1], REQUEST_CODE: self._registers_table[r[0]] } for r in groups]

Expand Down

0 comments on commit 6771447

Please sign in to comment.