{"id":50429315,"url":"https://github.com/roquerodrigo/ha-midea-dishwasher","last_synced_at":"2026-05-31T13:01:39.325Z","repository":{"id":356620184,"uuid":"1231137017","full_name":"roquerodrigo/ha-midea-dishwasher","owner":"roquerodrigo","description":"Home Assistant custom integration for Midea dishwashers (LAN, no cloud)","archived":false,"fork":false,"pushed_at":"2026-05-22T10:11:50.000Z","size":410,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T12:31:17.108Z","etag":null,"topics":["custom-component","dishwasher","hacs","home-assistant","home-automation","homeassistant","iot","midea"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roquerodrigo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T17:02:54.000Z","updated_at":"2026-05-22T10:10:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/roquerodrigo/ha-midea-dishwasher","commit_stats":null,"previous_names":["roquerodrigo/ha-midea-dishwasher"],"tags_count":0,"template":false,"template_full_name":"roquerodrigo/ha-integration-blueprint","purl":"pkg:github/roquerodrigo/ha-midea-dishwasher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roquerodrigo%2Fha-midea-dishwasher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roquerodrigo%2Fha-midea-dishwasher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roquerodrigo%2Fha-midea-dishwasher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roquerodrigo%2Fha-midea-dishwasher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roquerodrigo","download_url":"https://codeload.github.com/roquerodrigo/ha-midea-dishwasher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roquerodrigo%2Fha-midea-dishwasher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33731998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-component","dishwasher","hacs","home-assistant","home-automation","homeassistant","iot","midea"],"created_at":"2026-05-31T13:01:38.343Z","updated_at":"2026-05-31T13:01:39.300Z","avatar_url":"https://github.com/roquerodrigo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Midea Dishwasher for Home Assistant\n\n[![CI](https://github.com/roquerodrigo/ha-midea-dishwasher/actions/workflows/ci.yml/badge.svg)](https://github.com/roquerodrigo/ha-midea-dishwasher/actions/workflows/ci.yml)\n[![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/hacs/integration)\n\nHome Assistant integration for **Midea dishwashers** (`device_type 0xE1`, plugin v5), talking to the appliance directly over the LAN — no cloud round-trips at runtime. Built on top of [`midea-dishwasher-api`](https://pypi.org/project/midea-dishwasher-api/), which implements the `AA … E1` application protocol and the LAN V3 transport (handshake 8370 + AES-128-CBC + SHA-256).\n\nConventions for contributors live in [`CODE_STYLE.md`](./CODE_STYLE.md); architectural notes for AI agents in [`CLAUDE.md`](./CLAUDE.md).\n\n## Add to Home Assistant\n\n[![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=roquerodrigo\u0026repository=ha-midea-dishwasher\u0026category=integration)\n\n## What's included\n\n- **Local polling** over LAN V3 — no cloud calls once configured.\n- **Config flow** for host, port, device ID, token, key — with reauth and reconfigure flows.\n- **Options flow** with a configurable `scan_interval` (default 30 s, min 10 s).\n- **Entities**: power switch, door / extra-drying / rinse-aid binary sensors, status / progress / mode / time-remaining / error sensors, rinse-aid level number, and start-eco / start-intensive / cancel buttons.\n- **Service** `midea_dishwasher.start_cycle` (mode + extra-drying) for automations.\n- **Diagnostics platform** with credential redaction (`token`, `key`, `device_id`).\n- **Repairs platform** wired into HA's Issue Registry, with a sample `unreachable_device` issue.\n- **Translations** for English and Brazilian Portuguese (parity enforced by tests).\n- **CI**: ruff lint + format, mypy type-check, `hassfest`, HACS validation, CodeQL.\n- **Coverage gate** at 95 % enforced by `pytest.ini` (currently at 100 %).\n\n## Entities\n\n| Domain | Key | Source field | Notes |\n|---|---|---|---|\n| `switch` | `power` | `machine_state` | `power_on` / `power_off` |\n| `binary_sensor` | `door` | `door_closed` (inverted) | device class `door` |\n| `binary_sensor` | `extra_drying` | `extra_drying` | flag of the running cycle |\n| `binary_sensor` | `rinse_aid` | `bright_lack` | device class `problem`, diagnostic |\n| `sensor` | `status` | `cycle_state` | enum (`power_off`, `idle`, `order`, `work`, `error`, `soft_gear`) |\n| `sensor` | `progress` | `wash_stage` | enum (`idle`, `pre_wash`, `main_wash`, `rinse`, `dry`, `finish`) |\n| `sensor` | `mode` | `mode` | enum (14 programs: `auto`, `eco`, `intensive`, `90min`, `1hour`, `rapid`, …) |\n| `sensor` | `time_remaining` | `left_time` | duration, minutes |\n| `sensor` | `error` | `error_code` | enum (`none`, `water_supply`, `heating`, `overflow`, `water_valve`), diagnostic |\n| `number` | `bright` | `bright` | rinse-aid dosage 1–5 (slider) |\n| `button` | `start_eco` | — | starts ECO cycle |\n| `button` | `start_intensive` | — | starts Intensive cycle (extra-drying ON) |\n| `button` | `cancel` | — | cancels the running cycle |\n\nFor more flexible automations the integration also exposes the `midea_dishwasher.start_cycle` service, which accepts `mode` (any of the 14 programs above) and `extra_drying` (bool).\n\n## Obtaining `token` and `key`\n\n`token` (128 hex chars) and `key` (64 hex chars) are device-specific credentials issued by the Midea cloud. The library does not extract them — use one of the existing tools tied to your Midea account:\n\n- [`midea-msmart`](https://github.com/mill1000/midea-msmart) — `midea-discover login`\n- [`midea-beautiful-air`](https://github.com/nbogojevic/midea-beautiful-air) — `midea-beautiful-air-cli`\n- The **MideaAir** mobile app extraction route described in those projects' docs\n\nOnce you have them, paste into the integration's setup form alongside the dishwasher's IP and `device_id`.\n\n## Useful commands\n\n```bash\nscripts/setup      # install dependencies (requirements.txt)\nscripts/develop    # start Home Assistant in debug mode with the integration loaded\nscripts/lint       # ruff format + check + mypy\npytest             # run tests with the 95 % coverage gate\n```\n\nEach script auto-detects `./.venv` and prepends it to `PATH` — no `source .venv/bin/activate` needed. For ad-hoc commands the same trick works: `.venv/bin/pytest`, `.venv/bin/ruff …`.\n\nHA runs with config in `config/` and `PYTHONPATH` pointing at `custom_components/` — no symlinks. To recreate entity/device IDs during development:\n\n```bash\nrm config/.storage/core.entity_registry config/.storage/core.device_registry\n```\n\n## Layout\n\n```\ncustom_components/midea_dishwasher/\n├── __init__.py             # async_setup_entry / unload / reload\n├── api.py                  # MideaDishwasherApiClient (executor-wrapped LAN client)\n├── binary_sensor/          # door, extra_drying, rinse_aid (one class per file)\n├── brand/                  # icon/logo for HACS\n├── button/                 # cancel, start_eco, start_intensive\n├── config_flow.py          # user / reauth / reconfigure steps\n├── const.py                # DOMAIN, LOGGER, defaults, hex-length constants\n├── coordinator.py          # DataUpdateCoordinator polling the device\n├── data.py                 # typed ConfigEntry + MideaDishwasherData dataclass + TypedDicts\n├── diagnostics.py          # downloadable diagnostics with credential redaction\n├── entity.py               # base CoordinatorEntity\n├── exceptions/             # one file per exception class\n├── manifest.json\n├── number.py               # rinse-aid level slider\n├── options_flow.py         # OptionsFlow with scan_interval\n├── repairs.py              # Repair platform: async_create_fix_flow + sample issue\n├── sensor/                 # status, progress, mode, time_remaining, error\n├── services.py             # midea_dishwasher.start_cycle\n├── services.yaml\n├── switch.py               # power\n└── translations/\n    ├── en.json\n    └── pt-BR.json\n```\n\nThe \"one top-level class per file\" rule (with related classes grouped under a directory) is documented in [`CODE_STYLE.md`](./CODE_STYLE.md).\n\n## Pre-commit hooks\n\nInstall once per clone (after `scripts/setup`):\n\n```bash\npre-commit install\n```\n\nThis wires ruff + basic file hygiene checks (`.pre-commit-config.yaml`) into every commit, mirroring the CI lint job.\n\n## CI\n\n- **`lint.yml`** — ruff (check + format) and mypy (Python 3.14)\n- **`validate.yml`** — `hassfest` + HACS validation; push/PR to `main` and a daily cron\n- **`codeql.yml`** — GitHub CodeQL security scan; push/PR to `main` and a weekly cron\n\n## Credits\n\nThis repository was bootstrapped from [`ludeeus/integration_blueprint`](https://github.com/ludeeus/integration_blueprint) and the [`@roquerodrigo`](https://github.com/roquerodrigo) HACS template that lives at [`roquerodrigo/ha-integration-blueprint`](https://github.com/roquerodrigo/ha-integration-blueprint). The LAN V3 + AA codec implementation lives in the standalone [`midea-dishwasher-api`](https://github.com/roquerodrigo/midea-dishwasher-api) package.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froquerodrigo%2Fha-midea-dishwasher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froquerodrigo%2Fha-midea-dishwasher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froquerodrigo%2Fha-midea-dishwasher/lists"}