92b377f66d MiELHVAC: add Home Assistant MQTT discovery (#25027)
* MIELHVAC New features and bug fixes

## 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.

* Extend AirDirection capability, added web ui energy sensor, cleanup

### 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.

* MiElHVAC Full support of AirDirection control

* MiELHVAC fix globals, VLA, duplicate JSON fields and float formatting

## Summary

- **Remove file-scope globals** (`temp_type`, `remotetemp_active`,
  `remotetemp_auto_clear_time`, `remotetemp_last_call_time`,
  `remotetemp_half`): moved into `miel_hvac_softc` as `sc_temp_type`
  and `sc_remotetemp_*`. All references updated. Eliminates potential
  conflict with other drivers sharing the same translation unit.

- **Fix VLA in `miel_hvac_send`**: `char hex_d[(len + 1) * 2]` replaced
  with fixed-size `(MIEL_HVAC_DATABUFLEN + 1) * 2`. Variable-length
  arrays on the stack are disallowed by `-Wvla` and unreliable on
  embedded targets.

- **Make `temp_type` explicit**: helper functions `miel_hvac_deg2temp`,
  `miel_hvac_temp2deg`, `miel_hvac_roomtemp2deg` now take `bool
  temp_type` as a parameter. Detection of the extended encoding moved
  from render functions to `miel_hvac_input_data()`, removing a hidden
  side effect inside JSON serialisation code.

- **Remove duplicate JSON fields**: `Purifier`, `NightMode`, `EconoCool`
  were emitted twice (from both the settings block and the options
  block). Options block now only emits `OptionsHex`.

- **Fix `RemoteTemperatureSensorAutoClearTime` JSON type**: was
  serialised as a string (`"10000"`), now a proper JSON number (`10000`).

- **Bool consistency**: assignments `= 1` / `= 0` on `bool` fields
  replaced with `= true` / `= false`.

* MiElHVAC auto-enable i-See widevane when setting AirDirection

### Problem
`HVACSetAirDirection` (`indirect` / `direct` / `even`) sets the i-See airflow
direction via a `0x41 0x08` runstate packet (flag `0x2000`). The unit only
honors that value once i-See airflow control is enabled, which requires
`widevane=0x80` sent in a `0x01` settings packet.

Until now the user had to manually run `HVACSetWideVane isee` **before**
`HVACSetAirDirection`, otherwise the direction change was silently ignored.

### Change
`HVACSetAirDirection` now sets the widevane to
`MIEL_HVAC_SETTINGS_WIDEVANE_ISEE` (`0x80`) in the same call.

The dispatcher always sends the settings (`0x01`) packet before the runstate
(`0x41`) packet, so the unit receives the i-See enable first and the direction
value on the following tick — no manual ordering required.

### Notes
- `off` is unchanged (still expressed as `widevane=0x8c` via `0x01`).
- The existing capability guard (`cap_vane_v` + `sc_has_isee`) is unchanged.

* Fix GPIO name table offset from duplicate MODBUSRELAY entry

kSensorNames had the four D_MODBUSRELAY_* tokens twice while the
UserSelectablePins enum lists GPIO_MODBUSRELAY_* once, shifting every
following name by four - the GPIO dropdown showed MiEl HVAC MB Tx/Rx/DE
and CC1101 CS as 'MbsRelay ...'. Drop the duplicate row.

* MiEL HVAC accept fan_only as alias for fan mode

Home Assistant's climate integration uses 'fan_only'; map it to the same
value as 'fan' so HVACSetMode/HVACSetHAMode accept it. Reporting is
unchanged (miel_hvac_map_byval still returns 'fan').

* MiEL HVAC Modbus: mirror sensor values on FC03 holding registers

Add holding registers 0x0010..0x0017 as read-only mirrors of room
temperature, compressor, instantaneous power, stage operation/fan/mode
and the requests/CRC-error diagnostic counters, so a master that only
speaks FC03 can read them. Writes to these addresses still return
exception 0x02.

* MiEL HVAC Modbus: start FC03 mirror block at 0x000f, no gap after control block

* MiEL HVAC Modbus: queue writes when HVAC link is not up yet

Return to the master with a normal response and queue the update
(same as the HVACSet* console commands) instead of Modbus exception
0x04, so a PLC can pre-load settings and bench testing works without
the AC connected.

* MiEL HVAC Modbus: frame incoming requests by length, not the T3.5 gap

A FUNC_LOOP poll cannot measure the 3.5-char inter-frame gap reliably
above 9600 baud, so a frame split across two polls was processed as two
truncated frames (CRC error count exceeded the request count on a busy
19200 8E1 bus). Compute the expected request length from the function
code and dispatch as soon as it is buffered; keep the idle gap only to
flush a stuck partial frame or retry an unknown function code. Also skip
requests addressed to other slaves without a CRC check.

* MiEL HVAC Modbus: byte-level resync, larger RX buffer, no flush on auto-direction

CrcErrors was still ~1:1 with Requests on a busy 19200 8E1 multi-drop bus.
- resync one byte at a time on a framing/CRC mismatch instead of dropping
  the whole assumed frame and waiting for bus idle
- only count a CRC error when the frame claims our own address
- 1 kB RX buffer so a late FUNC_LOOP poll does not lose bytes to a UART
  FIFO overflow (TasmotaSerial cannot report the overflow on ESP32)
- bulk serial read instead of byte-at-a-time
- skip flush() when no DE pin is configured - on ESP32 flush() also
  discards the RX buffer, dropping the next request on a shared bus

* MiEL HVAC Modbus: add link status to the FC03 sensor mirror

Holding register 0x0017 (PLC 40024) mirrors input 0x0001 - connected to
the HVAC unit (0/1).

* MiEL HVAC Modbus: wait the RTU turnaround silence before answering

Intermittent corrupted responses (master saw e.g. 80 C8 ...) on an
auto-direction transceiver at 19200: the slave started transmitting
before the master's line had turned around. Hold quiet for up to 3.5
char times after the last received byte before sending the response.
Track the last-byte time per read so the wait is accurate.

* MiEL HVAC Modbus: do not send a late reply once the master has re-polled

When a FUNC_LOOP stall makes the response miss the master's timeout
(Siemens S7 MB_MASTER STATUS 0x80C8), a newer request is already
buffered behind the stale one. Apply the stale request but skip its
response so it cannot land on the master's next transaction and make
that one time out too.

* MiEL HVAC Modbus: strip the i-See bit from the swingH register

Input 0x0015 / holding 0x0005 (40006) returned the raw wide-vane byte,
so a unit with an i-See sensor reported e.g. 131 (0x83 = 0x80 | center).
Report the position only (1..8, 12), or 0x80 when the byte encodes
i-See direction mode - matching the SwingH field in the SENSOR JSON.

* MiEL HVAC: document the driver and Modbus slave in the file header

Move the Modbus RTU slave detail out of the changelog into a doc block
at the head of xdrv_44_miel_hvac.ino, per the PR #24993 review.

* MiELHVAC: add Home Assistant MQTT discovery

Publishes a single retained "climate" entity covering mode, current/target
temperature, fan speed, action, vertical swing, horizontal swing/widevane
and air direction (as a preset), the same layout as a manually written
climate: YAML config, so the device appears in Home Assistant without any
manual configuration. Republishes on every MQTT (re)connect and honors
SetOption19 like the rest of Tasmota's HA discovery.

Fan speed, both swing controls and air direction use Jinja dict templates
to show capitalized display labels (e.g. "Up Middle") while still sending
the driver's own lower_snake_case values over MQTT. The web control panel's
own labels are updated to match, it previously used "Up-Middle" style
hyphens for these, inconsistent with the discovery config.

Widevane's "I-See" position is a read-back of air direction control being
active, not a directly settable vane position, so it's only listed once
the unit is known to support it, and selecting it now re-engages air
direction at the last active direction instead of sending a widevane byte
the unit won't act on. The same option and behavior are now available in
the web control panel, which previously hid "I-See" unconditionally.

Also adds a computed "HAAction" SENSOR field (heating/cooling/drying/fan/
idle/defrosting/preheating/off), using the Stage packet's OperationStage
(standby/defrost/preheat) as well as HAMode, so the discovery config
doesn't need to derive it with a template and HA gets the more specific
action whenever the unit reports one.

The combined discovery payload does not fit under Tasmota's default
MQTT_MAX_PACKET_SIZE (1200 bytes), so my_user_config.h raises it to 4096.

* MiELHVAC: expose HA discovery capabilities dynamically

Build fan_modes from cap_fan_auto and the C9-reported fan count instead
of a fixed list, drop Quiet from MQTT since some CN105 units report an
IR-selected Quiet back as fan speed 1, and gate the AirDirection preset
on isee_capable so it is only advertised on units that actually support
it. Republish discovery once C9 capabilities and i-See are known, not
just on MQTT connect, since TasRediscover only re-runs Tasmota's native
discovery and never this driver's custom HA payload.

Based on a suggestion from mamrai1 in grzegorz914/Tasmota#2.

* MiELHVAC: also hide Quiet in the web panel fan speed selector

The web control panel's Fan speed dropdown still offered Quiet whenever
the unit reported 5 fan speeds. Since some CN105 units report an
IR-selected Quiet back as fan speed 1, hide it unconditionally there
too, matching the HA discovery fan_modes list.

* MiELHVAC: make web panel and MQTT discovery use the same capability gates

The web panel's AirDirection control, its widevane I-See option, the
readout row and the SENSOR JSON AirDirection field all defaulted to
shown until capabilities proved otherwise, while HA discovery's
preset_modes/isee_capable gate defaulted to hidden until proven
supported. Standardize all of them on the stricter confirmed-capable
gate so MQTT and the web panel never disagree about whether AirDirection
is available.

Also cap the web panel's Fan speed 2 and 3 options to the C9-reported
fan count, matching the numbered-speed cap already applied to the HA
discovery fan_modes list (only speed 4 was capped there before).

* MiELHVAC: order horizontal vane positions left-to-right

swing_horizontal_modes (HA discovery) and the web panel's Vane
horizontal select listed positions in raw protocol byte order
(left, left_middle, center, right_middle, right, left_center,
right_center), which reads oddly in a dropdown. Reorder both, and
the backing miel_hvac_widevane_map, to the physical left-to-right
order: left, left_middle, left_center, center, right_center,
right_middle, right, then split/swing/isee.

* MiELHVAC: restore capability-gated Quiet instead of removing it outright

Unconditionally dropping Quiet from fan_modes assumed CN105 units
universally can't distinguish a Quiet selection from fan speed 1 on
readback. Testing on a real unit that reports 5 fan speeds (Auto,
Quiet, 1-4) showed Quiet works correctly and reports back reliably,
so removing it lost a real, working mode.

Gate Quiet on fan_count == 5 instead, the same threshold SetFanSpeed
already enforces when rejecting the command -- both HA discovery's
fan_modes/fan_mode_state_template/fan_mode_command_template and the
web panel's Fan speed selector now only expose Quiet once the C9
capabilities response confirms the unit actually has it.

* MiELHVAC: add Home Assistant MQTT discovery for Prohibit

Publish the Prohibit / remote-control lock as a separate select entity
(homeassistant/select/<id>_prohibit/config), mirroring the web panel's
Prohibit dropdown -- climate entities have no native lockout concept.
Clear its retained config alongside the climate entity's when SetOption19
disables discovery.

Based on a suggestion from mamrai1 in grzegorz914/Tasmota#2.

* MiELHVAC: document why Prohibit's entity_category hides it from Area cards

Note in the code that entity_category "config" is a deliberate choice,
not an oversight -- HA excludes config/diagnostic entities from the
Area dashboard's auto-generated card even once an Area is assigned,
by design. The entity stays reachable from the device page and
Settings > Areas.

* MiELHVAC: document confirmed dual-vane widevane behavior, no renames

Tested against a real MSZ-LN unit: left/center/right/split/swing move
both horizontal vanes together, while the *_middle/*_center values
move only one vane independently. Considered relabeling raw 4/5 and
6/7 based on mUART's protocol docs (which describe a single continuous
left-right axis plus generic "Split" combinations), but that scheme
does not match this unit's actual behavior, and there is no capability
bit indicating vane count or per-side behavior to detect which scheme
applies on a given unit. Document the confirmed behavior as
model-specific instead of renaming, to avoid baking in an assumption
that breaks a different model.

* MiELHVAC: swap right/right_middle labels to match actual vane extremes

Confirmed by testing: WIDEVANE_RR (0x05) drives the right vane to its
furthest-right extreme (single vane only), while WIDEVANE_R (0x04)
moves both vanes together to a lesser right-ward position. The
previous naming had this backwards -- "right" pointed at the lesser,
synchronized position and "right_middle" at the extreme one.

Swap the two labels in miel_hvac_widevane_map so "right" means the
same thing intuitively on both sides: the furthest position, matching
how "left" already refers to the full-left extreme. HA discovery and
the web panel need no changes -- they key off these string names, not
the raw byte values, so they pick up the corrected mapping
automatically.

* MiELHVAC: fix web panel never showing I-See as the current Vane horizontal

The web panel's "Vane horizontal" selector passed set->widevane masked
with MIEL_HVAC_SETTINGS_WIDEVANE_MASK (0x0f) as the current value, but
i-See is signaled by the high bit (0x80) or one of two odd raw values
(0x28/0xaa) seen in the wild -- none of which survive that mask. The
dropdown could therefore never show I-See as selected, even right
after engaging AirDirection (which sets widevane to exactly 0x80).

Compute the same wv_isee check already used correctly elsewhere in
this function (readout rows, Air Direction control) before masking,
and share it between the Vane horizontal selector and the Air
Direction block below it.

* MiELHVAC: fix live-sync never updating Vane horizontal when I-See engages

Same class of bug as the earlier "Vane horizontal never shows I-See as
selected" fix, in a different spot: the JS live-sync path in
miel_hvac_web_readout() (which pushes S('hvh', ...) updates into the
already-rendered web panel without a full reload, skipping controls
the user has focused) computed wn as NULL whenever i-See was active,
so the S('hvh', ...) call was skipped entirely and the selector was
left showing its last non-i-See value instead of updating live.

* MiELHVAC: gate MQTT_MAX_PACKET_SIZE bump on USE_MIEL_HVAC

Raising MQTT_MAX_PACKET_SIZE to 4096 in my_user_config.h applied to
every build regardless of whether MiELHVAC was even enabled, costing
every other user extra RAM for a buffer only this driver's Home
Assistant discovery payload needs. Wrap it in #ifdef USE_MIEL_HVAC,
placed after the user_config_override.h include so the driver's own
enable flag is already visible, keeping the 1200 byte default for
everyone else.

Addresses maintainer review feedback from arendst on PR #25027.

* Update xdrv_44_miel_hvac.ino

* MiELHVAC: document confirmed vaneH split/sync behavior precisely

Update the widevane_map comment with the fully confirmed picture from
testing: left/left_middle/center/right_middle/right/split/swing move
both vanes together to that position, while left_center and
right_center are asymmetric splits (left_center puts the left vane at
the left_middle angle and the right vane at center, right_center
mirrors that). Earlier revisions of this comment described
left_middle/left_center as left-vane-only, which testing has now
superseded.

Also notes a second real unit (from a PR reviewer) showed yet another
variant, reinforcing that this is model-specific.

* MiELHVAC: no semicolons in prose comments

Replace two semicolons in the widevane_map doc comment, one with a
comma (continuing a single flowing clause), one with a period (a true
independent-clause boundary).

* MiELHVAC: fix cap_run_state gating, confirm Purifier/NightMode/EconoCool per option

cap_run_state (0xC9 byte 9 bit 0x10) turned out to be undocumented and
unreliable per mUART's own docs ("???", observed both true and false),
and this file's own struct comment even pointed at the wrong byte (6
instead of 9) for it. It was wrongly used to block the HVACSetPurify/
HVACSetNightMode/HVACSetEconoCool commands, the matching web panel
controls, and 0x42 polling itself outright, hiding these features even
on units that do support them.

Removed all cap_run_state-based gating. Purifier/NightMode/EconoCool
are now only reported once independently proven via a round trip: a Set
Run State request that actually asks for a different value than last
confirmed is armed, and the option is marked confirmed only if the next
genuine 0x42 response reads back exactly that requested value (not all
units that answer 0x42 support all three, so a single shared confirmed
flag was too coarse). No optimistic apply — these fields reflect the
unit's own confirmed state only, never what was just requested, since
on units where 0x42 never responds an optimistic guess would never get
corrected. The web panel only shows a button once its option is
confirmed; *Supported (capabilities) is the single source of truth for
support status, so the Settings block doesn't repeat "not_supported".

Also adds a debug-only HVACProbeRunState command (MIEL_HVAC_DEBUG-gated)
for sending an arbitrary flags/byte/value combination on the 0x08 Set
Run State surface, to correlate a raw packet with a physically observed
effect on real hardware rather than a 0x42 read-back that may never
arrive.

Verified against a real MSZ-LN unit whose 0xC9 fingerprint (byte 6/9 =
0x07/0x25) independently matches the "non-supporting" signature reported
in https://github.com/echavet/MitsubishiCN105ESPHome/discussions/366 —
0x42 never responds, Set Run State commands are ACKed but produce no
observable effect (including a buzzer test that works on other units),
and toggling these options via the physical remote does not leak into
any other polled response type either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Update xdrv_44_miel_hvac.ino

Added a sensor for horizontal wide-vane support.

Horizontal wide-vane support is assumed to be available by default. If a requested horizontal vane position change is rejected by the unit, support is marked as unavailable and the horizontal wide-vane controls are hidden.

* MiELHVAC: add Home Assistant MQTT discovery for Purifier/NightMode/EconoCool

Publishes each as a separate switch entity, climate has no slot for
arbitrary on/off toggles. Each is only published once its own
round-trip-confirmed flag is set (sc_purifier_confirmed et al), matching
the SENSOR JSON and the web panel, both of which already gate on these
per-feature flags instead of the unreliable cap_run_state bit. Cleared
along with the climate entity and Prohibit select when SetOption19
disables discovery.

* MiELHVAC: document that SwingV only reports the right vertical vane

On dual-vertical-vane units (confirmed on MSZ-LN, remote has separate
Left/Right vertical vane buttons) the vane byte tracks only the right
vane. Confirmed by testing: setting left=up/right=down then
left=down/right=up gave the same final vane byte both times (matches
the right vane, not a combined state), changing only the right vane
moved the byte, changing only the left vane three times in a row left
every byte of the Settings packet unchanged. No other field in the
packet exposes the left vane either, this is the same class of gap as
Purifier/NightMode/EconoCool being settable from the remote but
unreported over CN105.

Documentation only, no behavior change.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: mamrai1 <57288344+mamrai1@users.noreply.github.com>
2026-09-21 18:11:39 +02:00
2022-12-21 17:22:54 +01:00
2026-02-13 11:24:01 +01:00
2026-02-13 11:24:01 +01:00
2023-10-26 18:04:34 +02:00
2024-01-01 18:22:01 +01:00
2023-10-26 18:04:34 +02:00
2026-08-24 11:42:43 +02:00
2023-10-26 18:04:34 +02:00
2019-11-13 11:46:56 +01:00
2026-08-25 11:38:08 +02:00
2026-03-31 14:25:09 +02:00
2017-05-13 13:02:10 +02:00
2025-02-17 10:04:07 +01:00
2026-08-25 11:38:08 +02:00
2023-12-14 15:29:19 +01:00
2023-01-24 10:48:38 +01:00
2026-08-17 11:01:49 +02:00

Tasmota logoTasmota logo

Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Written for PlatformIO.

GitHub version GitHub download License Discord


In light of current events we like to support the people behind PlatformIO Project, especially Ivan Kravets, and wish them the strength to help stop the war. See platformio-is-ukrainian-project-please-help-us-stop-the-war for what you can do.


Easy install

Easy initial installation of Tasmota can be performed using the Tasmota WebInstaller.

If you like Tasmota, give it a star, or fork it and contribute!

GitHub stars GitHub forks donate

See RELEASENOTES.md for release information.

Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/ or http://ota.tasmota.com/tasmota32/release/ for ESP32 binaries.

Development

Dev Version Download Dev Tasmota CI Build_development

See CHANGELOG.md for detailed change information.

Unless your Tasmota powered device exhibits a problem or lacks a feature that you need, leave your device alone - it works so don’t make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved.

Every commit made to the development branch, which is compiling successfully, will post new binary files at http://ota.tasmota.com/tasmota/ (this web address can be used for OTA updates too). It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted.

Note that there is a chance, as with any upgrade, that the device may not function as expected. You must always account for the possibility that you may need to flash the device via the serial programming interface if the OTA upgrade fails. Even with the master release, you should always attempt to test the device or a similar prototype before upgrading a device which is in production or is hard to reach. And, as always, make a backup of the device configuration before beginning any firmware update.

Disclaimer

⚠️ DANGER OF ELECTROCUTION ⚠️

If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (Beware: certain countries prohibit installation without a licensed electrician present). Remember: SAFETY FIRST. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power).

We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site.

Note

Please do not ask to add new devices unless it requires additional code for new features. If the device is not listed as a module, try using Templates first. If it is not listed in the Tasmota Device Templates Repository create your own Template.

Quick Install

Download one of the released binaries from http://ota.tasmota.com/tasmota/release/ or http://ota.tasmota.com/tasmota32/release/ and flash it to your hardware using our installation guide.

Important User Compilation Information

If you want to compile Tasmota yourself keep in mind the following:

  • For ESP8285 based devices only Flash Mode DOUT is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device.
  • For ESP8285 based devices Tasmota uses a 1M linker script WITHOUT spiffs 1M (no SPIFFS) for optimal code space.
  • To make compile time changes to Tasmota use the user_config_override.h file. It assures keeping your custom settings when you download and compile a new version. You have to make a copy from the provided user_config_override_sample.h file and add your setting overrides.

Configuration Information

Please refer to the installation and configuration articles in our documentation.

Migration Information

See migration path for instructions how to migrate to a major version.

Do not upgrade from minimal to minimal version. It will most likely fail at some point and will require flashing via serial. If you do have to use minimal versions, always OTA to a full version of the same release before applying next minimal version.

Pay attention to the following version breaks due to dynamic settings updates:

  1. Migrate to Sonoff-Tasmota 3.9.x
  2. Migrate to Sonoff-Tasmota 4.x
  3. Migrate to Sonoff-Tasmota 5.14
  4. Migrate to Sonoff-Tasmota 6.7.1 (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions
  5. Migrate to Tasmota 7.2.0 (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin)

--- Major change in parameter storage layout ---

  1. Migrate to Tasmota 8.5.1 (http://ota.tasmota.com/tasmota/release-8.5.1/tasmota.bin)

--- Major change in internal GPIO function representation ---

  1. Migrate to Tasmota 9.1 (http://ota.tasmota.com/tasmota/release-9.1.0/tasmota.bin.gz)
  2. Upgrade to latest release (http://ota.tasmota.com/tasmota/release/tasmota.bin.gz)

While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release v9.1.0 Imogen the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing v9.1.0.

Support Information

For a database of supported devices see Tasmota Device Templates Repository

If you're looking for support on Tasmota there are some options available:

Documentation

Support's Community

  • Tasmota Discussions: For Tasmota usage questions, Feature Requests and Projects.
  • Tasmota Users Chat: For support, troubleshooting and general questions. You have better chances to get fast answers from members of the Tasmota Community.
  • Search in Issues: You might find an answer to your question by searching current or closed issues.
  • Software Problem Report: For reporting problems of Tasmota Software.

Unofficial Community Resources

  • Tasmota-DE: A German-language Telegram group related to Tasmota.

Contribute

You can contribute to Tasmota by

  • Providing Pull Requests (Features, Proof of Concepts, Language files or Fixes)
  • Testing new released features and report issues
  • Donating to acquire hardware for testing and implementing or out of gratitude
  • Contributing missing documentation for features and devices

donate

Credits

People helping to keep the show on the road:

  • Sfromis providing extensive user support
  • Barbudor providing user support and code fixes and additions
  • David Lang providing initial issue resolution and code optimizations
  • Heiko Krupp for his IRSend, HTU21, SI70xx and Wemo/Hue emulation drivers
  • Wiktor Schmidt for Travis CI implementation
  • Thom Dietrich for PlatformIO optimizations
  • Marinus van den Broek for his EspEasy groundwork
  • Pete Ba for more user friendly energy monitor calibration
  • Lobradov providing compile optimization tips
  • Flexiti for his initial timer implementation
  • reloxx13 for his TasmoAdmin management tool
  • Joachim Banzhaf for his TSL2561 library and driver
  • Andre Thomas for providing many drivers
  • Gijs Noorlander for his MHZ19, SenseAir and updated PubSubClient drivers
  • Erik Montnemery for his HomeAssistant Discovery concept and many code tuning tips
  • Federico Leoni for continued HomeAssistant Discovery support
  • Aidan Mountford for his HSB support
  • Daniel Ztolnai for his Serial Bridge implementation
  • Gerhard Mutz for multiple sensor & display drivers, Sunrise/Sunset, and scripting
  • Nuno Ferreira for his HC-SR04 driver
  • Adrian Scillato for his (security)fixes and implementing and maintaining KNX
  • Gennaro Tortone for implementing and maintaining Eastron drivers
  • Raymond Mouthaan for managing Wemos Wiki information
  • Norbert Richter for his decode-config.py tool
  • Joel Stein, digiblur and Shantur Rathore for their Tuya research and driver
  • Frogmore42 for providing many issue answers
  • Jason2866 for platformio support and providing many issue answers
  • Blakadder for managing the document site and providing template management
  • Stephan Hadinger for refactoring light driver, enhancing HueEmulation, LVGL, Zigbee and Berry support
  • tmo for designing the official Tasmota logo
  • Stefan Bode for his Shutter and Deep sleep drivers
  • Jacek Ziółkowski for his TDM management tool and Tasmotizer flashing tool
  • Christian Staars for NRF24L01 and HM-10 Bluetooth sensor support
  • Paul Diem for UDP Group communication support
  • Jörg Schüler-Maroldt for his initial ESP32 port
  • Javier Arigita for his thermostat driver
  • Simon Hailes for ESP32 Bluetooth extensions
  • Many more providing Tips, Wips, Pocs, PRs and Donations

License

This program is licensed under GPL-3.0-only

S
Description
Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at
https://tasmota.github.io/docs Readme GPL-3.0
1.1 GiB
0 Stars 1 Watchers 0 Forks
Languages
C 57%
C++ 34.9%
Berry 4.7%
Python 2.7%
Jupyter Notebook 0.2%
Other 0.4%