You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> events-list decoupling, time-windowed graph X positioning, parallel
15
-
> E2E matrix, shell completion) are the last polish items from
16
-
> hardware testing on rc7. Once GA the entry below is promoted from
12
+
> Status: v5.1.0-rc9 is the final candidate before v5.1.0 GA. rc9
13
+
> reframes the voltage-monitoring path for grid-quality reporting
14
+
> (clamp warnings to ±10% nominal, add severity-aware notification
15
+
> bypass) on top of rc8's TUI/E2E/completion polish. After Federico's
16
+
> live-mains testing on rc9 the entry below is promoted from
17
17
> `[Unreleased]` to `[5.1.0] - YYYY-MM-DD` with no other changes.
18
18
19
19
### Added
20
+
-**rc9 — Grid-quality voltage reporting.** Voltage warning thresholds (`BROWNOUT_DETECTED` / `OVER_VOLTAGE_DETECTED`) are now derived as the **tighter** of the EN 50160 / IEC 60038 ±10% envelope and `input.transfer.{low,high}` ± 5V — never wider than ±10%. Wide UPS firmware defaults (typical APC: 170 / 280 on 230V) used to make warnings fire only ~5V before the UPS itself switched to battery; the clamp ensures warnings serve the operator's grid-quality question instead. Managed UPSes with narrow transfer points (e.g. 215 / 245) keep their existing tighter thresholds via the same clamp. New `MonitorState.ups_transfer_low/high` fields track the UPS firmware switch points separately for use in notification context. The startup log line is reformatted to show both grid-quality warnings and UPS battery-switch points on separate lines.
21
+
-**rc9 — Severity-aware notification bypass.** Voltage deviations greater than ±15% from nominal now bypass `voltage_hysteresis_seconds` (default 30s) and notify **immediately**, with a `(severe, X.X% below/above nominal)` tag and an `Approaching UPS battery-switch threshold` callout when the UPS is likely to react soon. Mild deviations (10–15%) still go through the dwell so neighbour-appliance flap doesn't spam. The threshold (15%) is hard-coded — same reasoning as warning thresholds, no config knob to misconfigure.
22
+
-**rc9 — Notification text overhaul.**`BROWNOUT_DETECTED` / `OVER_VOLTAGE_DETECTED` notifications now carry `% deviation`, the warning threshold, and (when NUT exposes them) the UPS firmware's switch points so the operator can distinguish "grid is wobbly" from "UPS is about to switch". Mild events read e.g. `input voltage 200.0V is 13.0% below 230V nominal (warning threshold 207.0V). Persisted 30s. UPS will not switch to battery until 170.0V (firmware setting); this is a grid-quality issue, not an imminent power loss.`
20
23
-**rc8 — `eneru tui` CLI alias.** First-class subcommand, identical options + dispatch to `eneru monitor`. Both spellings show in top-level help; the same `--config / --once / --interval / --graph / --time / --events-only` options work for either.
21
24
-**rc8 — Graph Y-axis labels, units, and now/min/max header in the live TUI.** Each graph panel prints a stat row under the title (`now: 100% min: 95% max: 100%`) and labels the top/middle/bottom rows of the chart with values + units (`100% ┤`, `50% ┤`, `0% ┤`). Voltage and runtime graphs use observed bounds (e.g. `235.4V` / `233.1V`); runtime values render as `45m 12s` instead of raw seconds.
22
25
-**rc8 — Time-windowed X positioning in `BrailleGraph.plot`.** New optional `x_values` / `x_min` / `x_max` arguments place each sample at its actual time within the requested window instead of spreading evenly across the chart. Without this, a 12h dataset in a 30d view looked like 30 days of data; sparse data now stays in the leftmost slice and a `data: 12h of 30d requested` footer surfaces the gap. `--once` mode keeps the legacy behaviour by not passing the new arguments.
@@ -60,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
60
63
-**rc7 — Stats schema bumped 2 → 3.** Added `events.notification_sent INTEGER DEFAULT 1`. Auto-migrates v2 DBs via idempotent `ALTER TABLE` on first start; existing rows default to `1` (the v2 daemon always notified). Pattern documented as the second exercise of the schema-evolution mechanic introduced in rc6.
61
64
62
65
### Changed
66
+
-**rc9 — Voltage warning thresholds may produce more notifications on wide-transfer UPSes.** Operators with default-wide UPS firmware (e.g. APC Smart-UPS 170/280 on 230V) previously got essentially zero `BROWNOUT_DETECTED` / `OVER_VOLTAGE_DETECTED` notifications because the warnings fired only just before the UPS itself reacted. After rc9, the same setup will fire warnings at the EN 50160 ±10% band (207 / 253 on 230V) — that is the goal. If your mains is consistently outside that envelope, you'll learn about it. If you don't want per-event pings for sub-30s flap, the existing `notifications.voltage_hysteresis_seconds` (default 30s) still filters mild events; severe events (>±15%) bypass it and notify immediately.
63
67
-**rc8 — TUI events panel is decoupled from the graph timescale.** Pressing `<T>` to cycle the graph window (1h → 6h → 24h → 7d → 30d) no longer re-queries the events list. The events panel uses a fixed `EVENTS_TIME_WINDOW = 24 * 3600` regardless of `<T>`, and `<M>` keeps toggling between 8 and 50 max rows. The two controls are now orthogonal — the graph is the variable view, the events list is the stable recent-history view.
64
68
-**rc8 — E2E workflow runs as a 4-way parallel matrix.** The single `e2e-test` job is replaced by four matrix jobs visible in the GitHub Checks tab as `E2E CLI`, `E2E UPS Single`, `E2E UPS Multi`, and `E2E Redundancy and Stats`. Setup steps are a composite action at `.github/actions/e2e-setup/`; test bodies live in `tests/e2e/groups/{group}.sh`. Total wall-clock is bounded by the slowest group instead of the sum of all 32 tests. **Operator action (one-time, manual):** branch protection on `main` previously required `e2e-test`. Replace it with the four new checks listed above. GitHub allows adding checks before they exist (status: *expected*), so do this immediately before/after the merge so PRs aren't blocked on a check that no longer runs.
65
69
-**`shutdown_order` and `parallel` are now mutually exclusive.** Setting both on the same server is a hard validation error (previously a warning). Pick one model: `shutdown_order` for multi-phase ordering, or `parallel` for the legacy two-group behaviour.
📊 Voltage auto-detect re-snap: NUT=230V disagreed with observed median 120.0V (window=[120.5, 119.0, ...]V). Re-snapped to 120V; new thresholds 108.0V / 132.0V.
78
117
⚡ POWER EVENT: VOLTAGE_AUTODETECT_MISMATCH - NUT nominal=230V, observed median=120.0V, re-snapped to 120V
79
118
```
80
119
81
-
The bottom row also lands in the SQLite `events` table with
120
+
The autodetect-mismatch row lands in the SQLite `events` table with
82
121
`notification_sent=0` so it doesn't ping you (it's startup
83
122
information, not an active power event).
84
123
124
+
### What you'll see in a brownout notification
125
+
126
+
**Mild brownout (UPS won't switch):**
127
+
128
+
```text
129
+
🔻 BROWNOUT_DETECTED: input voltage 200.0V is 13.0% below 230V nominal
130
+
(warning threshold 207.0V). Persisted 30s.
131
+
UPS will not switch to battery until 170.0V (firmware setting);
132
+
this is a grid-quality issue (outside the EN 50160 ±10% envelope),
133
+
not an imminent power loss.
134
+
```
135
+
136
+
**Severe brownout (UPS may switch shortly):**
137
+
138
+
```text
139
+
🔻 BROWNOUT_DETECTED: (severe, 21.7% below nominal): input voltage 180.0V.
140
+
Notifying immediately (bypassed hysteresis).
141
+
Approaching UPS battery-switch threshold (170.0V) -- battery may
0 commit comments