v0.78.0 — Factory reset + MyCoffee read/brew for Nivona
Five merged PRs bundled into one release. Focused on Nivona feature parity — factory-reset buttons and the first end-to-end MyCoffee read+brew path. Melitta installs see no functional change.
Added
Factory reset buttons (Nivona)
Two new button entities under entity_category=config, device_class=restart (HA dashboards surface a confirm dialog):
- Factory Reset Settings — sends HE with
commandId = 50(HE_CMD_FACTORY_RESET_SETTINGS); wipes machine-wide settings. - Factory Reset Recipes — sends HE with
commandId = 51(HE_CMD_FACTORY_RESET_RECIPES); wipes per-recipe customizations.
Available on families 600 / 700 / 79x / 900 / 900-light / 1030 / 1040. NIVO 8000 hidden — the vendor app has no factory-reset menu on that family, so we mirror the gating. Melitta brand gets no factory-reset buttons (Melitta uses its own per-register HD reset path).
New generic execute_command(command_id) / execute_he_command(command_id) path on EugsterProtocol / BleCommandsMixin for future HE-with-commandId actions.
MyCoffee bulk read (Nivona)
On every connect, after capability resolution, the client now bulk-reads MyCoffee slot params and caches them on MelittaBleClient.my_coffee_slots. Per-(slot, param) MyCoffee slot N <param> diagnostic sensors expose the cached values. Sensors stay unavailable until the first bulk read completes.
Params read per slot, gated on whether the family's MyCoffee layout defines the corresponding offset:
| Param | Type | Notes |
|---|---|---|
coffee_amount |
int (vendor units, typically ml) | every family |
water_amount |
int | every family |
milk_amount |
int | every family except 600 (no offset on 600) |
milk_foam_amount |
int | every family |
enabled |
0/1 flag | every family — used as the "armed" gate for brew buttons |
strength |
code 1..N | every family |
temperature |
code 0..3 | single-byte families only (600 / 700 / 79x / 8000); 900 / 1030 / 1040 use per-fluid temperature offsets and skip this param |
Sensor counts per family (all under EntityCategory.DIAGNOSTIC):
| Family | Slots | Params | Sensors |
|---|---|---|---|
| NIVO 8000 | 9 | 7 | 63 |
| NICR 1040 | 18 | 6 (no temperature) | 108 |
| NICR 1030 | 18 | 6 | 108 |
| NICR 700 / 79x / 900 / 900-light | per-model | 6–7 | up to 63 |
| NICR 600 | 1–5 (per-model) | 6 (no milk_amount) | up to 30 |
Brew MyCoffee slot N buttons (Nivona)
One button per slot 0..N-1, display name "Brew MyCoffee slot 1..N" (1-indexed). Pressing slot M sends:
HE.payload[3] = caps.first_mycoffee_selector + M (vendor base 20)
HE.payload[5] = 0 (use saved recipe — no temp-recipe write)
Availability gated on:
client.connectedstatus.is_ready_for_brew(tolerated_brew_manipulations)- The slot's cached
enabledflag == 1 — so unconfigured slots stay unavailable instead of firing an empty recipe
Tests
- 8 new tests for the factory-reset path (
tests/test_protocol.py::TestExecuteCommand+tests/test_button.py). - 6 new tests for MyCoffee bulk read (
tests/test_ble_client.py::TestReadMyCoffeeSlots) + 4 sensor-registration tests (tests/test_sensor.py). - 5 new tests for the brew-by-slot path (
tests/test_ble_client.py::TestBrewMyCoffeeSlot) + 3 button tests. - Full suite: 990 passed (was 964 on v0.77.1).
What's intentionally NOT in this release
- Sommelier on Nivona — auto-brew from a Sommelier-generated recipe still requires
brew_freestyle(Melitta HJ); enabling on Nivona needs a recipe-shape mapper to Nivona temp-recipe overrides. - MyCoffee writes — read-only this release. Write support (edit slot params, set name) comes later, behind family-aware encoding for the name field.
- Card adaptation for Nivona recipes-tab — pending UI work.
- NICR 1040 HotMilk slot 8 — known recipe-layout discrepancy, pending hardware confirmation from a 1040 owner.
🤖 Generated with Claude Code