Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Ongoing

- PR [342](https://github.com/plugwise/python-plugwise-usb/pull/342): Improve node_type chaching.

## 0.46.0 - 2025-09-12

- PR [338](https://github.com/plugwise/python-plugwise-usb/pull/338): Append report interval to Sense node configuration
Expand Down
24 changes: 17 additions & 7 deletions plugwise_usb/network/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ async def save_cache(self) -> None:
"""Save the node information to file."""
cache_data_to_save: dict[str, str] = {}
for mac, node_type in self._nodetypes.items():
node_value = str(node_type)
cache_data_to_save[mac] = node_value
_LOGGER.debug("Save NodeTypes %s", str(len(cache_data_to_save)))
await self.write_cache(cache_data_to_save)
cache_data_to_save[mac] = node_type.name
_LOGGER.debug("Save NodeTypes for %s Nodes", (len(cache_data_to_save)))
await self.write_cache(
cache_data_to_save, True
) # rewrite set to True is required

async def clear_cache(self) -> None:
"""Clear current cache."""
Expand All @@ -44,11 +45,16 @@ async def restore_cache(self) -> None:
self._nodetypes = {}
for mac, node_value in data.items():
node_type: NodeType | None = None
if len(node_value) >= 10:
# Backward-compatible parsing: support full enums, enum names, or numeric values
val = node_value.strip()
key = (val.split(".", 1)[1] if val.startswith("NodeType.") else val).upper()
node_type = NodeType.__members__.get(key) # e.g., "CIRCLE"
if node_type is None:
try:
node_type = NodeType[node_value[9:]]
except KeyError:
node_type = NodeType(int(val))
except ValueError:
node_type = None

if node_type is None:
_LOGGER.warning("Invalid NodeType in cache: %s", node_value)
continue
Expand Down Expand Up @@ -86,5 +92,9 @@ async def prune_cache(self, registry: list[str]) -> None:
continue
if (node_type := self.get_nodetype(mac)) is not None:
new_nodetypes[mac] = node_type

if new_nodetypes == self._nodetypes:
_LOGGER.debug("prune_cache: no changes; skipping save")
return
self._nodetypes = new_nodetypes
await self.save_cache()
12 changes: 6 additions & 6 deletions tests/test_usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1712,9 +1712,9 @@ async def makedirs(cache_dir: str, exist_ok: bool) -> None:

# test with valid data
mock_read_data = [
"0123456789ABCDEF;NodeType.CIRCLE_PLUS",
"0123456789ABCDEF;CIRCLE_PLUS",
"FEDCBA9876543210;NodeType.CIRCLE",
"1298347650AFBECD;NodeType.SCAN",
"1298347650AFBECD;6",
]
file_chunks_iter = iter(mock_read_data)
mock_file_stream = MagicMock(readlines=lambda *args, **kwargs: file_chunks_iter)
Expand All @@ -1733,10 +1733,10 @@ async def makedirs(cache_dir: str, exist_ok: bool) -> None:
)
mock_file_stream.writelines.assert_called_with(
[
"0123456789ABCDEF;NodeType.CIRCLE_PLUS\n",
"FEDCBA9876543210;NodeType.CIRCLE\n",
"1298347650AFBECD;NodeType.SCAN\n",
"1234ABCD4321FEDC;NodeType.STEALTH\n",
"0123456789ABCDEF;CIRCLE_PLUS\n",
"FEDCBA9876543210;CIRCLE\n",
"1298347650AFBECD;SCAN\n",
"1234ABCD4321FEDC;STEALTH\n",
]
)
assert pw_nw_cache.nodetypes == {
Expand Down