From 7230e00e325d97b19f8ac90fd1d90c6e2b2516a0 Mon Sep 17 00:00:00 2001 From: Sterling Archer Date: Mon, 10 Aug 2026 22:24:01 -0700 Subject: [PATCH] Add monitor_fields for logging values not used by rules --- solixauto/engine.py | 19 +++++++++++++++++-- solixauto/rules.py | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/solixauto/engine.py b/solixauto/engine.py index 2c92251..676ad17 100644 --- a/solixauto/engine.py +++ b/solixauto/engine.py @@ -238,9 +238,17 @@ class Engine: if floor and floor.field not in names: names.insert(0, floor.field) - readings = " ".join( + parts_readings = [ f"{name}={variables.get(name)}" for name in names if name in variables - ) + ] + + for name in self.profile.monitor_fields: + if name in names: + continue + value = variables.get(name, None) + parts_readings.append(f"{name}={'-' if value is None else value}") + + readings = " ".join(parts_readings) parts = [] for state in self.states: @@ -506,6 +514,13 @@ class Engine: ) else: self.report("battery floor: NONE SET", force=True) + + if self.profile.monitor_fields: + self.report( + "also logging (not used by any rule): " + + ", ".join(self.profile.monitor_fields), + force=True, + ) self.report(f"target: {self.target.label} channel {self.target.channel}", force=True) async with aiohttp.ClientSession() as session: diff --git a/solixauto/rules.py b/solixauto/rules.py index f21678b..cdffe67 100644 --- a/solixauto/rules.py +++ b/solixauto/rules.py @@ -340,6 +340,13 @@ class PowerProfile: raise ProfileError("at least one rule is required") self.rules = [Rule(item, index) for index, item in enumerate(raw_rules)] + monitor = raw.get("monitor_fields") or [] + if isinstance(monitor, str): + monitor = [monitor] + if not isinstance(monitor, list): + raise ProfileError("monitor_fields must be a list of field names") + self.monitor_fields = [str(entry).strip() for entry in monitor if str(entry).strip()] + self.notifications = NotificationSettings(raw.get("notifications") or {}) safety = raw.get("safety") or {} @@ -455,6 +462,13 @@ def validate(profile): for warning in automation_warnings(device_automation, profile.target_channel): notes.append(f"target device has its own automation: {warning}") + for name in profile.monitor_fields: + if name not in available: + notes.append( + f"monitor_fields lists {name!r}, which this device does not report. " + "It will show as '-' in the log." + ) + if profile.battery_floor is None: notes.append( "no safety.battery_floor is set. If this target controls charging for "