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

52 KiB

GREE Controller v0.8.3 - build and validation report

0.8.3 Temporary Quick Thermostat sessions

Source baseline: v0.8.2.

Changes

  • Added a separate persisted Temporary Quick Thermostat session, independent of the existing local_thermostat_resume_at 15-minute local-OFF hand-back mechanism.
  • Added finish rules for duration, absolute date/time, temperature reached, continuously held temperature and next schedule boundary.
  • Temperature rules support within, at_or_below and at_or_above, configurable tolerance, continuous hold time and an optional maximum safety duration.
  • Added active-session countdown/status in the dashboard Quick Thermostat card and a configuration dialog for starting or updating a session.
  • Moved the zone automation enabled switch outside the Quick Thermostat controls to separate automation availability from local thermostat operation.
  • A temporary session can temporarily enable a disabled zone and restores the pre-session enabled state when it ends.
  • Manual Quick Thermostat power changes cancel the temporary session, while target changes update temperature-based session targets safely.
  • Bumped controller and Home Assistant integration version to 0.8.3 and rotated the PWA service-worker cache key.

Validation executed in this environment

  • node --check web/app.js
  • node --check web/theme-init.js
  • node --check web/sw.js
  • parsed all JSON files
  • python3 -m compileall -q home-assistant scripts make_zip.py
  • bash -n scripts/*.sh
  • checked version consistency across Cargo.toml, Cargo.lock, README and Home Assistant manifest
  • regenerated and verified FILE_MANIFEST.sha256
  • tested the final ZIP with unzip -t

Rust toolchain note

This execution environment does not contain cargo, rustc or rustfmt, so Rust tests and full compilation cannot be executed here. The installer/updater still runs cargo test --all-targets before replacing the running service.


GREE Controller v0.8.2 - build and validation report

0.8.2 UI/i18n + Home Assistant sensor freshness

Source baseline: v0.8.1.

Changes

  • Fixed the 0.8.x ownership translations: zones.controlOwner, owner labels and owner timing labels are now inside each language pack's translations object, so the Web UI receives translated values instead of raw translation keys.
  • Simplified the Polish owner caption from Właściciel sterowania to Sterowanie and allowed the owner/timing line to wrap instead of truncating.
  • Added home_assistant.sensor_stale_after_seconds with a serde-compatible 300 s default. The Home Assistant / Sensors page exposes it as minutes (1-1440 min); the backend clamps API/env values to 30-86400 s.
  • The configured freshness limit is used by room HA sensors, the outdoor HA sensor and the HA connection test. Existing non-default zone.sensor_stale_after_seconds values remain per-zone API overrides; the historical hidden/default 300 s value inherits the global HA setting.
  • Added HA_SENSOR_STALE_AFTER_SECONDS as an optional environment override.
  • Quick Thermostat and Direct Device dashboard grids now use align-items:start, so a taller manual/ownership panel no longer visually stretches neighbouring cards in the same row.
  • build.rs now rejects unexpected top-level language-pack keys, preventing translation keys from being accidentally stored outside translations again.
  • Added a Rust regression test for global/per-zone stale-timeout resolution.
  • Bumped controller and Home Assistant integration version to 0.8.2 and changed the service-worker cache key.

Validation executed in this environment

  • node --check web/app.js
  • node --check web/theme-init.js
  • node --check web/sw.js
  • parsed all JSON files
  • verified both language packs contain only meta + translations
  • verified all 564 statically referenced UI translation keys exist in both English and Polish packs
  • parsed web/index.html
  • python3 -m compileall -q home-assistant scripts make_zip.py
  • bash -n scripts/*.sh
  • checked version consistency across Cargo.toml, Cargo.lock, README and Home Assistant manifest
  • checked that no HA temperature read still uses a hardcoded Some(300) freshness limit
  • reviewed the complete 0.8.1 -> 0.8.2 source diff for unintended file changes

Rust toolchain note

This execution environment does not contain cargo, rustc or rustfmt, so the Rust regression test and full compilation cannot be executed here. The existing installer/updater still runs cargo test --all-targets before touching the running service and then performs the release build. If Rust compilation or tests fail on the target host, the running service is not replaced.


GREE Controller v0.8.1 - build and validation report

0.8.1 Rust borrow-checker hotfix

Version 0.8.1 is a compile-only hotfix for the 0.8.0 ownership release. It does not change controller behavior. Two mode-selection values in src/engine.rs borrowed zone.mode as &str across refresh_control_ownership(&mut zone, ...), which Rust correctly rejected with E0502. Both paths now clone the selected mode into an owned String before the mutable ownership refresh and create the &str view only afterwards.

The affected paths are the live thermostat engine loop and /api/control-plan construction. No persisted schema, API field, ownership rule, thermostat decision, lockout rule or Home Assistant entity semantics changed.

Validation available in this environment

  • Confirmed both E0502 source patterns are removed and no zone.mode.as_str() borrow is held across refresh_control_ownership(&mut zone, ...).
  • node --check passed for Web JavaScript.
  • All JSON files parse successfully.
  • Python Home Assistant integration and helper scripts pass py_compile.
  • Shell scripts pass bash -n.
  • Version consistency checked for Cargo package, Cargo lock root package, README and Home Assistant manifest.
  • This packaging container still has no cargo, rustc or rustfmt; therefore the target-host update script remains the authoritative Rust compile/test gate and must run cargo test --all-targets and cargo build --release before replacing the service.

GREE Controller v0.8.0 - build and validation report

0.8.0 ownership/concurrency/safety release

Version 0.8.0 keeps the 0.7.13 public behavior while adding explicit control ownership, per-zone serialization and optimistic revisions, stale Home Assistant sensor protection, schedule-boundary recalculation for physical manual takeover, automatic Heat/Cool compressor lockout, desired-vs-actual diagnostics, and owner/source status in Web/Home Assistant.

Compatibility

  • Existing zone JSON remains loadable because every new persisted field uses serde defaults.
  • The revision request field is optional, so older Web/API clients continue to work; clients that send it receive HTTP 409 on stale writes.
  • Existing control-plan.control_source keeps its historical meaning (temperature source). The new command provenance is exported as control_command_source to avoid breaking Home Assistant or third-party consumers.
  • Existing physical and zone climate entity unique IDs remain unchanged.

Validation available in this environment

  • node --check passed for Web JavaScript.
  • All JSON files parse successfully.
  • Python Home Assistant integration and helper scripts pass py_compile.
  • Shell scripts pass bash -n.
  • Structural checks confirm all Zone and ZoneControlPlan literals contain the newly required fields.
  • A Rust compiler/toolchain is not installed in this container and external network access from the container is disabled, so cargo fmt/check/test cannot be executed here. The release/update scripts must still run the normal Cargo build/test gate on the target host before replacing the service binary.

GREE Controller v0.7.13 - build and validation report

Scope

Version 0.7.13 hardens Quick Thermostat ownership against polling/firmware-settling races, disables Global when no global Heating/Cooling mode is selected, and adds live counters for UDP frames received from configured GREE units. The 0.7.12 timed hand-back behavior remains unchanged.

0.7.13 race protection and diagnostics

  • Per-zone Quick Thermostat changes are serialized with polling using the same per-device operation lock, preventing a stale poll from restoring a false physical/pilot takeover after the user explicitly selects local thermostat control.
  • Recent controller-requested states and their pre-command baselines are kept for a bounded settling window, so delayed/out-of-order GREE status frames are not mistaken for remote-control changes.
  • The Quick Thermostats Global button is disabled while the global house mode is neither Heating nor Cooling.
  • Settings shows live total and per-device UDP receive counters, updated over the existing WebSocket event stream.

Existing 0.7.12 hand-back correction

  • Local thermostat ON/OFF now goes through one backend helper, so every new OFF action creates a fresh authoritative 15-minute deadline and ON always cancels it.
  • A physical/direct-device takeover temporarily suspends expiry of an existing local-OFF hand-back. Returning the unit to the previous OFF state re-arms the countdown from that return moment instead of continuing an old timer.
  • The Home Assistant coordinator keeps the exact local_thermostat_resume_at returned by the zone-control API in its short optimistic overlay, preventing a stale in-flight plan refresh from briefly restoring an older countdown.

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:

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.

0.6.6 climate groups, HA off-target and standalone simulation

  • Added persistent named climate groups based on thermostat zones, with independent group power, Heat/Cool/whole-house-follow mode and Auto/Comfort/Sleep/Away profile control.
  • Added group controls directly below the global All air conditioners panel plus a dedicated Groups view for membership management.
  • Whole-house Turn all on, Cooling/Heating and whole-house profile activation now re-enable all groups as part of their existing "all units" semantics; global power-off remains the authoritative master block.
  • Automation actions can target either a direct device or a climate group and can apply group mode/power/profile changes.
  • The control plan keeps a resolved thermostat target temperature while a zone, group or whole-house inherited mode is off, so Home Assistant zone climate entities no longer expose the configured target as unknown solely because control is disabled.
  • Home Assistant documentation and zone attributes clarify that zone thermostat Auto means follow the controller's whole-house Heating/Cooling mode; the direct physical-device climate entity still uses native GREE Auto.
  • The simulator can be opened as a standalone new-tab view, switched to browser full-screen mode, and filtered by individual unit or climate group.
  • Configuration backup/import, bootstrap/WebSocket state, SQLite schema and API documentation include groups.

Validation performed in this packaging environment:

  • node --check web/app.js and node --check web/sw.js.
  • Home Assistant Python modules compiled with python3 -m py_compile.
  • English/Polish translation packs parsed and checked for key parity and static UI references.
  • HTML IDs and translation references checked for duplicates/missing keys.
  • INIT_SCHEMA executed against an empty SQLite database and the new climate_groups table verified.
  • Rust compilation cannot be executed here because the environment does not contain cargo, rustc or rustfmt; the backend changes were statically reviewed and still require the normal LXC/CI cargo test --all-targets and cargo build --release gate before deployment.

0.6.7 dashboard hierarchy

  • Reorganized the main dashboard into three levels: whole-house controls, climate-group controls, and secondary details.
  • Global master power and whole-house climate mode/profile now share one panel instead of competing for separate dashboard space.
  • Group controls remain directly below global control, use a compact horizontal strip, and omit duplicate mode/profile/member summary boxes on the dashboard while retaining full details on the Groups page.
  • Control plan, quick thermostats and direct device controls remain available from the dashboard but are collapsed by default and can be expanded independently.
  • Dashboard section badges show current group, zone and device counts.
  • Mobile layout keeps global actions and expandable sections compact without removing any controls.
  • PWA cache key advanced to gree-controller-v067-dashboard so the reorganized web assets replace cached v0.6.6 files after update.

0.6.8 compact dashboard without horizontal scrolling

  • Removed the horizontally scrolling group strip from the main dashboard.
  • Dashboard group cards now use a responsive wrapped grid and flow into additional rows.
  • Group mode/profile controls use fixed grids on the dashboard, so they never require horizontal scrolling.
  • Whole-house profile controls also wrap into a grid on narrow screens.
  • Kept Control plan, Zones and Devices as collapsed disclosure panels.
  • Reduced dashboard hero, metric, global-control, group-card and disclosure spacing for a denser layout without removing functionality.
  • Advanced PWA cache key to gree-controller-v068-dashboard-wrap.

0.6.9 dashboard fit, compact summary and group-aware control plan

  • Reworked dashboard Quick Thermostats so the target-temperature control occupies its own row and measured/device-target temperatures sit below it; labels no longer collide or clip in medium-width cards.
  • Kept the quick-thermostat list as a wrapped responsive grid with no horizontal scrolling.
  • Compressed the Home / Comfort under control summary into one short card; average temperature and small online/active/demand counters now share the same row instead of consuming a separate large hero plus metrics row.
  • Reduced dashboard control-plan blocks to compact simulator-style cards.
  • Added explicit climate-group cards to What happens next, combining member demand and upcoming member-zone events.
  • Zone plan cards identify their climate group membership, and automation plan rows preserve group targets.
  • Advanced the PWA cache key to gree-controller-v069-dashboard-fit.

0.7.0 UI cleanup and scheduler/automation integrity audit

  • Removed directional arrow glyphs from Swing controls on dashboard and device cards.
  • Removed the divider above the unit feature block and tightened desktop quick-mode/fan controls so all buttons fit without horizontal scrolling.
  • Allowed the detailed zone quick-change hint to wrap naturally on desktop.
  • Added an explicit Mode policy hint: keep Follow house mode when the zone should inherit the global GREE Controller mode; fixed Cooling/Heating are intentional overrides.
  • Fixed the Always-comfort schedule template to represent a true 24-hour window without a one-minute gap.
  • Added overlap detection for enabled schedules, including overnight windows, and deterministic handling for legacy overlapping rows.
  • Fixed the Workday template Sunday-to-Monday handoff so Sunday Sleep ends at 06:30 before Monday Morning starts.
  • Manual zone/profile overrides now expire at the actual next weekly schedule transition; if none exists, they remain active until explicitly cleared instead of expiring after an arbitrary fallback timeout.
  • Editing/deleting/applying schedule templates refreshes the active manual-override boundary.
  • Time automations are limited to one execution per local minute even with the minimum 30-second cooldown; failed actions now also observe cooldown to avoid retry/log storms.
  • Temperature automations ignore stale readings from disabled/offline trigger devices.
  • Direct-device automations cannot wake a unit blocked by a disabled climate group.
  • Group power-on respects other disabled overlapping groups; group power-off remains authoritative.
  • Automation creation/import validates target/trigger references, empty actions and unsupported group-action fields.
  • Device/zone deletion now protects automation/group references and removes orphaned schedules. A physical device can be assigned to only one thermostat zone.
  • Control-plan event timestamps are normalized to minute boundaries; time-event preview covers DST-length local days.
  • Added Rust unit-test cases for overnight/full-day schedules, overlap detection, weekly boundary lookup, Workday weekend handoff and one-fire-per-minute time automations.

Rust compilation/tests still require a host with the Rust toolchain (cargo/rustc); this build environment does not provide it. Static frontend, JSON, Python/Home Assistant, archive and manifest validation are performed below.

Validation for the 0.7.0 package:

  • node --check passed for web/app.js and web/sw.js.
  • PL/EN JSON and Home Assistant manifest parsed successfully; PL/EN translation key sets are identical (578 keys each).
  • Home Assistant Python modules passed python3 -m py_compile.
  • web/index.html parsed with Python's HTML parser; CSS braces are balanced.
  • No Swing arrow glyph remains in web controls, the device feature divider rule is removed, and the detailed-zone quick hint has an explicit wrapping rule.
  • All built-in schedule templates were exercised against the weekly minute-mask model: no overlaps; Family/Child/Bedroom/Always cover the full week, and Workday's intentional uncovered period falls back to the normal Comfort profile.
  • SQLite INIT_SCHEMA and device-delete orphan-schedule cleanup SQL were executed successfully against temporary in-memory databases.
  • Rust source delimiter/static checks passed. Rust compile/test execution is unavailable here because no Rust toolchain is installed.

0.7.1 quick-control visual consistency

  • Refactored dashboard-only thermostat/device controls to semantic quick-control-card and quick-control-row-* classes.
  • Quick thermostat preset/mode controls and quick manual HVAC/fan/function controls now share the same compact height, spacing, typography and fixed responsive grids.
  • Removed the superseded #dashboardDevices desktop-only size override; full Devices/Zones views remain unchanged.
  • Changed the compact inherited-mode label from Dom/House to Globalny/Global, while retaining the internal house value for API/backward compatibility.
  • Changed Sen teraz/Sleep now to Sen/Sleep.

Validation for the 0.7.1 package:

  • node --check passed for web/app.js and web/sw.js.
  • PL/EN JSON parsed successfully and translation key sets are identical (574 keys each).
  • Home Assistant manifest parsed successfully and Home Assistant Python modules passed python3 -m py_compile.
  • web/index.html parsed with Python's HTML parser and CSS brace balance passed.
  • Static assertions confirm the compact classes are attached only to dashboard quick cards (detailed == false), while full Zone/Device cards keep their existing classes and sizes.
  • Quick controls use explicit 3/4/5-column grids with no horizontal overflow behavior; all compact option buttons share the same 28 px minimum height, 9 px typography and 4 px gap.
  • User-facing inherited-mode labels are Globalny/Global; the internal/API value remains house, preserving backward compatibility.
  • No thermostat, schedule, automation, group, database or device-control logic was changed in 0.7.1.

0.7.2 zone configuration separation

  • Reworked the Zones list into read-only status + configuration cards.
  • Removed live temperature, preset, mode and enable/disable controls from the Zones list.
  • Added navigation from a zone configuration card to its matching Dashboard quick thermostat.
  • Kept backend zone-control endpoints and thermostat logic unchanged.
  • Kept the legacy setpoint field in form submission as a hidden compatibility value while profile temperatures remain the explicit configuration surface.

0.7.2 packaging hotfix

  • Corrected an invalid Cargo.lock entry that labeled the tokio-util package as 0.7.29 while retaining the checksum and dependency resolution for 0.7.19.
  • Restored tokio-util = 0.7.19, which satisfies tower-http 0.6.11 (^0.7) and is present in the crates.io index used by the target LXC.
  • No application source, database schema, scheduler, automation, device-control or Web UI logic changed in this hotfix.

0.7.3 Home Assistant climate-group support

  • Added restricted HA group discovery and group-control endpoints.
  • Added one Home Assistant device per configured climate group.
  • Added group Power switch, Thermostat mode select, Work profile select and Control plan sensor.
  • Group reporting derives common mode/profile from member-zone configuration and reports mixed states without coercing them.
  • Group plan attributes include members, online unit count, average current temperature, demand count and upcoming zone schedule events.
  • Existing group-control engine remains the single command path, including global-master-power and overlapping-disabled-group protections.

0.7.3 validation

  • python3 -m py_compile home-assistant/custom_components/gree_controller/*.py passed.
  • Home Assistant manifest and PL/EN translation JSON parsed successfully.
  • Cargo.toml parses successfully and both Cargo package metadata and HA manifest report 0.7.3.
  • Cargo.lock keeps the packaging hotfix at tokio-util = 0.7.19.
  • Static assertions confirm the restricted HA router exposes group discovery/control, the API client polls groups, and select/switch/sensor group entities are registered.
  • node --check web/app.js and node --check web/sw.js passed.
  • bash -n scripts/*.sh passed.
  • HTML parsing and CSS brace-balance checks passed.
  • The validation environment does not provide cargo/rustc, so the Rust test/build step must run on the target host/LXC (the normal scripts/update.sh performs cargo test --all-targets before installation).

2026-08-25 disabled-zone and standby-command hotfix

  • Disabled thermostat zones are excluded from normal house, group-loop and direct-device automation ownership while sensor polling/history continue normally.
  • Disabling an active zone now sends one immediate power-off command to its assigned unit. Later manual operation remains possible through the technical Devices control path.
  • Whole-house ON only powers devices assigned to enabled thermostat zones; unassigned devices and devices belonging to disabled zones are not started.
  • Whole-house OFF now cascades group power gates to OFF and powers off all enabled physical devices. Whole-house ON restores group gates but still respects disabled zones.
  • Restricted Home Assistant direct-device commands are rejected for devices assigned to disabled zones; zone/group/house endpoints keep their managed semantics.
  • Dashboard direct-device controls are locked for devices assigned to disabled zones and point the operator to the Devices view for explicit technical/manual control.
  • Smart Quiet now follows demand transitions instead of being reasserted throughout steady standby. Outside the night window it no longer fights Smart Fan by toggling Quiet off/on on successive cycles.
  • Standby Low fan is sent on a relevant transition/core thermostat change rather than retried forever when firmware reports a different fan state, preventing periodic command/beep loops with unchanged room temperature and setpoint.
  • Added regression assertions for steady-standby Smart Quiet behavior and night-mode/Smart-Fan interaction.
  • PWA cache key changed so browsers fetch the corrected frontend and language strings after deployment.

Validation in this packaging environment:

  • node --check web/app.js and node --check web/sw.js passed.
  • PL/EN application language JSON parsed successfully and translation-key parity passed.
  • web/index.html parsed successfully with Python's HTML parser.
  • Home Assistant Python modules and JSON manifests/translations passed syntax/parse checks.
  • Shell scripts passed bash -n.
  • Rust source was statically reviewed and delimiter-checked. This environment does not provide cargo, rustc or rustfmt; the normal target update path must run cargo test --all-targets and cargo build --release before installation.

0.7.4 physical/manual takeover

  • Added persistent per-zone device manual override state with source fields, start time and optional next-schedule expiry.
  • Polling detects external power/mode/setpoint/fan changes relative to the last controller-known state and suspends automatic correction for that zone.
  • Known standby Low-to-Auto fan normalization is ignored to avoid false remote-control detection.
  • Technical climate commands from the Devices endpoint enter the same takeover; light-only/non-thermostat feature changes do not.
  • Manual takeover has priority over zone modulation, climate groups and direct-device automations. Whole-house power-off is the explicit exception and clears all takeovers.
  • Added Web UI Manual control / remote state and Resume automation action, plus control-plan fields for integrations/simulation.
  • Added regression tests for external climate-state detection, Low-to-Auto suppression and takeover reset state.

0.7.4 validation

  • node --check passed for web/app.js and web/sw.js.
  • PL/EN language packs parse successfully, have identical key sets (586 keys each), and all UI translation references resolve.
  • Home Assistant Python modules and helper Python scripts pass py_compile; shell scripts pass bash -n.
  • Cargo metadata parses from Cargo.toml; package, Cargo lock root package and Home Assistant manifest report 0.7.4.
  • web/index.html parses successfully and CSS braces are balanced.
  • Rust source delimiter/static invariant checks pass, including poll detection, group/automation guards, whole-house override clear and technical manual-command routing.
  • The packaging environment has no cargo, rustc or rustfmt; the target update path remains the compile gate and must run cargo test --all-targets and cargo build --release before replacing the running binary.

0.7.5 UI polish

  • Added explicit active styling for climate-group ON/OFF buttons, matching the existing active mode/profile treatment.
  • Reworded simulator demand summary to Zones with demand / Strefy z zapotrzebowaniem.
  • Bumped application and Home Assistant integration version to 0.7.5 and rotated the PWA service-worker cache key.
  • Validation: node --check passed for the web scripts, PL/EN language packs parse with identical 587-key sets, version declarations are consistent and the package SHA-256 manifest verifies.
  • cargo check remains unavailable in this environment because the Rust toolchain is not installed.

2026-08-26 manual takeover, per-unit quick power and restart safety

Implemented against the supplied v0.7.5 source archive:

  • Manual/remote takeover now stores the pre-takeover physical climate state in the persisted zone payload.
  • If the user restores that operational state, the takeover clears automatically. When the previous state was OFF, returning to OFF is sufficient even if the remote retained a different dormant target/mode, so a stale Resume automation prompt is not shown.
  • If the manual state is not restored, the existing next-schedule-boundary expiry remains unchanged; zones without a future transition still require an explicit resume.
  • Dashboard Quick thermostats now include per-unit ON/OFF controls. They intentionally use manual/remote semantics, affect only that physical unit and do not enable its climate group.
  • Cooling controlled by a valid external/combined room sensor now applies a small pre-rounding demand bias so the unit selects the next lower whole-degree target (normally 0.5-1.0 C below the room target). The bias is disabled during GREE fallback/discrepancy fallback and is not added on top of a larger outdoor-assist correction.
  • Startup thermostat/schedule/automation command emission is gated until one complete poll attempt of all enabled devices finishes. This prevents stale persisted device state from producing a restart-only command while leaving manual API control available.
  • /api/health, bootstrap system data and /api/system/info expose control_ready for startup diagnostics.
  • Advanced the PWA cache key to gree-controller-v075-zone-manual-power-restart so changed dashboard assets are refreshed.

Validation performed in this packaging environment:

  • node --check web/app.js - passed.
  • node --check web/sw.js - passed.
  • EN/PL JSON parsing and translation-key parity - passed (590/590 keys).
  • Static tr(...)/data-i18n references in the Web UI - all resolved.
  • web/manifest.webmanifest JSON parsing - passed.
  • bash -n scripts/*.sh - passed.
  • Home Assistant Python modules and helper Python scripts compiled with python3 -m py_compile - passed.
  • All direct Zone { ... } constructors were updated for the new persisted baseline field.

Rust compiler note: this packaging environment still does not provide cargo, rustc or rustfmt, so the Rust unit tests and release build cannot be executed here. The normal deployment/update compile gate must still run cargo test --all-targets and cargo build --release before replacing the running binary.

2026-08-26 Home Assistant state-bounce fix

  • Added bounded post-command GREE status settling retries (0/150/350/650 ms) so an acknowledged write is not immediately contradicted by a firmware status frame that still contains the pre-command state.
  • Added a three-second Home Assistant pending-command guard for physical-unit climate and optional-feature switches. Fresh command intent survives overlapping/stale coordinator refreshes, then automatically yields to factual controller polling.
  • Kept the guard intentionally short and non-persistent; it does not change restart behavior or permanently mask a failed command.

2026-08-26 v0.7.7 quick-control desktop label fit

  • Reproduced the dashboard quick-device layout issue from the supplied screenshot: five equal columns left too little usable width after button padding for Polish Chłodzenie/Osuszanie.
  • Rebalanced only the five quick-device mode columns and reduced their horizontal padding from 5 px to 3 px. This keeps all five labels on one line without reducing the shared 9 px control font.
  • Verified the Home Assistant integration already exposes every controller zone as an independent climate thermostat with TURN_ON/TURN_OFF, plus a separate per-zone Enabled switch. Turning on a zone thermostat sends only enabled: true for that zone; it does not power the whole group. Physical indoor units also remain independently controllable through their own climate entities.
  • Bumped application/Home Assistant package metadata to 0.7.7 and rotated the PWA cache key.

2026-08-26 v0.7.8 zone status wording and quick unit power

  • Replaced the misleading thermostat runtime labels Potrzeba komfortu / Komfort / standby inwertera with Zapotrzebowanie aktywne / Cel osiągnięty. The Comfort wording remains reserved for the actual Comfort preset/profile. Runtime status also reports Oczekiwanie when thermostat control is paused by mode and Brak pomiaru when no valid control temperature is available, so Cel osiągnięty is not used as a generic idle state.
  • Simplified per-unit manual power in Dashboard -> Quick thermostats: removed the redundant Jednostka · pilot caption and the separate ON/OFF pair. A single contextual Włącz jednostkę / Wyłącz jednostkę button now directly controls only that physical unit with the existing manual-takeover semantics.
  • Bumped package/Home Assistant metadata to 0.7.8 and rotated the PWA cache key.

2026-08-27 v0.7.9 zone profile and Home Assistant fixes

  • Explicit quick-zone target/mode/profile/enable actions now refresh the runtime profile target immediately and wake the regulator instead of waiting for the next fixed thermostat interval.
  • Manual/remote takeover no longer exposes a physical standby target (for example 25 C) as the zone thermostat target. The thermostat profile target and physical device_setpoint are reported separately.
  • Control-plan enabled is now the configured per-zone switch; new effective_enabled reports disabled-group gating without making the Home Assistant zone switch bounce to Off.
  • Home Assistant zone commands have a short pending-state guard against stale overlapping refreshes.
  • Zone climate entities support Auto/Comfort/Sleep/Away presets and each zone device has a dedicated Work profile select.
  • Added a focused Rust unit test for immediate manual-profile target refresh.

Validation for this package is recorded after the final archive/manifest checks. Rust compile/test still requires the normal target/CI host because this packaging environment has no Rust toolchain.

2026-08-27 v0.7.10 local quick thermostat and false takeover fix

  • Added persisted local_thermostat_power ownership with three distinct states: normal group/schedule ownership (null), locally forced thermostat ON (true) and locally forced thermostat OFF (false).
  • Dashboard quick ON/OFF uses local thermostat semantics and never calls the direct/manual-device command path.
  • A locally active thermostat bypasses disabled climate-group power gates while retaining the normal sensor, hysteresis, profile/target, Smart Fan and GREE setpoint-modulation logic.
  • Resume automation for a local thermostat clears local ownership and returns the zone to group/schedule control. The existing device takeover Resume action remains separate.
  • Direct device commands and genuine remote/pilot changes still create device_manual_override; local thermostat ownership does not.
  • Added a bounded pending controller-command record for GREE climate fields when post-command status has not settled. A later poll matching that expected state is no longer misclassified as remote control, fixing false Manual control / remote after group ON and similar controller-originated transitions.
  • Direct device automations are suppressed while local thermostat ownership is active so they cannot fight the local regulator.
  • Home Assistant zone climate ON/OFF now maps to local thermostat power; the separate Enabled switch remains the technical zone enable.
  • Rotated the PWA cache key and advanced package/Home Assistant metadata to 0.7.10.

Final validation for v0.7.10

  • node --check passed for all Web UI JavaScript files.
  • Home Assistant modules, helper scripts and make_zip.py passed python3 -m py_compile.
  • All JSON files parsed successfully; Polish and English language packs have identical 598-key sets.
  • All shell scripts passed bash -n; web/index.html parsed successfully and CSS braces are balanced.
  • Cargo package, Home Assistant manifest, README and PWA cache metadata consistently report version 0.7.10.
  • Rust source delimiter/static invariant checks passed, including the new regulator wake-up and control-plan fields.
  • FILE_MANIFEST.sha256 is regenerated from the final tree and verified before packaging; the resulting ZIP is tested with unzip -t.
  • This environment does not provide cargo, rustc or rustfmt, so the normal target/CI update path must still run cargo test --all-targets and cargo build --release before replacing the running binary.

2026-08-27 v0.7.11 cleanup and compile fix

  • Removed the obsolete /api/zones/{id}/manual-power compatibility route, request structure and handler. The only zone quick-power API is now POST /api/zones/{id}/control with power:true/false.
  • Renamed Web UI local-thermostat power internals so they no longer use misleading manual-power terminology.
  • Fixed Rust error E0505 in local_thermostat_ownership_blocks_direct_automation: the test now passes a borrowed one-element slice with std::slice::from_ref(&zone) instead of moving zone while borrowing zone.device_id.
  • Advanced package/Home Assistant/PWA metadata to 0.7.11.

Final validation for v0.7.11

  • node --check passed for Web UI JavaScript files.
  • Home Assistant modules, helper scripts and make_zip.py passed python3 -m py_compile.
  • JSON files parsed successfully; Polish and English language packs have identical 602-key sets.
  • All shell scripts passed bash -n; web/index.html parsed successfully and CSS braces are balanced.
  • Runtime source trees (src, web, home-assistant, scripts) contain no legacy manual-power route, handler, symbol or CSS naming.
  • Cargo package and Home Assistant manifest report version 0.7.11; PWA cache metadata was rotated for this release.
  • The reported Rust E0505 test case was corrected with borrow-only std::slice::from_ref(&zone) calls.
  • This packaging environment does not provide cargo, rustc or rustfmt; target/CI must run cargo test --all-targets and cargo build --release before deployment.

2026-08-27 v0.7.12 timed local-thermostat resume

  • Added persisted local_thermostat_resume_at to each zone.
  • Local Quick Thermostat ON has no timeout; local OFF powers the unit down immediately and schedules automatic automation hand-back after exactly 15 minutes.
  • The control loop now sleeps only until the earlier of its normal interval or the nearest local-resume deadline, so the 15-minute hand-back is not delayed by a long zone interval and remains restart-safe.
  • Expiry clears local power ownership and quick preset/setpoint overrides, then re-evaluates the current group, house mode, schedule, temperature and hysteresis. It never restores a stale physical ON/OFF snapshot.
  • Physical/pilot device_manual_override is intentionally untouched by the local timer.
  • Web UI displays a live MM:SS countdown and Resume now during the local-OFF window.
  • Persisted 0.7.10/0.7.11 local-OFF records without a deadline receive a fresh 15-minute deadline on first control cycle after upgrade.
  • Home Assistant zone attributes expose local_thermostat_resume_at.
  • Added a unit test that verifies local hand-back clears local quick state without clearing a real physical-device takeover.

Final validation for v0.7.12

  • Web JavaScript passes node --check.
  • Home Assistant modules and helper scripts pass python3 -m py_compile.
  • JSON and TOML metadata parse successfully; Polish and English translation packs have identical key sets.
  • Shell scripts pass bash -n; HTML parses and CSS braces are balanced.
  • Source references for local_thermostat_resume_at are consistent across model, API, engine, Web UI, control-plan output and Home Assistant attributes.
  • Version metadata is aligned at 0.7.12 and the PWA cache key is rotated.
  • This packaging environment still has no cargo, rustc or rustfmt; target/CI must run cargo test --all-targets and cargo build --release before deployment.

2026-08-27 v0.7.13 quick-thermostat race protection and frame counters

  • Quick Thermostat changes from Web/Home Assistant are serialized with the same per-device operation lock used by polling/manual-takeover detection.
  • Controller-originated climate changes retain a bounded settling history of requested and pre-command states so delayed/out-of-order GREE status frames do not falsely trigger physical/pilot takeover.
  • Dashboard Quick Thermostat Global is disabled whenever the global house mode is neither Heating nor Cooling.
  • Settings exposes live total and per-device UDP receive counters for configured GREE units via the existing WebSocket stream.
  • The Home Assistant zone climate entity remains the supported path for controlling one thermostat independently.

Final validation for v0.7.13

  • node --check passed for web/app.js and web/sw.js.
  • All JSON files parsed successfully; Polish and English language packs have identical 610-key sets.
  • Home Assistant Python modules and helper Python scripts pass py_compile; shell scripts pass bash -n.
  • web/index.html parses successfully and CSS brace balance passes.
  • Cargo package, Home Assistant manifest, README and PWA cache metadata are aligned at 0.7.13.
  • The final SHA-256 file manifest and ZIP integrity are verified during packaging.
  • This packaging environment does not provide cargo, rustc or rustfmt; target/CI must run cargo test --all-targets and cargo build --release before deployment.