From 5ab8ee75fb8df1bce3435cf9223e36c9691dde0d Mon Sep 17 00:00:00 2001 From: retr0 <42kdesigners@gmail.com> Date: Mon, 4 May 2026 15:12:15 +0200 Subject: [PATCH] =?UTF-8?q?v1.8.13:=20Labels=20+=20Invertiert-Modus=20f?= =?UTF-8?q?=C3=BCr=20=C3=9Cberschuss-Ger=C3=A4te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Beschriftung über jedem Eingabefeld (Name, Z2M Name, Schwellwert, etc.) - Checkbox "Invertiert": EIN bei Netzbezug, AUS bei Überschuss - Live-Tab: ↑/↓ Pfeil zeigt normale/invertierte Logik Co-Authored-By: Claude Sonnet 4.6 --- haos-addon/config.yaml | 2 +- haos-addon/src/surplus_devices.py | 9 ++++++-- haos-addon/src/web/index.html | 35 +++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/haos-addon/config.yaml b/haos-addon/config.yaml index 98b429a..0eedbfc 100644 --- a/haos-addon/config.yaml +++ b/haos-addon/config.yaml @@ -1,5 +1,5 @@ name: ShineBridge -version: "1.8.12" +version: "1.8.13" slug: shinebridge description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI url: https://gitea.bitfire.work/retr0/shinebridge diff --git a/haos-addon/src/surplus_devices.py b/haos-addon/src/surplus_devices.py index 01bf06f..d9353d6 100644 --- a/haos-addon/src/surplus_devices.py +++ b/haos-addon/src/surplus_devices.py @@ -36,12 +36,17 @@ class SurplusDeviceController: threshold = float(dev.get("threshold_w", 500)) hysteresis = float(dev.get("hysteresis_w", 150)) min_on_s = float(dev.get("min_on_minutes", 0)) * 60 + inverted = bool(dev.get("inverted", False)) currently_on = self._states.get(name, False) - if not currently_on and surplus_w >= threshold: + # Invertiert: EIN bei Netzbezug (kein Überschuss), AUS bei Überschuss + should_turn_on = not currently_on and (surplus_w >= threshold if not inverted else surplus_w < (threshold - hysteresis)) + should_turn_off = currently_on and (surplus_w < (threshold - hysteresis) if not inverted else surplus_w >= threshold) + + if should_turn_on: self._send(name, True) self._on_since[name] = now - elif currently_on and surplus_w < (threshold - hysteresis): + elif should_turn_off: on_since = self._on_since.get(name, 0.0) if now - on_since >= min_on_s: self._send(name, False) diff --git a/haos-addon/src/web/index.html b/haos-addon/src/web/index.html index 941acd1..0fbb321 100644 --- a/haos-addon/src/web/index.html +++ b/haos-addon/src/web/index.html @@ -988,19 +988,31 @@ async function importConfig(input) { let surplusDevices = []; +function field(label, input) { + return `
+ ${label} + ${input} +
`; +} + function renderSurplusDeviceRow(dev) { const id = dev.id || ('sd_' + Math.random().toString(36).slice(2)); return `
-
- - - - - - - +
+ ${field('Name', ``)} + ${field('Z2M Friendly Name', ``)} + ${field('Schwellwert (W)', ``)} + ${field('Hysterese (W)', ``)} + ${field('Min. Laufzeit (min)', ``)} +
+ + +
+
`; } @@ -1044,6 +1056,7 @@ function _collectSurplusDevices() { threshold_w: parseFloat(row.querySelector('[data-field=threshold_w]').value) || 0, hysteresis_w: parseFloat(row.querySelector('[data-field=hysteresis_w]').value) || 0, min_on_minutes: parseFloat(row.querySelector('[data-field=min_on_minutes]').value) || 0, + inverted: row.querySelector('[data-field=inverted]').checked, enabled: row.querySelector('[data-field=enabled]').checked, })); } @@ -1086,7 +1099,7 @@ function renderSurplusStatus(surplusData) { return `
${dot} ${esc(d.name||d.z2m_name)} - ab ${d.threshold_w}W + ${d.inverted ? '↓' : '↑'} ${d.threshold_w}W ${info} ${on?'EIN':'AUS'}
`;