Skip to content

Add LG PuriCare humidifier HUM_056905_WW - #114

Open
tunarabuuu wants to merge 1 commit into
anszom:masterfrom
tunarabuuu:dev-humidifier
Open

Add LG PuriCare humidifier HUM_056905_WW#114
tunarabuuu wants to merge 1 commit into
anszom:masterfrom
tunarabuuu:dev-humidifier

Conversation

@tunarabuuu

Copy link
Copy Markdown
Contributor

Second of the per-device-class splits from #111.

HUM_056905_WW — a ThinQ2 PuriCare humidifier (deviceType 404) on the existing TLV path. The wire map is taken from LG's own modelJSON tlv_* labels rather than guessed tags, and every enum was confirmed against the LG cloud's decode of the same unit while bridged.

Shared infrastructure (same as the dehumidifier PR #113): TLVDevice's packet gate accepts 0xA7 in byte 6 alongside 0x87 — this family frames with 0xA7. Originally from @BluSyn's #64.

All labels are English. npm test passes; tsc clean.

@anszom anszom left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase to the latest master, the 0xa7 change was already applied there.
Also please add a note to the README with the device's "public" model name.

Comment thread cloud/devices/HUM_056905_WW.ts Outdated
Comment on lines +27 to +29
* The rest are LG's own declarations, published because the appliance reports them: every
* id here appeared in the device's answer to a values query (0x1f5=2), so nothing below is
* an entity for a field this unit does not have.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment contradicts the example packet provided in QUERY_RESPONSE_HEX. The TLVs 0x117 0x10e 0x337 0x35a and 0x35b don't appear there.

Comment thread cloud/devices/HUM_056905_WW.ts Outdated
this.addSwitch(config, 0x20e, 'auto_dry', 'Auto dry', 'mdi:fan-auto', AUTO_DRY_ON)

this.addNumber(config, 0x21e, 'watertank_light', 'Tank light brightness', 'mdi:lightbulb', 0, 200, 1)
this.addNumber(config, 0x21b, 'off_timer', 'Off timer (min)', 'mdi:timer-off', 0, 720, 10)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use addTimerField here? Follow the RAC_.. implementation as well.

Comment thread cloud/devices/HUM_056905_WW.ts Outdated
Comment on lines +244 to +251
this.addSensor(config, 0x355, 'filter_used', 'Filter usage hours', {
icon: 'mdi:filter-outline',
entity_category: 'diagnostic',
})
this.addSensor(config, 0x356, 'filter_max', 'Filter replacement cycle', {
icon: 'mdi:filter-cog',
entity_category: 'diagnostic',
})

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RAC_05... publishes similar entities, can you make these consistent with them?

Comment on lines +71 to +76
const DISPLAY_BRIGHTNESS = [
['Off', 0],
['1Level', 8],
['2Level', 9],
['3Level', 10],
] as const

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be better to expose this as a simple integer value 0-3? Either that, or use readable names "Level 1".."Level 3"

Comment thread cloud/devices/HUM_056905_WW.ts Outdated
unit_of_measurement: '%',
state_class: 'measurement',
})
;(config.components as any).humidifier.current_humidity_topic = '$this/current_humidity-'

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as any casts may not be necessary after rebasing to master where a HumidifierComponent is defined already.

Comment thread cloud/devices/HUM_056905_WW.ts Outdated
Comment on lines +202 to +203
this.addNumber(config, 0x35a, 'start_time', 'Scheduled on time(HHMM)', 'mdi:clock-start', 0, 2400, 10)
this.addNumber(config, 0x35b, 'stop_time', 'Scheduled off time(HHMM)', 'mdi:clock-end', 0, 2400, 10)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HHMM is not understood natively by homeassistant, use platform: time and convert to a HH:MM:SS format. The exact details depend on the actual values used by the appliance, including a "no timer set" state.

dev.drop()
})

test('every mode code decodes to its Korean label', (t) => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no Korean labels anymore

A ThinQ2 humidifying air purifier on the existing TLV path (deviceType 404). The
wire map is taken from LG's own modelJSON tlv_* labels rather than guessed tags,
and its enums were confirmed against the LG cloud's decode while bridged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tunarabuuu

Copy link
Copy Markdown
Contributor Author

Rebased onto master — the 0xA7 change is gone from this branch since it is already there, so this is now the driver, its tests, the bridge entry and a README line.

Your comments, one by one:

  • as any casts (:181) — right, they were only there because HumidifierComponent did not exist yet. The config is now typed DeviceDiscovery & { components: { humidifier: HumidifierComponent } } with satisfies HumidifierComponent, and current_humidity_topic is set through the type instead of a cast. The helper builders use allowExtendedType like the rest of the codebase. The only cast left is the state_topic / command_topic pair, which is not on HumidifierComponent — the same two lines your DHUM_056905_WW casts for.

  • Header contradicts QUERY_RESPONSE_HEX (:29) — you are right, and I checked the frame rather than the claim. The values response carries every id the driver uses except 0x117 (over-humidification prevention) and 0x337 (air-quality sensor mode); 0x35a/0x35b are gone entirely, see below. The header now says exactly that: all but those two were observed, and those two are LG's modelJSON declaration for the model, marked as such at their call site too.

  • Display brightness (:76) — now Off / Level 1 / Level 2 / Level 3.

  • addTimerField (:201) — done, copied from RAC_056905_WW so the two behave identically: hours in Home Assistant, minutes on the wire, device_class: duration, 0.25 h steps, slider. Max is 12 h rather than RAC's 24, because LG's airState.reservation.targetTimeToStop validates 0..720 minutes for this model.

  • HHMM on 0x35a/0x35b (:203) — dropped both. They are LG's absoluteStartTime / absoluteStopTime, validated 0..2400, and you are right that HA cannot read that; but I have no capture that pins down what the appliance uses for "no schedule", so a platform: time conversion would be a guess at the one value that matters. Better absent than wrong — I will send them as a follow-up once I can drive the schedule and watch both tags.

  • Consistency with RAC_05… (:251) — the filter and auto-dry sensors now match what RAC publishes: filterused "Filter used time" (duration, h, total_increasing, diagnostic), filterlife "Filter life time" (duration, h, diagnostic) and autodryremain "Auto dry remaining" (%, suggested_display_precision: 0, diagnostic), same icons.

  • Test :90 — the "Korean label" wording is gone; nothing in the suite claims that any more.

420 tests passing (409 on master + 11 here), tsc --noEmit and prettier --check clean.

On the README: I listed it by its ThinQ id, because LG's modelJSON for this platform gives no marketing model name (Info.modelName is literally Full Model) and I could not find one in any capture. Say the word and I will read the sticker off the unit and replace it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants