Integrate Electrolux to MQTT / Home Assistant
10K+
A robust TypeScript bridge for controlling Electrolux appliances via MQTT and Home Assistant. Features automatic discovery, dynamic appliance management, and a modular architecture for easy extensibility.
stable/beta), OS name and version, CPU architecture, and connected-appliance model id(s) and count to a self-hosted Aptabase instance. It also sends a stable per-install id — a one-way SHA-256 hash of your Electrolux username (never the username itself or any credential) — so the same install can be counted over a rolling ~24h (26h) window without revealing who you are. Aptabase additionally derives an approximate country from the request IP. Opt out by setting E2M_TELEMETRY_ENABLED=false. This is a personal project maintained in my free time, and knowing the active user count helps me gauge how much effort to invest in it.Relevant links:
| Model | Type | Notes |
|---|---|---|
| Electrolux Comfort 600 | Portable Air Conditioner | Full support: climate modes, fan speed, swing, sleep mode, temperature control |
Unknown models that report as a portable air conditioner will use the Comfort 600 implementation as a fallback. If you have a different Electrolux appliance and would like support added, please open an issue.
All configuration can be provided via environment variables or via config.yml file. If a config.yml file is present, it will be used and environment variables will be ignored.
Example config.yml file is included in the repository and can be used as a template.
For detailed descriptions and reasoning behind each option, see the comments in
config.example.yml.
| Variable | Description | Default | Required |
|---|---|---|---|
MQTT_URL | MQTT broker URL (mqtt:// or mqtts://) | — | Yes |
MQTT_USERNAME | MQTT broker username | — | Yes |
MQTT_PASSWORD | MQTT broker password | — | Yes |
ELECTROLUX_API_KEY | Electrolux API key | — | Yes |
ELECTROLUX_USERNAME | Electrolux account email | — | Yes |
ELECTROLUX_PASSWORD | Electrolux account password | — | Yes |
ELECTROLUX_COUNTRY_CODE | Two-letter uppercase country code | — | Yes |
MQTT_TOPIC_PREFIX | MQTT topic prefix | electrolux_ | No |
MQTT_CLIENT_ID | MQTT client identifier | electrolux-comfort600 | No |
MQTT_RETAIN | Retain MQTT messages | false | No |
MQTT_QOS | MQTT QoS level (0, 1, or 2) | 2 | No |
ELECTROLUX_REFRESH_INTERVAL | State polling interval in seconds (10–3600) | 30 | No |
ELECTROLUX_APPLIANCE_DISCOVERY_INTERVAL | Appliance discovery interval in seconds (60–3600) | 300 | No |
ELECTROLUX_RENEW_TOKEN_BEFORE_EXPIRY | Minutes before token expiry to refresh (5–715) | 60 | No |
ELECTROLUX_COMMAND_STATE_DELAY_SECONDS | Seconds to wait after a command before re-polling state (5–300) | 30 | No |
ELECTROLUX_APPLIANCE_REMOVAL_GRACE_PERIOD_MINUTES | Minutes an appliance must be continuously absent before cleanup (1–1440) | 30 | No |
ELECTROLUX_API_TIMEOUT_SECONDS | HTTP request timeout in seconds for Electrolux API calls (1–120) | 25 | No |
HOME_ASSISTANT_AUTO_DISCOVERY | Enable HA MQTT auto-discovery | true | No |
HOME_ASSISTANT_REVERT_STATE_ON_REJECTION | Immediately revert HA state on rejected commands | false | No |
HA_BIRTH_REPUBLISH | Re-publish discovery config + state when HA comes online (birth message) | true | No |
HA_STATUS_TOPIC | MQTT topic HA publishes its birth/will message to | homeassistant/status | No |
HA_BIRTH_PAYLOAD | Payload that signals HA is online | online | No |
LOG_LEVEL | Log level (silent/fatal/error/warn/info/debug/trace) | info | No |
LOGGING_SHOW_CHANGES | Log state changes | true | No |
LOGGING_IGNORED_KEYS | Comma-separated keys to ignore in change logs | — | No |
LOGGING_SHOW_VERSION_NUMBER | Show version in log prefix | true | No |
LOGGING_SKIP_CACHE_LOGGING | Suppress cache debug logs | true | No |
LOGGING_SHOW_TIMESTAMP | Show timestamps in logs | true | No |
VERSION_CHECK_INTERVAL | Update check interval in seconds (60–86400) | 3600 | No |
VERSION_CHECK_NOTIFY_GRACE_PERIOD | Minimum age (seconds) a release must reach before you are notified (0–604800) | 3600 | No |
VERSION_CHECK_NTFY_WEBHOOK_URL | ntfy.sh webhook URL for update notifications | — | No |
VERSION_CHECK_UPDATE_CHANNEL | stable skips pre-release builds; beta includes them. Omit to use the image default: :next images are built with beta, :latest images with stable. Set only to override the image default. | image-baked | No |
HEALTH_CHECK_ENABLED | Enable file-based health check for Docker HEALTHCHECK | true | No |
HEALTH_CHECK_FILE_PATH | Path to health check file | /tmp/e2m-health | No |
HEALTH_CHECK_UNHEALTHY_RESTART_MINUTES | Minutes of API failure before container self-restarts | 45 | No |
E2M_TELEMETRY_ENABLED | Send anonymous telemetry (version, channel, OS, arch, appliance models/count) to self-hosted Aptabase. Opt out with false. | true | No |
Choose one of the following methods and open the details.
docker with config.ymlconfig.example.yml as config.yml:
cp config.example.yml config.yml
config.yml accordingly and save changes:
code config.yml
docker pull kirbownz/electrolux-to-mqtt:latest
docker run --rm -v ./config.yml:/app/config.yml:ro --name electrolux-to-mqtt kirbownz/electrolux-to-mqtt:latest
docker with environmental variablesdocker pull kirbownz/electrolux-to-mqtt:latest
docker run --rm \
# Mandatory variables \
-e MQTT_URL=mqtt://192.168.1.1:1883 \
-e MQTT_USERNAME=mqtt-user \
-e MQTT_PASSWORD=mqtt-password \
-e ELECTROLUX_API_KEY=electrolux-api-key \
-e [email protected] \
-e ELECTROLUX_PASSWORD=electrolux-password \
-e ELECTROLUX_COUNTRY_CODE=FI \
# Optional variables \
# -e MQTT_TOPIC_PREFIX=electrolux_ \
# -e MQTT_CLIENT_ID=electrolux-comfort600 \
# -e MQTT_RETAIN=false \
# -e MQTT_QOS=2 \
# -e ELECTROLUX_REFRESH_INTERVAL=30 \
# -e ELECTROLUX_APPLIANCE_DISCOVERY_INTERVAL=300 \
# -e ELECTROLUX_RENEW_TOKEN_BEFORE_EXPIRY=60 \
# -e ELECTROLUX_COMMAND_STATE_DELAY_SECONDS=30 \
# -e ELECTROLUX_APPLIANCE_REMOVAL_GRACE_PERIOD_MINUTES=30 \
# -e ELECTROLUX_API_TIMEOUT_SECONDS=25 \
# -e HOME_ASSISTANT_AUTO_DISCOVERY=true \
# -e HOME_ASSISTANT_REVERT_STATE_ON_REJECTION=false \
# -e HA_BIRTH_REPUBLISH=true \
# -e HA_STATUS_TOPIC=homeassistant/status \
# -e HA_BIRTH_PAYLOAD=online \
# -e LOG_LEVEL=info \
# -e LOGGING_SHOW_CHANGES=true \
# -e LOGGING_IGNORED_KEYS=networkInterface,totalRuntime \
# -e LOGGING_SHOW_VERSION_NUMBER=true \
# -e LOGGING_SKIP_CACHE_LOGGING=true \
# -e LOGGING_SHOW_TIMESTAMP=true \
# -e VERSION_CHECK_INTERVAL=3600 \
# -e VERSION_CHECK_NOTIFY_GRACE_PERIOD=3600 \
# -e VERSION_CHECK_NTFY_WEBHOOK_URL=https://ntfy.sh/vB66ozQaRiqhTE9j \ # Register your own at https://ntfy.sh/
# -e VERSION_CHECK_UPDATE_CHANNEL=stable \ # image default (omit unless pinning)
# -e HEALTH_CHECK_ENABLED=true \
# -e HEALTH_CHECK_FILE_PATH=/tmp/e2m-health \
# -e HEALTH_CHECK_UNHEALTHY_RESTART_MINUTES=45 \
# -e E2M_TELEMETRY_ENABLED=true \
--name electrolux-to-mqtt kirbownz/electrolux-to-mqtt:latest
docker composedocker-compose.example.yml as docker-compose.yml:
cp docker/docker-compose.example.yml docker-compose.yml
docker-compose.yml accordingly and save changes:
code docker-compose.yml
docker compose down ; docker compose up --pull always -d
electrolux-to-mqttWeb editor, copy the following variables and make changes accordingly, finally press Deploy the stack:services:
electrolux-to-mqtt:
image: kirbownz/electrolux-to-mqtt:latest
mem_limit: 128mb
memswap_limit: 256mb
restart: unless-stopped
volumes:
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
environment:
# Mandatory variables
- MQTT_URL=mqtt://192.168.1.1:1883
- MQTT_USERNAME=mqtt-user
- MQTT_PASSWORD=mqtt-password
- ELECTROLUX_API_KEY=electrolux-api-key
- [email protected]
- ELECTROLUX_PASSWORD=electrolux-password
- ELECTROLUX_COUNTRY_CODE=FI
# Optional variables (uncomment as needed)
# - MQTT_TOPIC_PREFIX=electrolux_
# - MQTT_CLIENT_ID=electrolux-comfort600
# - MQTT_RETAIN=false
# - MQTT_QOS=2
# - ELECTROLUX_REFRESH_INTERVAL=30
# - ELECTROLUX_APPLIANCE_DISCOVERY_INTERVAL=300
# - ELECTROLUX_RENEW_TOKEN_BEFORE_EXPIRY=60
# - ELECTROLUX_COMMAND_STATE_DELAY_SECONDS=30
# - ELECTROLUX_APPLIANCE_REMOVAL_GRACE_PERIOD_MINUTES=30
# - ELECTROLUX_API_TIMEOUT_SECONDS=25
# - HOME_ASSISTANT_AUTO_DISCOVERY=true
# - HOME_ASSISTANT_REVERT_STATE_ON_REJECTION=false
# - HA_BIRTH_REPUBLISH=true
# - HA_STATUS_TOPIC=homeassistant/status
# - HA_BIRTH_PAYLOAD=online
# - LOG_LEVEL=info
# - LOGGING_SHOW_CHANGES=true
# - LOGGING_IGNORED_KEYS=networkInterface,totalRuntime
# - LOGGING_SHOW_VERSION_NUMBER=true
# - LOGGING_SKIP_CACHE_LOGGING=true
# - LOGGING_SHOW_TIMESTAMP=true
# - VERSION_CHECK_INTERVAL=3600
# - VERSION_CHECK_NOTIFY_GRACE_PERIOD=3600
# - VERSION_CHECK_NTFY_WEBHOOK_URL=https://ntfy.sh/vB66ozQaRiqhTE9j # Register your own at https://ntfy.sh/
# - VERSION_CHECK_UPDATE_CHANNEL=stable # image default (omit unless pinning)
# - HEALTH_CHECK_ENABLED=true
# - HEALTH_CHECK_FILE_PATH=/tmp/e2m-health
# - HEALTH_CHECK_UNHEALTHY_RESTART_MINUTES=45
# - E2M_TELEMETRY_ENABLED=true
Pre-release (beta) builds are published to the :next Docker tag on every push to the next branch.
Betas follow Home Assistant's CalVer scheme YYYY.M.MICRObN (e.g. 2026.6.0b1). Each beta changelog
covers only the changes since the previous release (stable or beta).
:next and :latest are separate images built with different update channel defaults baked in:
:latest — built with stable channel baked in; only notifies about stable releases.:next — built with beta channel baked in; notifies about both beta and stable releases.This means the correct channel is always active regardless of what version number is running — even if
:next temporarily carries a promoted-stable version (e.g. 2026.6.4, no bN), it still defaults to
the beta channel.
Note: Pre-release builds may contain unfinished features or bugs. Use
:latestfor production.
To use the beta channel, replace :latest with :next in your setup:
docker:
docker pull kirbownz/electrolux-to-mqtt:next
docker run --rm -v ./config.yml:/app/config.yml:ro --name electrolux-to-mqtt kirbownz/electrolux-to-mqtt:next
docker-compose / Portainer: change the image: line:
image: kirbownz/electrolux-to-mqtt:next
When running the :next image, the update channel defaults automatically to beta — no extra
configuration needed. Override with VERSION_CHECK_UPDATE_CHANNEL=stable (env var) or
updateChannel: stable in config.yml under versionCheck: to pin to the stable channel.
Release notes for each beta are available on the GitLab releases page.
Either running natively locally:
# Copy config.example.yml
cp config.example.yml config.yml
# Modify as needed
code config.yml
# Make sure you have the correct toolchain (Node.js etc. — pinned in mise.toml)
# If you don't have mise installed, follow https://mise.jdx.dev/getting-started.html
mise install
# Install correct pnpm version if not installed already
corepack enable
corepack install
# Install the dependencies
pnpm install
# Run the app in development mode
pnpm dev
..or if you want to use Docker instead:
# Make a copy of the docker-compose.local.example.yml
cp docker/docker-compose.local.example.yml docker/docker-compose.local.yml
# Modify as needed
code docker/docker-compose.local.yml
# Run the stack (automatically uses Node version from .nvmrc)
NODE_VERSION=$(cat .nvmrc) docker compose -f docker/docker-compose.local.yml down ; NODE_VERSION=$(cat .nvmrc) docker compose -f docker/docker-compose.local.yml up --build
# Or if you have pnpm installed:
pnpm dev:docker
This project includes comprehensive unit tests to ensure reliability:
# Run all tests
pnpm test
# To run E2E tests (including version-checker E2E):
pnpm test:e2e
# You can override the ntfy notification topic for E2E tests with:
E2M_NTFY_TOPIC=yourtopic pnpm test:e2e
# If not set, the default topic is `vB66ozQaRiqhTE9j`.
# Run tests in watch mode (auto-rerun on changes)
pnpm test:watch
The CHANGELOG.md is baked into the Docker image at /app/CHANGELOG.md. To extract it from a running container:
# Auto-detect the container name (assumes it contains "electrolux-to-mqtt")
docker cp $(docker ps --filter name=electrolux-to-mqtt --format '{{.Names}}' | head -1):/app/CHANGELOG.md ./CHANGELOG.md
# Or specify the container name explicitly
docker cp <container-name>:/app/CHANGELOG.md ./CHANGELOG.md
cat CHANGELOG.md
Contributions are welcome! Please see CONTRIBUTING.md for detailed guidelines on:
Please read HOME_ASSISTANT.md for more details.
Inspired by — and thanks to — Dannyyy for the Electrolux to MQTT repository. I kept running into issues with various other implementations, and often had to wait a while for fixes, so I decided to build my own on top of the public Electrolux API.
Content type
Image
Digest
sha256:63676f49a…
Size
39.7 MB
Last updated
18 days ago
docker pull kirbownz/electrolux-to-mqtt