diff --git a/scripts/ac-power.lua b/scripts/ac-power.lua index 834cb5f..5c2281d 100644 --- a/scripts/ac-power.lua +++ b/scripts/ac-power.lua @@ -3,7 +3,7 @@ Features: * Polls `/api/states/` via curl with a long-lived token and trims the base URL to avoid duplicate slashes. - * Debounces HUD spam by only re-rendering when watt deltas exceed `min_delta_watts` or when `force_refresh_interval` elapses. + * Debounces HUD spam by only re-rendering when watt deltas exceed `min_delta_watts` (or `min_delta_percent`) or when `force_refresh_interval` elapses. * Survives flaky networks with capped exponential backoff, optional HUD error messages, and redraws of the last known value after OSD clears. Configuration: @@ -16,6 +16,7 @@ local CONFIG = { ha_token = "REPLACE_WITH_LONG_LIVED_TOKEN", poll_interval = 3, -- seconds between successful polls min_delta_watts = 5, -- only show when change ≥ delta + min_delta_percent = 0, -- optional % change relative to last reading force_refresh_interval = 30, -- seconds, even if delta small display_label = "AC Power", units_label = "W", @@ -123,6 +124,36 @@ local function ensure_poll_timer(delay, fn) end) end +local function meets_delta_threshold(value) + if not value then + return false + end + if not last_watts then + return true + end + + local delta = math.abs(value - last_watts) + if delta >= CONFIG.min_delta_watts then + return true + end + + if CONFIG.min_delta_percent > 0 then + local baseline = math.abs(last_watts) + if baseline < 1e-6 then + baseline = math.abs(value) + end + if baseline < 1e-6 then + baseline = 1 + end + local percent_delta = (delta / baseline) * 100 + if percent_delta >= CONFIG.min_delta_percent then + return true + end + end + + return false +end + local function handle_success(value, payload) backoff_failures = 0 local now = mp.get_time() @@ -130,8 +161,7 @@ local function handle_success(value, payload) local unit = sensor_units(payload) local force_due = CONFIG.force_refresh_interval > 0 and (now - last_display_ts) >= CONFIG.force_refresh_interval - local significant_change = value - and (not last_watts or math.abs(value - last_watts) >= CONFIG.min_delta_watts) + local significant_change = meets_delta_threshold(value) if significant_change or force_due or last_watts == nil then show_value(printable, unit)