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_at15-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_belowandat_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.jsnode --check web/theme-init.jsnode --check web/sw.js- parsed all JSON files
python3 -m compileall -q home-assistant scripts make_zip.pybash -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'stranslationsobject, so the Web UI receives translated values instead of raw translation keys. - Simplified the Polish owner caption from
Właściciel sterowaniatoSterowanieand allowed the owner/timing line to wrap instead of truncating. - Added
home_assistant.sensor_stale_after_secondswith 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_secondsvalues remain per-zone API overrides; the historical hidden/default 300 s value inherits the global HA setting. - Added
HA_SENSOR_STALE_AFTER_SECONDSas 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.rsnow rejects unexpected top-level language-pack keys, preventing translation keys from being accidentally stored outsidetranslationsagain.- 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.jsnode --check web/theme-init.jsnode --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.pybash -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 acrossrefresh_control_ownership(&mut zone, ...). node --checkpassed 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,rustcorrustfmt; therefore the target-host update script remains the authoritative Rust compile/test gate and must runcargo test --all-targetsandcargo build --releasebefore 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
revisionrequest 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_sourcekeeps its historical meaning (temperature source). The new command provenance is exported ascontrol_command_sourceto avoid breaking Home Assistant or third-party consumers. - Existing physical and zone climate entity unique IDs remain unchanged.
Validation available in this environment
node --checkpassed 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
ZoneandZoneControlPlanliterals 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/testcannot 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_atreturned 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
climateentity 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 + optionalQuiet=1in one GREE frame. If a unit rejectsQuiet, 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-planexposes 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
numberentities and per-zone enableswitchentities via the restricted integration API.
0.6.1 compile hotfix
- Fixed
u8/u32mismatches in communication-failure threshold handling without changing the persistedDevice.communication_failurestype or notification-settings schema. - Removed the unused
AppStateparameter 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/*.shfiles. - 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_timeoutanomaly 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.pngandlogo.pngbased on the existing project mark. - New installs create a minimal environment file, keep
SIMULATE=falseandAUTO_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.mdanddocs/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 runcargo test/cargo build --releasebefore 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-pressedfor 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>_thermostatinstead 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_2for a zone currently named Igor). - Migration is collision-safe: if the desired
climate.<zone_name>_thermostatID 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
offis 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
unknownsolely 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.jsandnode --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_SCHEMAexecuted against an empty SQLite database and the newclimate_groupstable verified.- Rust compilation cannot be executed here because the environment does not contain
cargo,rustcorrustfmt; the backend changes were statically reviewed and still require the normal LXC/CIcargo test --all-targetsandcargo build --releasegate 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-dashboardso 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 --checkpassed forweb/app.jsandweb/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.htmlparsed 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_SCHEMAand 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-cardandquick-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
#dashboardDevicesdesktop-only size override; full Devices/Zones views remain unchanged. - Changed the compact inherited-mode label from
Dom/HousetoGlobalny/Global, while retaining the internalhousevalue for API/backward compatibility. - Changed
Sen teraz/Sleep nowtoSen/Sleep.
Validation for the 0.7.1 package:
node --checkpassed forweb/app.jsandweb/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.htmlparsed 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 remainshouse, 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
setpointfield 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.lockentry that labeled thetokio-utilpackage as0.7.29while retaining the checksum and dependency resolution for0.7.19. - Restored
tokio-util = 0.7.19, which satisfiestower-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/*.pypassed.- Home Assistant manifest and PL/EN translation JSON parsed successfully.
Cargo.tomlparses successfully and both Cargo package metadata and HA manifest report0.7.3.Cargo.lockkeeps the packaging hotfix attokio-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.jsandnode --check web/sw.jspassed.bash -n scripts/*.shpassed.- 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 normalscripts/update.shperformscargo test --all-targetsbefore 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.jsandnode --check web/sw.jspassed.- PL/EN application language JSON parsed successfully and translation-key parity passed.
web/index.htmlparsed 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,rustcorrustfmt; the normal target update path must runcargo test --all-targetsandcargo build --releasebefore 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 --checkpassed forweb/app.jsandweb/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 passbash -n. - Cargo metadata parses from
Cargo.toml; package, Cargo lock root package and Home Assistant manifest report0.7.4. web/index.htmlparses 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,rustcorrustfmt; the target update path remains the compile gate and must runcargo test --all-targetsandcargo build --releasebefore 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.5and rotated the PWA service-worker cache key. - Validation:
node --checkpassed 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 checkremains 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/infoexposecontrol_readyfor startup diagnostics.- Advanced the PWA cache key to
gree-controller-v075-zone-manual-power-restartso 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-i18nreferences in the Web UI - all resolved. web/manifest.webmanifestJSON 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 onlyenabled: truefor 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.7and 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.8and 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_setpointare reported separately. - Control-plan
enabledis now the configured per-zone switch; neweffective_enabledreports 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_powerownership 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 --checkpassed for all Web UI JavaScript files.- Home Assistant modules, helper scripts and
make_zip.pypassedpython3 -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.htmlparsed 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.sha256is regenerated from the final tree and verified before packaging; the resulting ZIP is tested withunzip -t.- This environment does not provide
cargo,rustcorrustfmt, so the normal target/CI update path must still runcargo test --all-targetsandcargo build --releasebefore replacing the running binary.
2026-08-27 v0.7.11 cleanup and compile fix
- Removed the obsolete
/api/zones/{id}/manual-powercompatibility route, request structure and handler. The only zone quick-power API is nowPOST /api/zones/{id}/controlwithpower:true/false. - Renamed Web UI local-thermostat power internals so they no longer use misleading
manual-powerterminology. - Fixed Rust error E0505 in
local_thermostat_ownership_blocks_direct_automation: the test now passes a borrowed one-element slice withstd::slice::from_ref(&zone)instead of movingzonewhile borrowingzone.device_id. - Advanced package/Home Assistant/PWA metadata to
0.7.11.
Final validation for v0.7.11
node --checkpassed for Web UI JavaScript files.- Home Assistant modules, helper scripts and
make_zip.pypassedpython3 -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.htmlparsed successfully and CSS braces are balanced. - Runtime source trees (
src,web,home-assistant,scripts) contain no legacymanual-powerroute, 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,rustcorrustfmt; target/CI must runcargo test --all-targetsandcargo build --releasebefore deployment.
2026-08-27 v0.7.12 timed local-thermostat resume
- Added persisted
local_thermostat_resume_atto 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_overrideis intentionally untouched by the local timer. - Web UI displays a live
MM:SScountdown 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_atare consistent across model, API, engine, Web UI, control-plan output and Home Assistant attributes. - Version metadata is aligned at
0.7.12and the PWA cache key is rotated. - This packaging environment still has no
cargo,rustcorrustfmt; target/CI must runcargo test --all-targetsandcargo build --releasebefore 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
climateentity remains the supported path for controlling one thermostat independently.
Final validation for v0.7.13
node --checkpassed forweb/app.jsandweb/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 passbash -n. web/index.htmlparses 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,rustcorrustfmt; target/CI must runcargo test --all-targetsandcargo build --releasebefore deployment.