python-swidget 1.4.20__tar.gz → 1.4.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_swidget-1.4.20 → python_swidget-1.4.21}/PKG-INFO +1 -1
- {python_swidget-1.4.20 → python_swidget-1.4.21}/pyproject.toml +1 -1
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgetdevice.py +20 -5
- {python_swidget-1.4.20 → python_swidget-1.4.21}/README.md +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/__init__.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/cli.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/discovery.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/exceptions.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/provision.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/py.typed +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgetdimmer.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgetfan.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgetoutlet.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgetswitch.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/swidgettimerswitch.py +0 -0
- {python_swidget-1.4.20 → python_swidget-1.4.21}/swidget/websocket.py +0 -0
|
@@ -502,7 +502,11 @@ class SwidgetDevice:
|
|
|
502
502
|
# and flicker the UI.
|
|
503
503
|
for assembly_key, new_assembly in new_assemblies.items():
|
|
504
504
|
old_assembly = self.assemblies.get(assembly_key)
|
|
505
|
-
if
|
|
505
|
+
if (
|
|
506
|
+
old_assembly is None
|
|
507
|
+
or old_assembly.type != new_assembly.type
|
|
508
|
+
or old_assembly.id != new_assembly.id
|
|
509
|
+
):
|
|
506
510
|
continue
|
|
507
511
|
for component_id, new_component in new_assembly.components.items():
|
|
508
512
|
old_component = old_assembly.components.get(component_id)
|
|
@@ -513,6 +517,17 @@ class SwidgetDevice:
|
|
|
513
517
|
new_component.functions[fn_name] = old_component.functions[
|
|
514
518
|
fn_name
|
|
515
519
|
]
|
|
520
|
+
# Fan module readings live in state["modules"], but
|
|
521
|
+
# "modules" is not a summary function tag. Preserve
|
|
522
|
+
# readings only for modules the new summary still lists;
|
|
523
|
+
# removed modules must not retain stale sensor state.
|
|
524
|
+
module_state = old_component.functions.get("modules")
|
|
525
|
+
if new_component.modules and isinstance(module_state, dict):
|
|
526
|
+
new_component.functions["modules"] = {
|
|
527
|
+
name: module_state[name]
|
|
528
|
+
for name in new_component.modules
|
|
529
|
+
if name in module_state
|
|
530
|
+
}
|
|
516
531
|
self.assemblies = new_assemblies
|
|
517
532
|
self.device_type = DeviceType(self.assemblies["host"].type)
|
|
518
533
|
self.insert_type = InsertType(self.assemblies["insert"].type)
|
|
@@ -1064,11 +1079,11 @@ class SwidgetComponent:
|
|
|
1064
1079
|
starts as a same-keyed dict of placeholder ``None`` values and is
|
|
1065
1080
|
later mutated by ``process_state`` to carry live datapoint values.
|
|
1066
1081
|
|
|
1067
|
-
Process_state also
|
|
1082
|
+
Process_state also adds keys that aren't in the summary
|
|
1068
1083
|
functions list (e.g. fans emit a ``modules`` map in state that
|
|
1069
1084
|
isn't a declared function tag), so ``functions.keys()`` is *not*
|
|
1070
|
-
|
|
1071
|
-
|
|
1085
|
+
the declared schema. Anything that needs a stable schema
|
|
1086
|
+
fingerprint (entity wiring, structure-change
|
|
1072
1087
|
detection) must read ``summary_functions``, not ``functions``.
|
|
1073
1088
|
|
|
1074
1089
|
``max_cfm``, ``model_code`` and ``modules`` come from the optional
|
|
@@ -1079,7 +1094,7 @@ class SwidgetComponent:
|
|
|
1079
1094
|
def __init__(self, component):
|
|
1080
1095
|
funcs = list(component.get("functions", []))
|
|
1081
1096
|
self.summary_functions: tuple[str, ...] = tuple(funcs)
|
|
1082
|
-
self.functions = {f: None for f in funcs}
|
|
1097
|
+
self.functions: dict[str, Any] = {f: None for f in funcs}
|
|
1083
1098
|
self.max_cfm = component.get("maxCFM")
|
|
1084
1099
|
self.model_code = component.get("code")
|
|
1085
1100
|
self.modules = list(component.get("modules", []))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|