feat(dishwasher): Add LG Dishwasher (H11) support - #139
Open
asata wants to merge 4 commits into
Open
Conversation
added 3 commits
August 15, 2026 18:30
- Add local AABB parser for LG Dishwasher (H11) - Map dishwasher states, courses, and options to Home Assistant sensors - Support power control commands (Wake Up / Power Off) - Exclude fake local energy/cycle count data (LG Cloud only) - Register H11 in ha_bridge
- Add Pause, Resume, Cancel/Drain Stop commands - Add remote start parameters (Course, Delay, High Temp, Extra Dry, Extra Rinse) - Add start course button that dynamically builds f0 26 10 packet
* Add 7 new entities to control auxiliary settings (salt, rinse, buzzer, clean reminder, auto dry, brightness, remote start mode). * Update status payload (`00 18` block) parsing logic to map setting flags from bytes `[11]`, `[13]`, `[14]`, `[15]`, `[16]`, and `[19]`. * Implement `sendSettings` logic to safely overwrite a single setting by caching previous states and using bitwise operations for the `f0 26` control packet. * Convert `rinse_level` from a read-only sensor to a configurable number entity.
- Add support for parsing the `323e` energy statistics packet. - Extract the 2-byte accumulated energy consumption value (Wh). - Implement sequence-based deduplication logic to ignore redundant burst packets. - Expose the `energy_consumption` sensor via MQTT Discovery (`state_class: total_increasing`).
Owner
|
Thank you for the PR. I've just returned from vacation and I'm slowly working through the PR & issue backlog. I'd appreciate your patience :) |
jmhufford
pushed a commit
to jmhufford/rethink
that referenced
this pull request
Aug 21, 2026
Deployed to a real instance and read the service log back. The handler binds (no more "thinq2 device type N17 unknown"), publishes its discovery config, and decodes energy_consumption 0 -> 2 Wh from real frames. Three things I wrote from the bench capture were wrong, and one open question is answered. Wrong: 0x3E is not wash-only and 0x0A does not stop during a wash. Both types interleave in the same burst with the appliance idle at 2 Wh. The appliance does not stream continuously at all — it goes quiet for minutes, then bursts for about a minute (0x0A every 1-5s, 0x3E every 4-6s). Wrong: the 0x0A length byte is not a length. It reads 0xFF while the frame is 87 or 88 bytes, and 0x0A is the only type here that fails this repo's AABB checksum — 0x31, 0x72 and 0x3E all pass. Neither matters, because AABBDevice keys off the 0xAA/0xBB delimiters, but it explains the checksum failures seen earlier and it means the length byte cannot be trusted for this type. Answered: the statistics layout. The bench capture only ever saw all-zero payloads, so nothing distinguished delta from accumulated. A live change gives 32 3E 0002 0002 01 against 32 3E 0000 0000 00 — consistent with PR anszom#139's "delta, accumulated, sequence", and the sequence byte moved with the value and then held across six identical frames, so on this appliance it behaves as a change counter rather than the burst counter PR anszom#139 describes. 0x32 0xEC still never appears — zero occurrences across the whole deployment log, corroborating the bench capture on independent firmware. So state, course, remaining time and door remain unpublished and start() still sends nothing. Test fixtures now use real captured frames for 0x0A, 0x31, 0x72 and both statistics readings; the synthetic 0x72 stand-in is gone. The only synthetic fixtures left are the 0xEC ones, which have nothing real to draw on, and the sequence-wrap case, which is labelled as not-yet-observed behaviour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds support for the LG Dishwasher to the local AABB packet parser.
It includes read-only sensors for monitoring the dishwasher's state and full remote control capabilities reverse-engineered from the ThinQ app, including comprehensive auxiliary settings.
Features Added
state,course,remain_timeswitch, Pausebutton, Resumebutton, Cancel / Drain Stopbutton0x08), Extra Dry (0x04), Extra Rinse (1~3 levels)start_coursebutton dynamically constructs thef0 26 10control payload based on the selected virtual entities.salt_level,rinse_level,buzzer_level,end_alarm_sound,clean_reminder,auto_dry, andbrightness.remote_start_mode(Permanent, One-Time, Off) to configure the machine's behavior after cycles.🔍 Complete Packet Analysis & Protocol Structure (For Reviewers)
During the development of this parser, we successfully decoded the complete structure of the AABB local protocol for both status reporting and appliance control. Here is the full breakdown of the protocol for the H11 Dishwasher:
1. Status Payload (
32 ec->00 18Tag Block)The machine reports its current state using
32 ecpackets. The second half of the payload contains a00 18tag block followed by 24 bytes of data. Key offsets (starting at 0):[0](State):01(INITIAL),02(RUNNING),03(PAUSE),04(STANDBY)[3] & [4](Initial Time): Initial Course Time (Hour, Minute)[5](Course): Base Course Code (e.g.,01: Auto,12: 1 Hour,0b: Download Cycle)[7] & [8](Remain Time): Remaining Time (Hour, Minute)[9](Delay Start): Delay start time in hours (0means disabled)[11](Opt1 & Door):0x40(Clean Reminder LED ON),0x10(Auto Dry ON),0x02(Door Open)[12](Wash Options):0x04(Extra Dry ON),0x08(High Temp ON)[13](Rinse Level): Rinse dispenser level (0x00~0x04)[14](Salt Level): Salt dispenser level (0x00~0x04)[15](Buzzer & Btn):0x80(Buzzer HIGH),0x40(Buzzer LOW),0x00(Buzzer OFF). (Note:0x02represents the physical Remote Start button state)[16](Opt2):0x80(Remote Control: PERMANENT),0x40(ONE-TIME),0xc0(OFF).0x04(End Alarm Sound ON)[19](Opt3):0x40(Display Brightness HIGH)[20](Smart Course): Specific Downloaded Course ID (e.g.,0x0f: Plastic,0x0d: Tub Clean)[21](Extra Rinse):00(0),10(1 level),20(2 levels),30(3 levels)2. Control Commands (
f0 26)Unlike washing machines (
32 0a), the dishwasher usesf0 26packets for control.f0 26 16f0 26 12f0 26 13/f0 26 14f0 26 11(Pumps for 1 min, then powers off)f0 26 10 [Course] [DelayHour] [Opt2=0x00] [Opt3] [Opt4] [Opt5=0x00][Opt3](Wash Options):0x08(High Temp),0x04(Extra Dry). Both =0x0c.[Opt4](Rinse Levels):0x08(1),0x10(2),0x18(3). (Note: The0x40flag must be added if the course is0bDownload Cycle)f0 26 [Rinse] [Salt] [Opt1] [Opt2] [Opt3] 00 00 00 003. Note on "Downloaded Courses"
Changing the specific "Downloaded Course" assignment (e.g., changing from Tub Clean to Pots & Pans) cannot be executed via the local network. When changed via the app, the machine downloads the cycle algorithm payload directly from LG Cloud (HTTPS/MQTT). We can monitor the active course ID by reading byte
[20], but we cannot push a new assignment locally.