Files
gree-controller/BUILD_REPORT.md
T
2026-08-25 09:43:28 +02:00

142 lines
13 KiB
Markdown

# GREE Controller v0.6.6 - build and validation report
## Scope
Version 0.6.6 includes the 0.6.5 changes described below plus synchronized whole-house activation: selecting a global operating mode or work profile now re-enables master power and powers on all enabled units. The global power panel is also placed above the house climate controls.
## Implemented changes
- Night-mode settings moved out of application Settings into a dedicated **Night mode** page.
- Home Assistant connection, sensor aliases and integration access tokens moved to a dedicated **Home Assistant / Sensors** page.
- Settings now contains application/technical settings only.
- Unit-feature controls on device cards are smaller, centered and visually aligned with the other compact device controls.
- Disabled thermostat zones continue refreshing and showing room temperature while control commands remain disabled.
- Home Assistant sensor aliases are now presentation-only end-to-end: backend reads resolve aliases back to the original `entity_id`, settings are canonicalized, and zone/outdoor polling records the real entity ID.
- Outdoor temperature now falls back to the median outdoor reading from online GREE units when the configured Home Assistant outdoor sensor is unavailable.
- GREE optional capabilities are discovered from status properties (`Lig`, `Quiet`, `Tur`, `Air`, `Blo`, `Health`, `SwhSlp`) and persisted with each device.
- Supported unit features are shown in the Web UI and exposed as Home Assistant switches for panel light, Quiet, Turbo, X-FAN, Air, Health and Sleep.
- Night mode can use native GREE Sleep in the same command as the standby setpoint, fan limit and Quiet when the unit supports it.
- Home Assistant now exposes every controller zone as a full `climate` entity with Off / Auto (follow house mode) / Cool / Heat plus current and target temperature. Existing zone number/switch entities are retained.
- Decorative icons were removed from Settings block headers.
- Replaced the textual Connected/Disconnected label with a green/amber/red status dot in the top-left brand header.
- Fixed History filter layout so Zone/Device/Sensor and time-range controls keep equal heights and do not stretch after changing tabs.
- Reworked the Simulator into a Node-RED-style dotted flow board with connected live nodes for sensor input, thermostat target, decision, unit command and next event.
- Added configurable night mode (default 22:00-06:00): thermostat fan speed is capped during quiet hours and compatible units can be asked to keep Quiet enabled.
- Device cards now use **Name / protocol** instead of Rename and no longer show the fixed UDP port next to the IP address.
- Settings are split into visual blocks; the self-signed HA example uses a generic private address instead of an installation-specific address.
- Event/debug log retention is configurable and old rows are pruned automatically; the Events page can change retention and prune immediately.
- Home Assistant temperature sensors can have UI aliases; aliases replace raw entity IDs in history selectors, legends and custom-chart labels without changing stored entity IDs.
- Added a dedicated Web UI simulator page that visualizes thermostat/automation decisions as graphical blocks with hours, targets, demand, standby behavior, rule actions and upcoming events.
- Quick Thermostat cards on the dashboard can enable/disable a zone directly; the edit dialog is no longer required for this action.
- SQLite history housekeeping is tiered to chart resolution: full recent data, 10-minute buckets after 24 hours and 30-minute buckets after 7 days.
- Optional long-term InfluxDB archive supports both InfluxDB 1.x (database/basic auth) and 2.x (org/bucket/token), from persisted settings or environment variables.
- New samples are written to SQLite and InfluxDB in parallel when the archive is enabled.
- Maintenance backfills compacted legacy SQLite samples older than the configured Influx handoff age. A local row is deleted only after the Influx batch succeeds; archive failures keep the SQLite copy.
- History requests crossing the handoff age merge old InfluxDB data with recent SQLite data and fall back to SQLite when the archive query fails.
- Device commands are reduced to fields that actually changed. Optional GREE buzzer suppression uses `Buzzer_ON_OFF`/`BuzzerCtrl`; incompatible devices automatically fall back to normal frames and are remembered for the running process.
- Smart Fan now uses Low speed (`WdSpd=1`) when a zone is satisfied. The thermostat sends standby setpoint + Low fan + optional `Quiet=1` in one GREE frame. If a unit rejects `Quiet`, the controller retries without it and remembers that capability fallback until restart; when demand resumes, controller-owned Quiet is released on the transition.
- Toast progress indicators have horizontal inset so they stay inside rounded toast corners.
- Settings can be exported/imported as JSON. Metrics, event logs and generated API-token records are preserved during import. Exported configuration contains configured secrets and must be protected.
- Optional on-screen debug overlay is available on every Web UI route, can be changed through `/api/debug`, shows controller events plus live HTTP method/path/status timing and can include sanitized decrypted GREE request/response payloads.
- `/api/control-plan` exposes house state, current zone decisions, schedules, upcoming transitions and automation rules/time events.
- The dashboard renders the control plan as blocks with current targets/demand and upcoming actions.
- Home Assistant integration now also exposes whole-house/per-zone plan sensors, writable per-zone target-temperature `number` entities and per-zone enable `switch` entities via the restricted integration API.
## 0.6.1 compile hotfix
- Fixed `u8`/`u32` mismatches in communication-failure threshold handling without changing the persisted `Device.communication_failures` type or notification-settings schema.
- Removed the unused `AppState` parameter from Slack/Discord webhook delivery.
- Bumped application, Cargo lock root package, Home Assistant custom-component and PWA cache versions to `0.6.1`.
## Validation performed in packaging environment
- `node --check web/app.js`.
- Python syntax validation for the Home Assistant integration and helper scripts.
- Shell syntax validation for all `scripts/*.sh` files.
- JSON validation for EN/PL language packs, PWA manifest, Home Assistant manifest and HA translations.
- EN/PL UI translation-key parity and literal UI translation-reference validation.
- SQLite schema execution plus tiered compaction and event-log retention tests.
- SQLite archive-selection query tests for device, zone and Home Assistant histories.
- Configuration-clear behavior verified to preserve metric history, event logs and API tokens.
- Version consistency checked for Cargo package, Cargo lock root package, README and Home Assistant manifest.
- Archive ZIP integrity and SHA-256 manifest are verified during final packaging.
## Rust compiler note
The packaging environment does not contain `rustc`, `cargo` or `rustfmt`, so a Rust compile cannot be executed here. Rust unit tests cover unchanged-command filtering, history compaction, HA alias resolution, GREE outdoor fallback, night/native-Sleep decisions and combined standby command payloads; they cannot be executed in this packaging environment. The target LXC update/install scripts remain the authoritative compile gate and run:
```bash
cargo test --all-targets
cargo build --release
```
The update script must complete those commands before replacing the running binary.
## 2026-08-24 update
Implemented from the current source archive:
- Decimal thermostat input accepts both `.` and `,` in mobile/desktop UI via locale-independent parser and decimal keyboard hints.
- Notifications persisted in runtime settings with Pushover, Slack and Discord providers, test endpoint/button, two modes (`problems`, `important`), per-event cooldown, communication failure threshold and target-not-reached timeout.
- Device polling emits one offline anomaly after the configured consecutive-failure threshold and one recovery event when communication returns.
- Zone control tracks continuous demand and emits a `zone.target_timeout` anomaly once per demand episode when the target is not reached within the configured time.
- Automation dialog includes practical presets for high-temperature cooling, low-temperature heating, morning comfort and night power-off.
- Event log page has level/category filters and stronger visual separation by category/severity.
- Zone editor can copy thermostat tuning/profile settings from another zone without overwriting the destination zone identity, device assignment or HA entity.
- Language selector shows flags; theme selector shows compact theme icons.
- Home Assistant custom component includes `icon.png` and `logo.png` based on the existing project mark.
- New installs create a minimal environment file, keep `SIMULATE=false` and `AUTO_SEED=false`, and intentionally allow an empty application token. Existing env files remain untouched.
- Reverse-proxy support includes base-path routing, `X-Forwarded-Prefix`, prefix-aware UI/API/WebSocket/PWA assets and helper script health URLs.
- Removed permissive CORS and added basic browser security headers. Notification webhooks are HTTPS-only, host-restricted and do not follow redirects.
- Added `docs/SECURITY.md` and `docs/REVERSE_PROXY.md`.
History review: the supplied counts (28,133 GREE, 1,889 zone, 5,626 HA samples) are modest for the existing SQLite design. The current schema already has time/entity indexes, history bucketing, query limits, retention and compaction, so no database migration was added solely for these counts.
Validation performed in the build environment:
- `node --check web/app.js` - passed.
- JSON parsing of language files and web manifest - passed.
- `bash -n scripts/install.sh` - passed.
- Home Assistant icon files generated and verified as 256x256 RGBA PNG.
- Rust compilation was not executed because this execution environment does not contain `cargo`/Rust toolchain. Backend changes were therefore statically reviewed but require the normal project CI/build host to run `cargo test`/`cargo build --release` before deployment.
## 0.6.2 thermostat copy hotfix
- The destination zone identity is now stored independently from the form payload while editing.
- Copy-source choices exclude the currently edited zone.
- Copying thermostat settings explicitly preserves the destination zone ID, name, assigned device, sensor strategy/entity and enabled state.
- Zone updates use the independently tracked destination ID, preventing the source profile from being overwritten by a stale or mutated form ID.
## 0.6.3 house climate mode highlight
- The selected whole-house climate mode (Cool / Heat / Off) now has a persistent illuminated border, accent fill and glowing status dot.
- The active mode is still derived from persisted `settings.house_mode`, so the highlight survives refreshes and reconnects.
- Mode buttons now expose `aria-pressed` for an explicit accessible selected state.
## 0.6.4 Home Assistant zone thermostat naming
- Zone climate entities now use a descriptive entity name, `Thermostat`.
- New zone entities are therefore created as `climate.<zone_name>_thermostat` instead of falling back to ambiguous numeric suffixes such as `_2`.
- Existing zone climate registry entries are migrated on integration reload to the same scheme based on the zone's current name, fixing stale IDs left after zone renames (for example `climate.jan_2` for a zone currently named Igor).
- Migration is collision-safe: if the desired `climate.<zone_name>_thermostat` ID is already occupied, the existing entity ID is retained and a warning is logged instead of overwriting another entity.
## 0.6.5 house control, Home Assistant and LAN response time
- Whole-house thermostat `off` is presented as **Do not control** and no longer continuously powers units down. Directly operated devices remain untouched, while a zone explicitly overridden to Heat/Cool can continue controlling its own unit.
- Added a separate persistent whole-house master-power state. **Turn all off** powers enabled units down and prevents zone/controller automations from restarting them without modifying the selected thermostat mode/profile; **Turn all on** re-enables master power and powers enabled units on.
- Whole-house mode and preset buttons use the same normal active fill as other controls; the obsolete activity-dot styling was removed. Uniform whole-house presets remain visibly selected, while mixed zone profiles show no false global selection.
- Home Assistant now exposes controller-level **Thermostat mode** and **Work profile** select entities plus an **All air conditioners** master-power switch, backed by dedicated restricted HA endpoints.
- Device state stores the latest successful GREE communication round-trip time. **LAN network -> Devices** displays it in milliseconds next to the IP address and protocol.
- PWA cache key advanced to `gree-controller-v065`.
## 0.6.6 synchronized whole-house activation
- The global power panel is displayed above **House climate mode**.
- Selecting whole-house Cooling or Heating clears a previous global power-off and powers on all enabled units.
- Selecting Auto, Comfort, Sleep or Away as a whole-house profile does the same.
- House mode `off` / **Do not control** remains non-invasive and does not alter master power.
- The behavior is implemented in the shared backend endpoints, so Home Assistant house-mode/profile controls follow the same rules.