v0.4.1
This commit is contained in:
+73
-21
@@ -55,58 +55,110 @@ curl -X POST "$BASE/api/discovery" -H "$AUTH" -H 'Content-Type: application/json
|
||||
|
||||
Supported modes: `auto`, `cool`, `dry`, `fan`, `heat`. Fan speed: `0..5`. Physical GREE Celsius setpoints are normalized to whole degrees in the `8..30°C` range.
|
||||
|
||||
## Zone
|
||||
## Smart thermostat / house control
|
||||
|
||||
The controller separates the seasonal house mode from per-zone profiles. Normal operation uses setpoint modulation: units remain powered while the controller moves the device target between an active and satisfied setpoint. `off` is the explicit hard-off house mode.
|
||||
|
||||
```bash
|
||||
curl -X POST "$BASE/api/house/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"mode":"cool"}'
|
||||
|
||||
curl -X POST "$BASE/api/house/preset" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"preset":"sleep"}'
|
||||
```
|
||||
|
||||
House modes: `cool`, `heat`, `off`. House presets: `auto`, `comfort`, `sleep`, `away`. A non-`auto` house preset creates temporary per-zone overrides that expire at each zone's next schedule boundary.
|
||||
|
||||
A zone stores separate profile temperatures for both seasons:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Living room",
|
||||
"name": "Paweł",
|
||||
"device_id": "gree-aabbccddeeff",
|
||||
"enabled": true,
|
||||
"mode": "cool",
|
||||
"inherit_house_mode": true,
|
||||
"setpoint": 23.0,
|
||||
"cool_comfort_setpoint": 23.0,
|
||||
"cool_sleep_setpoint": 24.5,
|
||||
"cool_away_setpoint": 27.0,
|
||||
"heat_comfort_setpoint": 21.0,
|
||||
"heat_sleep_setpoint": 19.0,
|
||||
"heat_away_setpoint": 17.0,
|
||||
"hysteresis": 0.6,
|
||||
"min_on_seconds": 180,
|
||||
"min_off_seconds": 180,
|
||||
"min_adjust_seconds": 120,
|
||||
"standby_offset_c": 2.0,
|
||||
"smart_fan": true,
|
||||
"sensor_source": "combined",
|
||||
"ha_entity_id": "sensor.living_room_temperature",
|
||||
"ha_entity_id": "sensor.pawel_temperature",
|
||||
"external_sensor_weight": 0.4,
|
||||
"max_sensor_difference": 3.0
|
||||
}
|
||||
```
|
||||
|
||||
`sensor_source` supports:
|
||||
|
||||
- `device` — GREE indoor sensor only,
|
||||
- `combined` — GREE + this zone's HA room sensor,
|
||||
- `home_assistant` — this zone's HA room sensor, with GREE fallback.
|
||||
|
||||
For `combined` and `home_assistant`, set a per-zone `ha_entity_id`. `external_sensor_weight` is `0.0..1.0`. If a combined sensor pair differs by more than `max_sensor_difference`, the controller falls back to GREE. The returned zone object includes `device_temperature`, `external_temperature`, `current_temperature`, and `control_temperature_source`.
|
||||
|
||||
### Quick zone control
|
||||
Quick control does not directly fight the schedule engine:
|
||||
|
||||
```bash
|
||||
# Sleep now until the next schedule boundary
|
||||
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"setpoint":21.5,"mode":"heat"}'
|
||||
-d '{"preset":"sleep"}'
|
||||
|
||||
# Return to automatic schedule
|
||||
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"preset":"auto"}'
|
||||
|
||||
# Temporary custom room target
|
||||
curl -X POST "$BASE/api/zones/ZONE_ID/control" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"setpoint":22.5}'
|
||||
```
|
||||
|
||||
Fields are optional: `setpoint`, `mode` (`heat`/`cool`) and `enabled`. The zone setpoint may use 0.5°C precision for controller hysteresis; when the quick control changes setpoint/mode, the paired GREE unit is updated immediately while its current power state is preserved.
|
||||
`mode` on the quick zone endpoint accepts `house`, `cool`, or `heat`. Global `off` always wins over local zone mode overrides.
|
||||
|
||||
## Schedule
|
||||
### Ready-made schedule templates
|
||||
|
||||
Weekdays use ISO numbers: Monday `1`, Sunday `7`.
|
||||
Templates generate normal schedule records and replace the current schedules for the selected zone. Every generated entry remains editable.
|
||||
|
||||
```bash
|
||||
curl -X POST "$BASE/api/zones/ZONE_ID/schedule-template" -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
-d '{"template":"child"}'
|
||||
```
|
||||
|
||||
Templates: `family`, `child`, `bedroom`, `workday`, `always`.
|
||||
|
||||
Schedules use a profile (`comfort`, `sleep`, `away`) or a custom temperature:
|
||||
|
||||
```json
|
||||
{
|
||||
"zone_id": "UUID",
|
||||
"name": "Night",
|
||||
"name": "Sleep",
|
||||
"enabled": true,
|
||||
"weekdays": [1,2,3,4,5,6,7],
|
||||
"start_time": "22:00",
|
||||
"end_time": "06:00",
|
||||
"start_time": "20:30",
|
||||
"end_time": "06:30",
|
||||
"preset": "sleep",
|
||||
"setpoint": 24.0
|
||||
}
|
||||
```
|
||||
|
||||
For non-`custom` schedules, `setpoint` is only a compatibility value; the actual target comes from the zone's seasonal profile.
|
||||
|
||||
### Home Assistant outdoor assist and local HTTPS
|
||||
|
||||
Runtime settings can specify `home_assistant.outdoor_entity_id` and `outdoor_assist_enabled`. Outdoor temperature never replaces the zone room temperature. It is only used to make active setpoints/fan speed slightly more assertive in extreme weather.
|
||||
|
||||
For trusted local Home Assistant servers with self-signed/invalid HTTPS certificates, set:
|
||||
|
||||
```json
|
||||
{
|
||||
"home_assistant": {
|
||||
"url": "https://10.87.65.2",
|
||||
"allow_invalid_tls": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This setting is opt-in and applies only to the controller's outbound Home Assistant sensor client.
|
||||
|
||||
## WebSocket
|
||||
|
||||
Connect to `ws://HOST:8787/ws?token=TOKEN`. The first message uses event type `bootstrap`; later events include `device.updated`, `zone.updated`, `settings.updated` and `log.created`.
|
||||
|
||||
@@ -168,3 +168,10 @@ For a dedicated GREE NIC such as `eth1`, the expected startup/bind log should id
|
||||
### Legacy V1 devices discovered but not binding
|
||||
|
||||
Version 0.3.8 sends the GREE protocol `tcid` and inner `mac` identifiers in canonical lowercase hexadecimal. If an older `502cc6...` device is discovered on UDP/7000 but stays offline after bind timeouts, update to v0.3.8 before changing routing or firewall settings. With debug logging, `Sending GREE request` should show `wire_mac=502cc6...` in lowercase.
|
||||
|
||||
|
||||
## Home Assistant HTTPS with a self-signed certificate
|
||||
|
||||
The optional outbound HA sensor client validates TLS certificates by default. For a trusted local endpoint such as `https://10.87.65.2` that uses a self-signed, expired or hostname-mismatched certificate, enable **Settings -> Allow invalid/self-signed HTTPS certificate** and save. The same initial setting can be supplied as `HA_ALLOW_INVALID_TLS=true`.
|
||||
|
||||
This opt-in affects only controller -> Home Assistant sensor requests. It does not change the GREE UDP transport and it does not add HTTPS termination to the controller itself.
|
||||
|
||||
+32
-12
@@ -66,23 +66,35 @@ Each device stores:
|
||||
- fan, swing, quiet, turbo, light,
|
||||
- online/last-seen/error state.
|
||||
|
||||
## Temperature zones
|
||||
## Smart thermostat, zones and schedules
|
||||
|
||||
A zone connects an AC to a temperature-control policy. It contains:
|
||||
The primary user model is a fast thermostat, not raw device automation. A global **House mode** selects the season (`cool`, `heat`, `off`). Zones follow it by default and can optionally override Heat/Cool. Global Off is authoritative and powers controlled units down.
|
||||
|
||||
- target setpoint,
|
||||
- heat/cool mode,
|
||||
- hysteresis,
|
||||
- minimum ON time,
|
||||
- minimum OFF time,
|
||||
- temperature source,
|
||||
- optional Home Assistant sensor entity.
|
||||
During normal heating/cooling the controller minimizes unit power cycling. It keeps the indoor unit powered and uses **setpoint modulation**:
|
||||
|
||||
Each zone can assign its own Home Assistant room sensor. Combined mode fuses the GREE and room measurements with a configurable weight (40% room sensor by default), while GREE remains the primary input. If HA is unavailable or the two sensors differ beyond the configured limit, control falls back to the GREE sensor.
|
||||
- when the zone requires conditioning, use the active target (optionally assisted slightly by outdoor weather),
|
||||
- when the zone is satisfied, move the device setpoint to the non-demand side of the room target so the inverter/compressor can stop naturally,
|
||||
- use hysteresis and a minimum adjustment interval to avoid command chatter,
|
||||
- optionally adjust fan speed based on room error and outdoor extremes.
|
||||
|
||||
Each zone has separate seasonal profile temperatures:
|
||||
|
||||
- Cooling: Comfort / Sleep / Away,
|
||||
- Heating: Comfort / Sleep / Away.
|
||||
|
||||
The zone can use the GREE internal sensor, its own Home Assistant room sensor, or a weighted combination. External room sensors are configured per zone; loss/discrepancy falls back safely to the GREE sensor.
|
||||
|
||||
Weekly schedules reference profiles instead of duplicating temperatures. Ready-made Family, Child room, Bedroom, Workday and Always-comfort templates create ordinary schedule rows that remain fully editable. A manual **Sleep now**, Comfort, Away or custom-temperature override ends automatically at the next schedule boundary. Whole-house preset actions apply the same temporary policy to every zone.
|
||||
|
||||
Automations remain available for advanced exceptions. Daily comfort should be implemented with zones/profiles/schedules so direct-device automation commands do not compete with the thermostat engine.
|
||||
|
||||
### Outdoor temperature assist
|
||||
|
||||
A configured Home Assistant outdoor-temperature entity is optional auxiliary context. It never replaces the room-control temperature. Under strong heat/cold the engine may slightly bias the active AC target and increase Smart Fan airflow. If HA is unavailable, the smart thermostat continues without outdoor assistance.
|
||||
|
||||
## Scheduler and automations
|
||||
|
||||
Schedules are weekly time windows and may cross midnight. Automations currently support time or temperature triggers and send device commands with cooldown protection.
|
||||
Schedules are weekly time windows and may cross midnight. Schedules can select Comfort/Sleep/Away or a custom setpoint. Automations support time or temperature triggers and device commands with cooldown protection; they are intended for exceptions rather than the normal daily thermostat cycle.
|
||||
|
||||
The automation engine runs in Rust and does not require Home Assistant YAML automation logic.
|
||||
|
||||
@@ -142,7 +154,8 @@ A development script prepares dependencies/build/runtime configuration, and a se
|
||||
- secrets kept outside source control,
|
||||
- no direct public Internet exposure,
|
||||
- TLS delegated to a trusted reverse proxy/VPN when required,
|
||||
- local device keys and HA token protected in environment/database files.
|
||||
- local device keys and HA token protected in environment/database files,
|
||||
- invalid/self-signed HA HTTPS certificates are rejected by default; bypass is an explicit trusted-LAN opt-in.
|
||||
|
||||
|
||||
## Per-zone room sensors
|
||||
@@ -160,3 +173,10 @@ The zone controller supports `device`, `combined`, and `home_assistant` temperat
|
||||
- `scripts/service.sh` provides common systemd operations.
|
||||
- Cargo's `build.rs` stays at the package root because Cargo requires that location.
|
||||
- Every SQLite statement and schema definition is centralized in `src/queries.rs`; database/domain code must not embed SQL strings elsewhere.
|
||||
|
||||
|
||||
## Web UI design system (v0.4.1)
|
||||
|
||||
The embedded UI uses a compact Supabase-inspired dashboard language while retaining GREE Controller branding and information architecture. Light, Dark and System themes are driven by CSS design tokens. The visual system favors neutral layered surfaces, thin borders, 6-8 px radii, compact controls, a restrained green accent, no decorative shadows, a desktop sidebar and mobile bottom navigation.
|
||||
|
||||
Tailwind CSS is an optional local build dependency only. `web/styles.css` is committed and embedded into the Rust binary, so production/LXC runtime has no CDN or Node.js dependency. UI source/build files are `web/tailwind.input.css`, `tailwind.config.js`, `package.json`, and `scripts/build-web.sh`.
|
||||
|
||||
Reference in New Issue
Block a user