Skip to content

Commit

Permalink
Smartmeter Support and large refactor of JSON handling utility (#170)
Browse files Browse the repository at this point in the history
* Feature: add SmartMeter support

* Fix: Add temprature sensor into auto-generic class

* compat: use pre py3.10 union typing in jfollow

* test: backport test for following json paths

* test: bringing back more accidentally removed tests

* tests: explain why we test follow helper

* tests: be more concise

* test&fix: bring back old switchbox tests, fix regression in switchbox family and wind sensor

---------

Co-authored-by: Michał Jaworski <[email protected]>
  • Loading branch information
pvsti and swistakm authored Apr 19, 2024
1 parent 4fef17d commit 60e9dec
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 469 deletions.
85 changes: 0 additions & 85 deletions blebox_uniapi/box.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import re
import asyncio
import time

Expand All @@ -19,7 +18,6 @@
from .error import (
UnsupportedBoxResponse,
UnsupportedBoxVersion,
JPathFailed,
BadFieldExceedsMax,
BadFieldLessThanMin,
BadFieldMissing,
Expand Down Expand Up @@ -282,89 +280,6 @@ async def async_api_command(self, command: str, value: Any = None) -> None:
self._last_real_update = None # force update
return await self._async_api(False, method, *args)

def follow(self, data: dict, path: str) -> Any:
"""
Return payload from device response json.
:param self:
:param data:
:param path:
:return:
"""
if data is None:
raise RuntimeError(f"bad argument: data {data}") # pragma: no cover

results = path.split("/")
current_tree = data

for chunk in results:
with_string_value = re.compile(r"^\[(.*)='(.*)']$")
match = with_string_value.match(chunk)
if match:
name = match.group(1)
value = match.group(2)

found = False

for item in current_tree:
if item[name] == value:
current_tree = item
found = True
break

if not found:
raise JPathFailed(f"with: {name}={value}", path, data)

continue # pragma: no cover

with_int_value = re.compile(r"^\[(.*)=(\d+)]$")
match = with_int_value.match(chunk)
if match:
name = match.group(1)
value = int(match.group(2))

found = False

if not isinstance(current_tree, list):
raise JPathFailed(
f"list expected but got {current_tree}", path, data
)

for item in current_tree:
if item[name] == value:
current_tree = item
found = True
break

if not found:
raise JPathFailed(f"with: {name}={value}", path, data)
continue # pragma: no cover

with_index = re.compile(r"^\[(\d+)]$")
match = with_index.match(chunk)
if match:
index = int(match.group(1))
if not isinstance(current_tree, list) or index >= len(current_tree):
raise JPathFailed(f"with value at index {index}", path, data)

current_tree = current_tree[index]
continue

if isinstance(current_tree, dict):
names = current_tree.keys()
if chunk not in names:
raise JPathFailed(
f"item '{chunk}' not among {list(names)}", path, data
)

current_tree = current_tree[chunk]
else:
raise JPathFailed(
f"unexpected item type: '{chunk}' not in: {current_tree}",
path,
data,
)
return current_tree

def expect_int(
self, field: str, raw_value: int, maximum: int = -1, minimum: int = 0
) -> int:
Expand Down
Loading

0 comments on commit 60e9dec

Please sign in to comment.