Reset neighbours' cross-ventilation when a window's polarity flips

A flipped contact sensor reverses what every term saw as open, including the
other zones' cross-ventilation term, whose fingerprint covered only the
window's sensor and opening factor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
buzeraandClaude Opus 5.5 committed 2026-10-27 03:53:39 +02:00
1 parent 4911b32c5e
commit 8eef04c385
2 files changed
+8 -2

No files matched your search

@@ -15,7 +15,7 @@ everything else is kept. What each fingerprint covers:
* ventilation terms: the measurement plus the zone's windows (sensor, polarity, * ventilation terms: the measurement plus the zone's windows (sensor, polarity,
opening factor); "vent_wind_dir" also the windows' facing directions; opening factor); "vent_wind_dir" also the windows' facing directions;
"recovery" also the recovery time constant; "vent_cross" also the other zones' "recovery" also the recovery time constant; "vent_cross" also the other zones'
windows. windows (sensor, polarity, opening factor).
Comfort weight, target offset and names are not physical and are never included. Comfort weight, target offset and names are not physical and are never included.
""" """
@@ -71,7 +71,7 @@ def zone_fingerprints(zones: Mapping[str, Any], sources: Iterable[Any], windows:
m = measured[key] m = measured[key]
plain = zone_windows(key) plain = zone_windows(key)
# Cross-ventilation scales with the other zones' openings. # Cross-ventilation scales with the other zones' openings.
others = sorted([w.sensor, w.opening] for w in windows if w.zone != key and w.enabled) others = sorted([w.sensor, w.inverted, w.opening] for w in windows if w.zone != key and w.enabled)
prints = {"base": m, "loss": m, "heat": m, "bias": m, prints = {"base": m, "loss": m, "heat": m, "bias": m,
"internal": _hash([m, sorted(source_signature(s, sources) for s in sources "internal": _hash([m, sorted(source_signature(s, sources) for s in sources
if s.zone == key and s.enabled)]), if s.zone == key and s.enabled)]),
+6
View File
@@ -72,6 +72,12 @@ class FingerprintTests(unittest.TestCase):
self.assertEqual(diff['bed'], ['recovery', 'vent_cross', 'vent_gust', 'vent_natural', 'vent_wind', self.assertEqual(diff['bed'], ['recovery', 'vent_cross', 'vent_gust', 'vent_natural', 'vent_wind',
'vent_wind_dir']) 'vent_wind_dir'])
self.assertEqual(diff['living'], ['vent_cross']) # sees the bedroom's windows self.assertEqual(diff['living'], ['vent_cross']) # sees the bedroom's windows
# A flipped polarity reverses what every term saw as open, the neighbour's too.
flipped = [{'key': 'w1', 'sensor': 'binary_sensor.w1', 'zone': 'bed', 'azimuth': 345, 'inverted': True},
{'key': 'w2', 'sensor': 'binary_sensor.w2', 'zone': 'living', 'azimuth': 345}]
diff = differing(self.base, setup(windows=flipped)[0])
self.assertIn('vent_natural', diff['bed'])
self.assertEqual(diff['living'], ['vent_cross'])
self.assertEqual(differing(self.base, setup(recovery=40)[0]), {'living': ['recovery'], 'bed': ['recovery']}) self.assertEqual(differing(self.base, setup(recovery=40)[0]), {'living': ['recovery'], 'bed': ['recovery']})
def test_baseline_prints_and_change_detection(self): def test_baseline_prints_and_change_detection(self):