Skip to content

MIELHVAC New features and bug fixes#24660

Merged
arendst merged 2 commits intoarendst:developmentfrom
grzegorz914:development
Apr 21, 2026
Merged

MIELHVAC New features and bug fixes#24660
arendst merged 2 commits intoarendst:developmentfrom
grzegorz914:development

Conversation

@grzegorz914
Copy link
Copy Markdown
Contributor

@grzegorz914 grzegorz914 commented Apr 20, 2026

Bug Fixes

Memory leak in miel_hvac_pre_init() — on serial init failure, goto del jumped past free(sc), leaking the allocated state struct. Replaced with explicit delete sc->sc_serial; free(sc); return;.

remotetemp_clear semantics inverted — the variable was initialised true and caused a CLR frame to be sent on boot before any sensor had registered. Renamed to remotetemp_active, initialised false, and CLR is only sent after an active SET.

HVACSetPurify used wrong map — was passing airdirection_map instead of purifier_map.

0x08 Set Run State flags byte order — flags are little-endian on the wire (ref: muart-group/muart-group.github.io#17). Removed htons() from all 0x08 flag operations.

widevane_isee false positives — values like 0x84/0x85/0x8c (ISEE bit + physical position nibble) were incorrectly reported as AirDirection:"even". Reverted to exact-match for known active values (0x80, 0x28, 0xaa).


New Features

Base Capabilities query (0x5B 0xC9) — after connecting, the driver sends an Identify Request and parses the 0x7B 0xC9 response into a capability struct. Exposed as *Supported fields in the MiElHVAC JSON object.

HVAC Options polling (0x42) — new miel_hvac_data_hvac_options struct and request type. Polls Purifier, NightMode and EconoCool state. Sent with len=1 (short request form). Units without cap_run_state skip this slot entirely to avoid timeouts.

Run State commands (0x41 0x08) — added HVACSetPurify, HVACSetNightMode, HVACSetEconoCool and HVACSetAirDirection routed through command 0x08 on units that report cap_run_state=true. Optimistic local update applied before confirmation.

EconoCool0x08 byte 14, flag 0x10, COOL mode only. Command HVACSetEconoCool on|off.

i-See runtime detection — new sc_has_isee flag set when widevane shows i-See state (0x80 bit or values 0x28/0xaa). Used to distinguish units with vertical vane + i-See from units with vane only.

Capabilities-aware command validation — commands are blocked before send when the unit reports a feature unavailable:

  • HVACSetMode/HVACSetHAMode — blocks heat/dry/fan when unsupported (ISEE variants share parent mode bit)
  • HVACSetTemp — narrows range using unit-reported min/max per mode
  • HVACSetFanSpeed — blocks AUTO without cap_fan_auto, QUIET without 5 speeds, FAN_4 without 4 speeds
  • HVACSetPurify/HVACSetNightMode/HVACSetEconoCool — return NotSupported without cap_run_state
  • HVACSetAirDirection — returns ControlNotSupported when vane+i-See present but no run state

Web UI rows for Power and Energy — added FUNC_WEB_SENSOR handler via WSContentSend_PD showing instantaneous power (W) and cumulative total (kWh) on the Tasmota main page.

miel_hvac_append_settings_json() — shared JSON builder used by both HVACSETTINGS and SENSOR topics.


JSON Changes

  • Power (W) and Energy (kWh) now published both inside MiElHVAC and in a standard Tasmota ENERGY{} sub-object (Power/Total) for Home Assistant auto-discovery.
  • Purifier, NightMode, EconoCool shown in MiElHVAC and HVACSettings when cap_run_state=true, otherwise omitted.
  • AirDirection hidden from MiElHVAC and HVACSettings when the unit lacks a vertical vane or has no observed i-See sensor.
  • New flat fields in MiElHVAC from Base Capabilities: ModeHeatSupported, ModeDrySupported, ModeFanSupported, VaneVSupported, SwingSupported, FanAutoSupported, OutdoorTemperatureSupported, AirDirectionSupported, PurifierSupported, NightModeSupported, EconoCoolSupported, SetTemperatureCoolMinMax, SetTemperatureHeatMinMax, SetTemperatureAutoMinMax, CapabilitiesHex.
  • Values on / off / not_supported / control_not_supported.
  • AirDirectionSupported reports:
    • not_supported — no vertical vane, or no i-See observed
    • control_not_supported — vane + i-See present but unit does not support 0x08 Set Run State
    • on — full support
  • OptionsHex added for the 0x42 HVAC Options packet.

Tested on

MSZ-LN25VG2W — cap_run_state=false, temperature ranges 16–31 °C (cool/auto) and 10–31 °C (heat), 5 fan speeds, outdoor temperature reporting confirmed.

Checklist:

  • The pull request is done against the latest development branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • The code change is tested and works with Tasmota core ESP8266 V.2.7.8
  • The code change is tested and works with Tasmota core ESP32 V.3.1.11 / V.3.3.8
  • I accept the CLA.

NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass

## Changelog

### Bug Fixes

**Memory leak in `miel_hvac_pre_init()`** — `goto del` jumped past the `free(sc)` label, leaking the allocated struct on serial init failure. Replaced with explicit `delete`/`free`/`return`.

**`remotetemp_clear` semantics inverted** — variable was `true` on boot causing a CLR frame to be sent before any sensor registered. Renamed to `remotetemp_active`, initialised `false`.

**`HVACSetPurify` used wrong map** — `airdirection_map` was passed instead of `purifier_map`.

**`0x08` Set Run State flags wrong byte order** — flags are little-endian on the wire (ref: muart-group/muart-group.github.io#17). Removed `htons()` from all `0x08` flag assignments.

**`widevane_isee` false positives** — values like `0x84`/`0x85`/`0x8c` (ISEE bit + position nibble) incorrectly reported `AirDirection:"even"`. Reverted to exact-match for `0x80`, `0x28`, `0xaa`.

---

### New Features

**`0x42` HVAC Options polling** — added `miel_hvac_data_hvac_options` struct and `MIEL_HVAC_REQUEST_HVAC_OPTIONS` request. The unit is polled for Purifier, NightMode and EconoCool state. Requires short request form (len=1). Results stored in `sc_hvac_options` and published in SENSOR and HVACSETTINGS when `cap_run_state=true`.

**Run State commands (`0x41 0x08`)** — new commands `HVACSetPurify`, `HVACSetNightMode`, `HVACSetEconoCool` and `HVACSetAirDirection` sent via `0x08` on units that report `cap_run_state=true`. Optimistic update to `sc_hvac_options` applied before confirmation.

**EconoCool** — `0x08` byte 14, flag `0x10`, COOL mode only. Command `HVACSetEconoCool on|off`.

**Base Capabilities (`0x5B 0xC9`)** — queried once after connecting. Parsed into `miel_hvac_capabilities`. Results published flat inside `MiElHVAC` as `*Supported` fields. Temperature ranges published as °C. Raw packet in `CapabilitiesHex`.

**Capabilities-aware command validation** — commands blocked when unit reports feature unavailable: modes (heat/dry/fan), temperature range from capabilities, fan speeds, run state commands return `NotSupported` or `ControlNotSupported`.

**`0x42` polling skip** — skipped on units with `cap_run_state=false`, eliminating recurring timeouts.

**`miel_hvac_append_settings_json()`** — shared helper replacing ~80 lines of duplicated JSON code between SENSOR and HVACSETTINGS topics.

---

### JSON Changes

- `Power` (W) and `Energy` (kWh) published inside `MiElHVAC` and also in a separate `ENERGY{}` object outside `MiElHVAC` for Home Assistant auto-discovery
- `Purifier`, `NightMode`, `EconoCool` shown in SENSOR and HVACSETTINGS when `cap_run_state=true`; otherwise omitted
- `AirDirection` always shows current state from `0x62 0x02` regardless of control support
- `*Supported` capability fields published flat inside `MiElHVAC`: `HeatSupported`, `DrySupported`, `FanSupported`, `VaneVSupported`, `SwingSupported`, `AutoFanSupported`, `OutdoorTempSupported`, `AirDirectionSupported`, `PurifierSupported`, `NightModeSupported`, `EconoCoolSupported`

---

### Tested on
MSZ-LN25VG2W — `cap_run_state=false`, temp ranges 16–31 °C cool/auto, 10–31 °C heat, 5 fan speeds.
### AirDirection — respect i-See sensor presence

`AirDirection` now requires three conditions instead of just the vertical vane capability:
- `cap_vane_v` — unit has a vertical vane
- `sc_has_isee` — i-See sensor observed at runtime (widevane ever seen with bit `0x80`, or value `0x28`/`0xaa`)
- `cap_run_state` — unit supports `0x08` for control

Resulting behaviour:

| `cap_vane_v` | `sc_has_isee` | `cap_run_state` | `AirDirection` visible | `AirDirectionSupported` |
|:-:|:-:|:-:|:-:|:-:|
| ❌ | — | — | hidden | `not_supported` |
| ✅ | ❌ | — | hidden | `not_supported` |
| ✅ | ✅ | ❌ | shown | `control_not_supported` |
| ✅ | ✅ | ✅ | shown | `on` |

Units with vertical + horizontal vanes but no i-See sensor now correctly report `AirDirectionSupported:"not_supported"` and omit `AirDirection` from both `MiElHVAC` and `HVACSettings` JSON.

### Capability field renames

For naming consistency across the `*Supported` fields:
- `cap_heat` → `cap_mode_heat`, `HeatSupported` → `ModeHeatSupported`
- `cap_dry` → `cap_mode_dry`, `DrySupported` → `ModeDrySupported`
- `cap_fan_mode` → `cap_mode_fan`, `FanSupported` → `ModeFanSupported`
- `cap_auto_fan` → `cap_fan_auto`, `AutoFanSupported` → `FanAutoSupported`
- `OutdoorTempSupported` → `OutdoorTemperatureSupported`
- `TempCool` / `TempHeat` / `TempAuto` → `SetTemperatureCoolMinMax` / `SetTemperatureHeatMinMax` / `SetTemperatureAutoMinMax`

### Energy values

- `Power` (W) and `Energy` (kWh) published both inside `MiElHVAC` and in a standard Tasmota `ENERGY{}` sub-object (`Power`/`Total`) for Home Assistant auto-discovery.
- Added Web UI rows via `FUNC_WEB_SENSOR` showing instantaneous power (W) and cumulative total (kWh) on the Tasmota main page.

### Runtime i-See detection

New `sc_has_isee` flag in `miel_hvac_softc`, set in `miel_hvac_input_settings` on the first widevane value indicating i-See state. Once set, stays set for the session.

**Practical note:** after boot, the flag starts `false`. Units with i-See that has never been activated since Tasmota started will show `AirDirection` as hidden until i-See is first used (via IR remote or `HVACSetAirDirection`). Safe default — prevents showing misleading values on units without i-See.
@arendst arendst merged commit a9b1715 into arendst:development Apr 21, 2026
64 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants