Skip to content

Commit 6293c46

Browse files
committed
Revert rescheduling discovery for now
Update registry caching to only store mac-NodeType combinations
1 parent 23088b2 commit 6293c46

File tree

4 files changed

+88
-155
lines changed

4 files changed

+88
-155
lines changed

plugwise_usb/network/__init__.py

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from ..api import NodeEvent, NodeType, PlugwiseNode, StickEvent
1414
from ..connection import StickController
15-
from ..constants import ENERGY_NODE_TYPES, NODE_DISCOVER_INTERVAL, UTF8
15+
from ..constants import ENERGY_NODE_TYPES, UTF8
1616
from ..exceptions import CacheError, MessageError, NodeError, StickError, StickTimeout
1717
from ..helpers.util import validate_mac
1818
from ..messages.requests import CircleMeasureIntervalRequest, NodePingRequest
@@ -72,8 +72,6 @@ def __init__(
7272
self._unsubscribe_node_rejoin: Callable[[], None] | None = None
7373

7474
self._discover_sed_tasks: dict[str, Task[bool]] = {}
75-
self._discover_task: Task | None = None
76-
self._discover_schedule_task: Task | None = None
7775

7876
# region - Properties
7977

@@ -340,7 +338,7 @@ async def discover_network_coordinator(self, load: bool = False) -> bool:
340338
# endregion
341339

342340
# region - Nodes
343-
def _create_node_object(
341+
async def _create_node_object(
344342
self,
345343
mac: str,
346344
address: int,
@@ -365,7 +363,7 @@ def _create_node_object(
365363
return
366364
self._nodes[mac] = node
367365
_LOGGER.debug("%s node %s added", node.__class__.__name__, mac)
368-
self._register.update_network_registration(address, mac, node_type)
366+
await self._register.update_network_registration(address, mac, node_type)
369367

370368
if self._cache_enabled:
371369
_LOGGER.debug(
@@ -406,22 +404,24 @@ async def _discover_node(
406404
407405
Return True if discovery succeeded.
408406
"""
409-
_LOGGER.debug("Start discovery of node %s ", mac)
407+
_LOGGER.debug(
408+
"Start discovery of node %s with NodeType %s", mac, str(node_type)
409+
)
410410
if self._nodes.get(mac) is not None:
411411
_LOGGER.debug("Skip discovery of already known node %s ", mac)
412412
return True
413413

414414
if node_type is not None:
415-
self._create_node_object(mac, address, node_type)
415+
await self._create_node_object(mac, address, node_type)
416416
await self._notify_node_event_subscribers(NodeEvent.DISCOVERED, mac)
417417
return True
418418

419419
# Node type is unknown, so we need to discover it first
420-
_LOGGER.debug("Starting the discovery of node %s", mac)
420+
_LOGGER.debug("Starting the discovery of node %s with unknown NodeType", mac)
421421
node_info, node_ping = await self._controller.get_node_details(mac, ping_first)
422422
if node_info is None:
423423
return False
424-
self._create_node_object(mac, address, node_info.node_type)
424+
await self._create_node_object(mac, address, node_info.node_type)
425425

426426
# Forward received NodeInfoResponse message to node
427427
await self._nodes[mac].message_for_node(node_info)
@@ -450,16 +450,6 @@ async def _discover_registered_nodes(self) -> None:
450450
str(discovered_counter),
451451
str(registered_counter),
452452
)
453-
if discovered_counter < registered_counter:
454-
if self._discover_task is None or self._discover_task.done():
455-
self._discover_task = create_task(
456-
self._schedule_discover_registered_nodes()
457-
)
458-
459-
async def _schedule_discover_registered_nodes(self) -> None:
460-
"""Reschedule node discovery every interval until finished."""
461-
await sleep(NODE_DISCOVER_INTERVAL)
462-
self._discover_schedule_task = create_task(self._discover_registered_nodes())
463453

464454
async def _load_node(self, mac: str) -> bool:
465455
"""Load node."""

plugwise_usb/network/cache.py

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
import logging
66

77
from ..api import NodeType
8-
from ..constants import CACHE_DATA_SEPARATOR
98
from ..helpers.cache import PlugwiseCache
109

1110
_LOGGER = logging.getLogger(__name__)
12-
_NETWORK_CACHE_FILE_NAME = "nodes.cache"
11+
_NETWORK_CACHE_FILE_NAME = "nodetype.cache"
1312

1413

1514
class NetworkRegistrationCache(PlugwiseCache):
@@ -18,68 +17,54 @@ class NetworkRegistrationCache(PlugwiseCache):
1817
def __init__(self, cache_root_dir: str = "") -> None:
1918
"""Initialize NetworkCache class."""
2019
super().__init__(_NETWORK_CACHE_FILE_NAME, cache_root_dir)
21-
self._registrations: dict[int, tuple[str, NodeType | None]] = {}
20+
self._nodetypes: dict[str, NodeType] = {}
2221

2322
@property
24-
def registrations(self) -> dict[int, tuple[str, NodeType | None]]:
23+
def nodetypes(self) -> dict[str, NodeType | None]:
2524
"""Cached network information."""
26-
return self._registrations
25+
return self._nodetypes
2726

2827
async def save_cache(self) -> None:
2928
"""Save the node information to file."""
3029
cache_data_to_save: dict[str, str] = {}
31-
for address in range(-1, 64, 1):
32-
mac, node_type = self._registrations.get(address, ("", None))
33-
if node_type is None:
34-
node_value = ""
35-
else:
36-
node_value = str(node_type)
37-
cache_data_to_save[str(address)] = (
38-
f"{mac}{CACHE_DATA_SEPARATOR}{node_value}"
39-
)
30+
for mac, node_type in self._nodetypes.items():
31+
node_value = str(node_type)
32+
cache_data_to_save[mac] = node_value
33+
_LOGGER.debug("Save NodeTypes %s", str(len(cache_data_to_save)))
4034
await self.write_cache(cache_data_to_save)
4135

4236
async def clear_cache(self) -> None:
4337
"""Clear current cache."""
44-
self._registrations = {}
38+
self._nodetypes = {}
4539
await self.delete_cache()
4640

4741
async def restore_cache(self) -> None:
4842
"""Load the previously stored information."""
4943
data: dict[str, str] = await self.read_cache()
50-
self._registrations = {}
51-
for _key, _data in data.items():
52-
address = int(_key)
53-
try:
54-
if CACHE_DATA_SEPARATOR in _data:
55-
values = _data.split(CACHE_DATA_SEPARATOR)
56-
else:
57-
# legacy data separator can by remove at next version
58-
values = _data.split(";")
59-
mac = values[0]
60-
node_type: NodeType | None = None
61-
if values[1] != "":
62-
node_type = NodeType[values[1][9:]]
63-
self._registrations[address] = (mac, node_type)
64-
_LOGGER.debug(
65-
"Restore registry address %s with mac %s with node type %s",
66-
address,
67-
mac if mac != "" else "<empty>",
68-
str(node_type),
69-
)
70-
except (KeyError, IndexError):
71-
_LOGGER.warning(
72-
"Skip invalid data '%s' in cache file '%s'",
73-
_data,
74-
self._cache_file,
75-
)
44+
self._nodetypes = {}
45+
for mac, node_value in data.items():
46+
node_type: NodeType | None = None
47+
if len(node_value) >= 10:
48+
node_type = NodeType[node_value[9:]]
49+
if node_type is not None:
50+
self._nodetypes[mac] = node_type
51+
_LOGGER.debug(
52+
"Restore NodeType for mac %s with node type %s",
53+
mac,
54+
str(node_type),
55+
)
7656

77-
def update_registration(
78-
self, address: int, mac: str, node_type: NodeType | None
79-
) -> None:
57+
async def update_nodetypes(self, mac: str, node_type: NodeType | None) -> None:
8058
"""Save node information in cache."""
81-
if self._registrations.get(address) is not None:
82-
_, current_node_type = self._registrations[address]
83-
if current_node_type is not None and node_type is None:
59+
if node_type is None:
60+
return
61+
if (current_node_type := self._nodetypes.get(mac)) is not None:
62+
if current_node_type == node_type:
8463
return
85-
self._registrations[address] = (mac, node_type)
64+
_LOGGER.warning(
65+
"Cache contained mismatched NodeType %s replacing with %s",
66+
str(current_node_type),
67+
str(node_type),
68+
)
69+
self._nodetypes[mac] = node_type
70+
await self.save_cache()

plugwise_usb/network/registry.py

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ async def start(self) -> None:
107107
"""Initialize load the network registry."""
108108
if self._cache_enabled:
109109
await self.restore_network_cache()
110-
await self.load_registry_from_cache()
111110
await self.update_missing_registrations_quick()
112111

113112
async def restore_network_cache(self) -> None:
@@ -121,22 +120,6 @@ async def restore_network_cache(self) -> None:
121120
await self._network_cache.restore_cache()
122121
self._cache_restored = True
123122

124-
async def load_registry_from_cache(self) -> None:
125-
"""Load network registry from cache."""
126-
if self._network_cache is None:
127-
_LOGGER.error(
128-
"Unable to restore network registry because cache is not initialized"
129-
)
130-
return
131-
132-
if self._cache_restored:
133-
return
134-
135-
for address, registration in self._network_cache.registrations.items():
136-
mac, node_type = registration
137-
if self._registry.get(address) is None:
138-
self._registry[address] = (mac, node_type)
139-
140123
async def retrieve_network_registration(
141124
self, address: int, retry: bool = True
142125
) -> tuple[int, str] | None:
@@ -167,17 +150,22 @@ def network_controller(self) -> tuple[str, NodeType | None]:
167150
raise NodeError("Unable to return network controller details")
168151
return self.registry[-1]
169152

170-
def update_network_registration(
153+
async def update_network_registration(
171154
self, address: int, mac: str, node_type: NodeType | None
172155
) -> None:
173156
"""Add a network registration."""
174-
if self._registry.get(address) is not None:
175-
_, current_type = self._registry[address]
176-
if current_type is not None and node_type is None:
177-
return
157+
if node_type is None:
158+
if self._registry.get(address) is not None:
159+
_, current_type = self._registry[address]
160+
if current_type is not None:
161+
return
162+
if self._network_cache is not None:
163+
node_type = self._network_cache._nodetypes.get(mac)
164+
178165
self._registry[address] = (mac, node_type)
179-
if self._network_cache is not None:
180-
self._network_cache.update_registration(address, mac, node_type)
166+
if node_type is not None:
167+
if self._network_cache is not None:
168+
await self._network_cache.update_nodetypes(mac, node_type)
181169

182170
async def update_missing_registrations_full(self) -> None:
183171
"""Full retrieval of all unknown network registrations from network controller."""
@@ -199,14 +187,10 @@ async def update_missing_registrations_full(self) -> None:
199187
str(nextaddress),
200188
"'empty'" if mac == "" else f"set to {mac}",
201189
)
202-
self.update_network_registration(nextaddress, mac, None)
190+
await self.update_network_registration(nextaddress, mac, None)
203191
await sleep(10)
204192
_LOGGER.debug("Full network registration finished")
205193
self._scan_completed = True
206-
if self._cache_enabled:
207-
_LOGGER.debug("Full network registration finished, save to cache")
208-
await self.save_registry_to_cache()
209-
_LOGGER.debug("Full network registration finished, post")
210194
_LOGGER.info("Full network discovery completed")
211195
if self._full_scan_finished is not None:
212196
await self._full_scan_finished()
@@ -228,7 +212,7 @@ async def update_missing_registrations_quick(self) -> None:
228212
str(nextaddress),
229213
"'empty'" if mac == "" else f"set to {mac}",
230214
)
231-
self.update_network_registration(nextaddress, mac, None)
215+
await self.update_network_registration(nextaddress, mac, None)
232216
await sleep(0.1)
233217
if self._registration_task is None or self._registration_task.done():
234218
self._registration_task = create_task(
@@ -239,9 +223,9 @@ async def update_missing_registrations_quick(self) -> None:
239223
self._quick_scan_finished = None
240224
_LOGGER.info("Quick network registration discovery finished")
241225

242-
def update_node_registration(self, mac: str) -> int:
226+
async def update_node_registration(self, mac: str) -> int:
243227
"""Register (re)joined node to Plugwise network and return network address."""
244-
self.update_network_registration(self._first_free_address, mac, None)
228+
await self.update_network_registration(self._first_free_address, mac, None)
245229
self._first_free_address += 1
246230
return self._first_free_address - 1
247231

@@ -251,22 +235,6 @@ def _stop_registration_task(self) -> None:
251235
return
252236
self._registration_task.cancel()
253237

254-
async def save_registry_to_cache(self) -> None:
255-
"""Save network registry to cache."""
256-
if self._network_cache is None:
257-
_LOGGER.error(
258-
"Unable to save network registry because cache is not initialized"
259-
)
260-
return
261-
_LOGGER.debug(
262-
"save_registry_to_cache starting for %s items", str(len(self._registry))
263-
)
264-
for address, registration in self._registry.items():
265-
mac, node_type = registration
266-
self._network_cache.update_registration(address, mac, node_type)
267-
await self._network_cache.save_cache()
268-
_LOGGER.debug("save_registry_to_cache finished")
269-
270238
async def register_node(self, mac: str) -> None:
271239
"""Register node to Plugwise network and return network address."""
272240
if not validate_mac(mac):
@@ -303,7 +271,7 @@ async def unregister_node(self, mac: str) -> None:
303271
+ f" failed to unregister node '{mac}'"
304272
)
305273
if (address := self.network_address(mac)) is not None:
306-
self.update_network_registration(address, mac, None)
274+
await self.update_network_registration(address, mac, None)
307275

308276
async def clear_register_cache(self) -> None:
309277
"""Clear current cache."""
@@ -314,9 +282,3 @@ async def clear_register_cache(self) -> None:
314282
async def stop(self) -> None:
315283
"""Unload the network registry."""
316284
self._stop_registration_task()
317-
if (
318-
self._cache_enabled
319-
and self._network_cache is not None
320-
and self._network_cache.initialized
321-
):
322-
await self.save_registry_to_cache()

0 commit comments

Comments
 (0)