|
| 1 | +from __future__ import annotations |
| 2 | +from typing import Any, Dict |
| 3 | + |
| 4 | +class DeviceRegistry: |
| 5 | + def __init__(self, initial: Dict[str, Dict[str, Any]] | None = None): |
| 6 | + self.data: Dict[str, Dict[str, Any]] = initial or {} |
| 7 | + |
| 8 | + # Backward-compatible access to underlying dict |
| 9 | + def get(self, dev_id: str) -> Dict[str, Any]: |
| 10 | + if dev_id not in self.data: |
| 11 | + self.data[dev_id] = {} |
| 12 | + return self.data[dev_id] |
| 13 | + |
| 14 | + def set_idn(self, dev_id: str, ident: str): |
| 15 | + self.update(dev_id, 'IDN', ident) |
| 16 | + |
| 17 | + def update(self, dev_id: str, key: str, value: Any, klass: str | None = None): |
| 18 | + bucket = self.get(dev_id) |
| 19 | + if klass: |
| 20 | + cb = bucket.setdefault(klass, {}) |
| 21 | + cb[key] = value |
| 22 | + else: |
| 23 | + bucket[key] = value |
| 24 | + |
| 25 | + def remove_item(self, dev_id: str, key: str | None = None, prefix: bool = False, klass: str | None = None): |
| 26 | + if dev_id not in self.data or not isinstance(self.data.get(dev_id), dict): |
| 27 | + self.data[dev_id] = {} |
| 28 | + return |
| 29 | + target = self.data[dev_id] |
| 30 | + if klass: |
| 31 | + target = target.setdefault(klass, {}) |
| 32 | + if key is None: |
| 33 | + if klass: |
| 34 | + self.data[dev_id][klass] = {} |
| 35 | + else: |
| 36 | + self.data[dev_id] = {} |
| 37 | + return |
| 38 | + if prefix: |
| 39 | + for k in list(target.keys()): |
| 40 | + if isinstance(k, str) and k.startswith(key): |
| 41 | + target.pop(k, None) |
| 42 | + return |
| 43 | + target.pop(key, None) |
| 44 | + |
| 45 | + def clear_device(self, dev_id: str): |
| 46 | + self.remove_item(dev_id, None) |
| 47 | + |
| 48 | + def clear_disconnected(self, dev_id: str): |
| 49 | + # Remove IDN and all per-class status entries when link drops |
| 50 | + self.remove_item(dev_id, 'IDN') |
| 51 | + # Clear status under all classes |
| 52 | + for klass in list((self.data.get(dev_id) or {}).keys()): |
| 53 | + # Class keys are short strings like PSU/DMM/AWG etc. Use known status prefix |
| 54 | + self.remove_item(dev_id, 'status_ch', prefix=True, klass=klass) |
0 commit comments