A custom integration for Home Assistant to locally control Daikin air conditioners via their local API. This solution focuses on speed, reliability, and privacy by avoiding any cloud dependency.
- Full Climate Control: Mode (Heat, Cool, Dry, Auto, Fan Only), target temperature, fan speed, and swing modes.
- Zone Management: Full support for ducted systems with individual zone control (On/Off and temperature if supported).
- Energy Management:
- Segmented tracking: Heat / cool / total energy sensors per unit with
state_class=total_increasingwhere applicable (Home Assistant does not allowlast_resetontotal_increasing; daily resets are reflected as counter drops in the state). - Optional auto history sync (off by default): reuses Daikin hourly data to correct recent long-term statistics once per local hour, integrated into the normal polling loop.
- Manual correction: Services
daikin_local.sync_historyanddaikin_local.sync_total_historyto backfill or fix delayed Daikin data on demand.
- Segmented tracking: Heat / cool / total energy sensors per unit with
- Diagnostics:
- Per-device daily error counters for pydaikin communication (disabled by default in the entity registry):
pydaikin_daily_poll_errors, plus BRP069 per-domain counterspydaikin_daily_state_poll_errorsandpydaikin_daily_energy_poll_errors(each failedupdate_statusis counted on the domain that was actually in flight, including the first call in a state+energy tick). - Response time (disabled by default):
pydaikin_state_domain_response_timeandpydaikin_energy_domain_response_timereport the duration of the last poll attempt for that domain—success or failure—in seconds, capped at the configured connection timeout (so timeouts show up as a flat line at the cap instead of leaving the previous success value unchanged). - Integration diagnostics (Home Assistant Download diagnostics on the integration or device): redacted config/options plus coordinator runtime (intervals, error counts, last response times, firmware/model hints). See Integration diagnostics.
- Transient communication warnings in the log include a clearer exception summary (type and message, or
reprwhen the message is empty).
- Per-device daily error counters for pydaikin communication (disabled by default in the entity registry):
- Clear default entity IDs: For new devices and new installations,
suggested_object_idis only the suffix (sensor key,hvac,zone_N, …). Home Assistant then buildssensor.<device_slug>_<suffix>(e.g.sensor.salon_humidity), so the device name is not duplicated in theentity_id. - Advanced Functions: Support for Streamer mode, Powerful (Boost), and Econo modes.
- Instant Feedback: State updates immediately in the UI after any setting change (no more waiting for the 30s refresh cycle).
- Polling:
- Default: recurring updates use pydaikin’s
update_status()(per device class; for BRP069 with energy this typically meansget_sensor_info,get_control_info,get_day_power_ex,get_week_power— not the full init resource list, so e.g. year aggregates are not fetched on every poll). - BRP069 optimization: polling can be split into state vs energy domains with different intervals to reduce network load and timeout risk.
- State:
aircon/get_sensor_info,aircon/get_control_info - Energy:
aircon/get_day_power_ex,aircon/get_week_power - Options:
poll_interval_state_secandpoll_interval_energy_sec(shown only for BRP069 with energy support).
- State:
- Default: recurring updates use pydaikin’s
- Open HACS in Home Assistant.
- Click the three dots in the top right corner and choose Custom repositories.
- Add the URL of this repository with the category Integration.
- Search for "Daikin Local" and click Download.
- Restart Home Assistant.
- Download the
custom_components/daikin_localfolder. - Copy it into the
custom_componentsdirectory of your Home Assistant installation. - Restart Home Assistant.
UI strings: custom_components/daikin_local/strings.json (English, required by some tooling) mirrors translations/en.json; other languages live in translations/ (e.g. fr.json). Keys under config.step.*.data must match the field names in config_flow.py (e.g. host, connection_timeout, poll_interval_sec); values like [%key:common::config_flow::data::host%] reuse Home Assistant’s built‑in labels. When you change English strings, update strings.json and translations/en.json together so they stay in sync.
- Go to Settings > Devices & Services.
- Click Add Integration.
- Search for Daikin Local.
- Enter the IP address of your Daikin unit, plus connection timeout (max time per HTTP request) and update interval (coordinator cadence when not using BRP069 state/energy split).
- Note: It is highly recommended to set a static IP for your AC unit via your router.
The total_power sensor (kW) is an estimated value derived by pydaikin from the slope of total energy counters. On some systems this estimate can be noisy when totals are inconsistent, so it is disabled by default. When enabled, it is updated on energy-domain refreshes (BRP069) to avoid excessive calculations and log spam.
Statistics import uses Home Assistant’s supported API (async_import_statistics) and only targets entity IDs belonging to this integration’s energy sensors (resolved via the entity registry). It does not iterate your whole system and cannot intentionally delete other integrations’ entities.
If you observe missing long-term statistics for unrelated devices, that usually points to a recorder / database issue (purge, disk space, restore, or Core update), not to a selective “delete all but Daikin”. Keep regular backups of Home Assistant (and the recorder DB) before bulk history corrections.
There are two complementary ways to correct history:
-
Manual services (recommended starting point)
When Daikin posts late hourly data, run:daikin_local.sync_history— detailed sensors (energy / cool / heat).
Parameter:days_ago—0= today only,1= yesterday then today.daikin_local.sync_total_history— total-energy sensor only (optionalentity_id).
-
Automatic sync integrated with polling
If you enable Options → Auto history sync:- After each successful energy refresh, the integration will attempt at most one history correction per local hour (using the same pydaikin data as the poll).
- Recent, completed hours are selected based on:
history_skip_extra_hours→ additional most recent hours to skip (current hour is always skipped).history_hours_to_correct→ number of hours to correct immediately before the skipped range.
- If a run fails (recorder not ready, transient errors), the integration broadens the window by one extra hour on the next attempt and retries on the next energy refresh.
Polling interval is set when adding the device, under Reconfigure, or in Options — Options override the value stored at setup when set.
If you have multiple controllers (e.g. two BRP069 adapters) that belong to the same outdoor unit / heat pump, you may want to avoid double work or ambiguous “system total” corrections.
Options:
energy_group_id(optional): assign the same group id (e.g.PAC_1) to all entries that belong to the same physical system.
This group id is used to scope the fallback aggregation for total history correction: when rebuilding a total series by summing cool+heat, only devices from the same group are included.
Ifenergy_group_idis empty, the fallback sums every entry that also has an emptyenergy_group_id(the “ungrouped” pool); entries with a non-empty group id are never mixed into that sum.energy_group_total_history_master(optional): mark exactly one entry per group as the master.
Fordaikin_local.sync_total_historywithoutentity_id: if at least one entry in a group is marked master, the service runs only on masters for that group. If no master is set for that group, or for ungrouped entries, the service runs only on entries whose compressor total energy sensor (compressor_energy_consumption/total_energy_today) exists in the entity registry and is not disabled — so disabled totals are skipped and you avoid useless work.
Integration options also set the default for insert missing hourly rows when running sync_history / sync_total_history without the insert_missing parameter; you can still override per service call.
If you see errors about duplicate statistic rows when correcting history: the integration now updates only hours that already have long-term statistics rows by default (insert_missing = false on services). That avoids clashing with Home Assistant’s hourly statistics compiler, which also inserts into the same table. Use insert_missing: true only when you need to backfill hours that have no row yet (rare recorder warnings may still appear).
No — not through the import API we use. In Home Assistant Core, async_import_statistics queues a job that runs _import_statistics_with_session: it loads metadata for one statistic_id, then inserts or updates hourly rows only for that statistic’s metadata_id. There is no “delete all other sensors” path in that code path.
So a sharp cutoff (e.g. “everything after 17:00 yesterday is gone for every device”) is not something this integration can do by design. It usually indicates something that affected the recorder database or Core as a whole, for example:
| Likely cause | What to check |
|---|---|
| Retention / purge | Settings → System → Recorder — retention days, automatic purge, filters |
| Backup restore | Partial restore, wrong snapshot, or DB file replaced |
| Disk / DB health | Full disk, SQLite corruption, abrupt power loss |
| Core / recorder update | Logs at upgrade time; migrations touching statistics |
| Excluded entities | Recorder exclude / include changed |
| States vs statistics | Energy dashboard uses long-term statistics; missing states is different from missing statistics |
What to verify
- Developer Tools → Statistics — see whether other entities still have rows after the cutoff (if yes, the issue is UI/dashboard/config; if no, the DB really lost data).
- Full Home Assistant backup before the cutoff — restoring
home-assistant_v2.dbis a last resort and should be done with care. - Host logs at the exact time the gap starts (recorder errors, purge, restart).
Correlation in time with running sync_history does not prove causation: the same window often includes Core updates, backups, or purge jobs.
- Check Settings → System → Recorder (retention, purge, included/excluded entities).
- Check host disk space and Core logs around the time the gap started.
- Restore from a backup taken before the issue if the database was damaged.
- Use Developer Tools → Statistics to confirm whether data is missing in the DB or only in the dashboard.
The integration sets suggested_object_id to a suffix only (sensor key, hvac for the main climate, zone_N / streamer / toggle for switches, etc.). Home Assistant prepends the device name slug when registering the entity, so you get ids like sensor.<room>_humidity, not sensor.<room>_<room>_humidity. The unique_id remains <mac>-<key> and is unchanged. Existing entities in the registry are not renamed automatically when you upgrade the integration.
Use the official entity settings so history and long-term statistics stay tied to the same logical entity (Core migrates recorder metadata when the entity registry changes).
- Open Settings → Devices & services (or Settings → Entities if your build exposes a direct Entities entry).
- Open the Entities tab (or use the header search) and find the Daikin Local entity.
- Click the entity → ⚙️ (settings) or Edit.
- Expand Advanced settings (wording may vary slightly).
- Set the Entity ID:
- Circular-arrow reset (next to the Entity ID field): restores Home Assistant’s suggested id. The integration only supplies the suffix; Core adds the device slug once at the front (see above).
- Manual edit: enter any valid id (lowercase,
domain.namefor sensors, e.g.sensor.salon_energy_consumption) if you prefer a custom name.
- Save.
After renaming
- History and long-term statistics (including energy graphs) are updated by Home Assistant for that entity. Allow some time for background work; avoid mass renames and immediate restarts in a tight loop.
- Energy dashboard configuration (Settings → Dashboards → Energy, or Settings → Energy depending on your UI):
- In most cases, references follow the renamed entity.
- Verify the Energy configuration screen: if a grid entry shows Unknown entity, unavailable, or clearly wrong data, open that section (individual device, grid consumption, gas, etc.), remove the broken line or re-select the sensor from the list so it points at the new
entity_id. You do not need to change anything if the card still shows the correct sensor and live values.
- Automations, scripts, and YAML that used the old
entity_idmust be updated to the new id (or use device triggers / entity labels where possible to reduce breakage next time).
Take a backup before renaming many entities at once.
This integration uses the pydaikin library to communicate with the devices. It is optimized to be fully asynchronous to ensure it never blocks the main Home Assistant process.
Unlike the official integration which can sometimes be limited or hardware-dependent, this version was designed to provide better responsiveness and extended support for specific features like zones and advanced modes.
Developed with ❤️ for the Home Assistant community.