Home Assistant integration for Daikin air conditioners fitted with a Faikin/Faikout module (RevK firmware), over MQTT.
The module publishes its state and accepts commands on MQTT. This integration subscribes to those topics and exposes the unit as a proper climate device, with the sensors and toggles the firmware reports.
Faikin/Faikout module ──MQTT──> broker ──> Home Assistant ──> this integration
The firmware has built-in Home Assistant support and for most setups that is the better choice — nothing to install, and it is maintained alongside the firmware itself. Try that first.
- In the module's web interface, enable its Home Assistant / MQTT auto-discovery setting, and point the module at your broker.
- In Home Assistant, have the MQTT integration configured against that same broker, with discovery enabled (it is on by default).
- The unit appears by itself under Settings → Devices & Services → MQTT.
The module then publishes retained discovery configs under the homeassistant/ topic prefix. To check
whether it is actually doing so:
mosquitto_sub -h your-broker -t 'homeassistant/#' -vIf entries scroll past, discovery is working and you are done — you do not need this integration.
Measured against a Faikin S21 unit; your model may report fewer fields.
| Built-in discovery | This integration | |
|---|---|---|
| Climate entity | yes | yes |
| Temperatures | outside, coil, plus the AC's own values | + inlet |
| Energy | 3 counters | 3 counters, converted to kWh |
| Switches | 9 | 9 |
| Faikout-Auto toggle | yes | no |
| Restart button | yes | no |
| Diagnostics (uptime, memory, WiFi, IP, build, …) | no | 14 entities |
| Broker separate from Home Assistant's | no | yes |
| Update-rate throttle | no | yes |
So the built-in route is not a subset — it exposes a Faikout-Auto switch and a restart button that this integration does not have. Pick whichever matches what you need.
- A separate broker. Home Assistant's MQTT integration connects to exactly one broker. If your Faikout publishes to a different one, discovery cannot reach it; this integration can open its own connection.
- Diagnostics as typed entities with proper device classes and units.
- Control over the update rate, which matters if the recorder database is growing faster than you like.
Do not run both. Two sets of entities for one unit, with two entity IDs for every value, is a mess to undo later. Turn the firmware's discovery off before adding this integration — and if you already had it on, delete the MQTT device afterwards, since retained discovery configs otherwise bring it back.
- Home Assistant 2026.8 or newer. This is the first release providing the unambiguous device registry lookup the integration uses; older releases only offer the one Home Assistant has since deprecated. A CI job pinned to exactly that version keeps the claim honest.
- Either Home Assistant's MQTT integration pointed at the broker your Faikout publishes to, or the broker's connection details so this integration can connect on its own.
- HACS → ⋮ → Custom repositories → add this repository as an Integration.
- Install Faikout and restart Home Assistant.
- Settings → Devices & Services → Add Integration → Faikout.
Copy custom_components/faikout into your Home Assistant config/custom_components/ directory and
restart.
The config flow first asks how Home Assistant should reach the module:
| Choice | Use when |
|---|---|
| Home Assistant's MQTT integration | your Faikout publishes to the broker HA is already connected to |
| An own MQTT broker | the Faikout lives on a different broker than HA's MQTT client |
Either way the integration then listens briefly on state/+ and offers the modules it found. You can also
type the hostname by hand — it is the middle part of the topics, the GuestAC in state/GuestAC.
The own-broker mode can encrypt the connection. Two switches, because they are not the same decision:
- Use TLS — encrypts the connection. The port moves to 8883 unless you set a different one. The one
exception is 8883's counterpart: a deliberately entered
1883cannot be told apart from the untouched default, so TLS on port 1883 specifically is not configurable. - Do not verify the certificate — accepts any certificate the broker presents.
Brokers commonly ship with a self-signed demo certificate (EMQX's, for instance, is issued to
CN=localhost by an untrusted root) which no client will accept on its own. The second switch exists for
that case, but be clear about what it costs: the traffic is still encrypted, yet an attacker on your
network who impersonates the broker cannot be detected — and they would receive your credentials. It
protects against someone passively listening, not against someone actively interfering.
For a connection you can actually trust, replace the broker's certificate with one from your own CA (or a publicly trusted one if the broker has a DNS name), issued to the name you connect to, and leave verification on.
Without TLS this mode is LAN only. Plain MQTT sends the broker credentials and all control traffic in the clear. Never use it across the internet unencrypted.
Reachable later via Configure on the integration entry:
- Update interval — how often incoming changes are pushed to the entities. Defaults to 10 seconds.
The module reports on every change, which for a running unit is more often than most people need and
writes a recorder row each time. The newest value is never lost, only delayed to the end of the window.
Set
0to pass every message straight through. Availability changes always bypass this. - Own MQTT client — switch an existing entry between the two transports, with the broker details and the TLS switches described above.
| Platform | What |
|---|---|
| Climate | power, mode (heat/cool/heat_cool/dry/fan only), target temperature, fan speed, swing |
| Number | demand — the output limit in percent, 30 to 100 in steps of 5 |
| Sensors | room / outside / inlet / coil temperature, humidity, power, energy (total, heating, cooling), compressor frequency, fan speed |
| Diagnostics | uptime, MQTT uptime, free memory, free SPI RAM, flash size, WiFi SSID/BSSID/channel/signal, IP address, reset reason, firmware build, protocol, last report |
| Switches | powerful, economy, streamer, quiet (outdoor), comfort, sensor mode, LED, vertical/horizontal swing |
The climate controls follow the unit rather than one hardware variant. Fan steps and the setpoint resolution come from the protocol it reports — S21 has five steps and 0.5 °C, CN_WIRED three steps and 1 °C, X50A and Altherma_S 0.1 °C. Vertical and horizontal swing are separate controls, each offered only when the unit actually reports that axis.
The current activity (heating, cooling, idle) is derived, since no Faikin protocol reports it directly.
Only S21 sends a compressor frequency, which is what tells idle apart from working; on CN_WIRED and
X50A the activity follows the selected mode, so a unit resting at its setpoint still reads as heating
or cooling. In heat_cool the direction cannot be determined at all and the activity stays unknown.
Entities are only created for the fields your module actually reports, and appear automatically when a field turns up for the first time. Some diagnostics are disabled by default — enable them in the entity settings if you want them.
- The LED switch is disabled by default. On S21 units a LED-only command does not trigger a frame to the indoor unit, so the new value only takes effect alongside the next real change. That makes it unreliable as a standalone switch.
- TLS has no way to pin a specific certificate. It either verifies against the usual trust stores or not at all; there is no field for a custom CA file.
- A wrong hostname is not rejected. The hostname is only checked for characters that would break an
MQTT topic, not against the broker — a module that is merely switched off at the time would otherwise be
impossible to add. So a typo produces a device that stays Unavailable forever, with only a warning in
the log. If a freshly added device never becomes available, check the hostname first: it is the middle
part of the topics, and
mosquitto_sub -h your-broker -t 'state/+' -vshows the ones that exist. - The device's auto mode is
heat_cool, notauto. Home Assistant reservesautofor a schedule or learned behaviour that also takes the temperature control away from the user, which is not what this mode does. The firmware's own discovery publishesheat_coolas well. - Some limits cannot be read from the device. The temperature range and whether the device's own
auto mode exists are firmware settings (
t.min,t.max,no.auto), but the module does not publish them over MQTT, so the integration offers 16–32 °C andheat_coolregardless. The same applies to the fan step count, which thefantypesetting can change independently of the protocol; the level the unit currently reports is always selectable even when it falls outside the protocol's usual set. - Faikout-Auto is not exposed (target range, external reference, schedules). Use the module's own web interface for that.
- Two modules with the same hostname on different brokers are told apart by their MAC address, which is read during discovery. A hostname typed by hand has no MAC to read, so in that case the hostname alone identifies the device.
The device↔Home Assistant logic lives in const.py and imports no Home Assistant code, so it is unit
tested standalone. On top of that, the config flow, coordinator and entities are tested against a real
Home Assistant core with a fake MQTT transport — no broker required.
python -m venv .venv
pip install -r requirements-test.txt
pip install pytest-homeassistant-custom-component paho-mqtt # for the full suite
pytest -qThe Home Assistant tests are Linux/macOS only — HA's test machinery imports fcntl. They skip themselves
elsewhere, so the pure suite still runs on Windows; use WSL2 there to run everything.
CI runs the suite against both the current and the minimum supported Home Assistant, plus hassfest.
The ESP32-Faikin firmware and hardware are by RevK. This integration is an independent Home Assistant client for it and is not affiliated with that project or with Daikin.
MIT — see LICENSE.