WIN_056905_WW: validate LW1022FVSM through unified RAC - #89
Conversation
Implements full HA climate integration for the WIN_056905_WW family of LG window air conditioners, confirmed working on: - LG LW6023IVSM (6,000 BTU) - LG LW1522IVSM (14,000 BTU) Protocol findings (via live packet capture): - Frame discriminator: buf[6]=0xa7 (vs 0x87 on RAC/POT units) - Tag 0x1f7: power (0=off, 1=on) - Tag 0x1f9: mode (0=cool, 1=dry, 2=fan_only, 8=eco/Energy Saver) - Tag 0x1fa: fan speed (2=low, 4=medium, 6=high) - Tag 0x1fd: current temperature (raw/2 = °C) - Tag 0x1fe: set temperature (raw/2 = °C, clamped 16–30°C) - Tag 0x21a: sleep timer (raw value in minutes) Features implemented: - HVAC modes: off, cool, dry, fan_only - Fan modes: low, medium, high - Eco/Energy Saver mode via HA preset_mode (maps to mode wire value 8) - Sleep timer as a number entity (0-7 hours, slider) - Current and target temperature Notes: - Eco mode (mode=8) is exposed as a climate preset rather than an hvac_mode, since HA only accepts standard hvac_mode values - Off is handled by writing tag 0x1f7 (power) rather than mode - Sleep timer write_xform converts hours to minutes for the wire value - tlv_device.ts: accept 0xa7 as a valid frame kind alongside 0x87 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
That's a significant change to |
|
@gonkey42 it seems you got several steps ahead of me. My intention was to first gather information on the differences between the two models. From what I can tell from your code, the differences are quite extensive:
Perhaps @maciejsszmigiero will be able to identify if these differences could be mapped down to the capability bits. Then we can decide if making a unified implementation actualy makes sense. |
72282f8 to
8fa9de4
Compare
|
Yeah, I got ahead of the information-gathering step here... I cleaned up the draft, and then again after I decided to do some more after doing more testing on the Here’s what I can say from my actual LW1022FVSM /
I'm fine treating PR #89 as a draft evidence branch / possible implementation while you decide how you want to map this down to capability bits, just happy to help! :) |
|
I also found some more sensor data exposed by my LW1022FVSM. I added a small fork-only mapper in my fork so I can experiment with my own setup without adding churn to upstream. I’m only exposing room/indoor temperature, outdoor-side air temperature, and estimated power draw right now, but there are other diagnostic values visible too. Let me know if you want me to post captures, field IDs, or more details here. |
|
I just did testing for a few hours and dug a lot further into the data from my LW1022FVSM after getting it working locally. I put a small fork-only mapper in my fork so I can experiment with my own setup without adding churn here. I’m only exposing three normal Home Assistant sensors right now, because those are the ones I actually want on dashboards/automations:
I also did some live testing with mode changes, fan speed, setpoint changes, Energy Saver, and real Dry mode. A few more TLVs are pretty clear now:
The only changing TLV from my original mystery list that I still would not name is:
Mode mapping also got clearer on this unit:
One Home Assistant detail that confused me at first: both Energy Saver and true Dry can show Some other RAC-ish fields that line up with the existing path / captures:
In my fork I intentionally only expose the three useful normal sensors and suppress the rest so my HA install does not fill up with diagnostics. But if any of this is useful upstream, I can post raw captures / example values / decoded notes here. The fork branch I’m playing with is -Peace |
|
|
||
| /** | ||
| * LG Air Conditioner Model LW1823HRSM | ||
| * LG Window Air Conditioner (e.g. LW6023IVSM, LW1522IVSM) |
There was a problem hiding this comment.
Why this file is still here and even getting patched if this PR was to support WIN_056905_WW via RAC_056905_WW.ts?
maciejsszmigiero
left a comment
There was a problem hiding this comment.
I did a quick glance at these changes, left a few comments.
It looks like supporting these units through RAC_056905_WW may have some sense indeed.
These new capability bits still need cross-checking however.
@gonkey42 do you have the model JSON file from ThinQ API for your unit?
Some other RAC-ish fields that line up with the existing path / captures:
I don't quite understand that sentence - does it mean that these tags also contain values values for Win units? Do they have EEVs instead of fixed metering and export ODU temperatures?
| readable: false, | ||
| write_xform: (val) => (val === 'ON' ? 1 : 0), | ||
| /* 0x1f7 is not necessary for ON but does not seem to hurt either */ | ||
| /* Direct power ON uses the generic RAC attach behavior; WIN-family mode writes add 0x1f7 separately. */ |
There was a problem hiding this comment.
This comment should not get overwritten.
| 'sleeptimer', | ||
| 'Sleep timer', | ||
| 'mdi:bed-clock', | ||
| this.isWinFamily() ? 12 : 15, |
There was a problem hiding this comment.
What happens on Win family if sleep time is programmed to 15 hours?
| } | ||
|
|
||
| addTimerField(config: DeviceDiscovery, id: number, name: string, desc: string, icon: string, max: number) { | ||
| const step = this.isWinFamily() ? 1 : 0.25 |
There was a problem hiding this comment.
What happens on Win family if timers are programmed in 15 minute steps?
| fan_modes: ['auto', 'very low', 'low', 'medium', 'high', 'very high'], | ||
| /* TODO: get allowed op modes from 0x2c1 */ | ||
| } satisfies ClimateComponent, | ||
| min_temp: this.raw_clip_state[0x2e1] != null ? this.raw_clip_state[0x2e1] / 2 : 18, |
There was a problem hiding this comment.
That's definitely not a complete support for these temperature tags so the TODO comment should stay.
| config['components']['energysaver'] = allowExtendedType({ | ||
| platform: 'switch', | ||
| unique_id: '$deviceid-energysaver', | ||
| name: 'Energy Saver', |
There was a problem hiding this comment.
It might make more sense to export this as eco preset mode for the HA climate component instead of dedicated switch.
| write_xform: (val) => { | ||
| const modes2clip: Record<string, number> = { cool: 0, dry: 1, fan_only: 2, heat: 4, auto: 6 } | ||
| if (val === 'off') { | ||
| if (this.isWinFamily()) { |
There was a problem hiding this comment.
Why just using the existing RAC code for turning the power off is not enough for Win family?
| this.setProperty('climate-power', 'OFF') | ||
| return null | ||
| } | ||
| if (this.isWinFamily()) this.raw_clip_state[0x1f7] = 1 |
There was a problem hiding this comment.
Isn't attaching both temperature and fan speed to mode setting enough to power on this unit like on RAC? Note that it may need them sent in different order than RAC (the tag order sometimes matters here).
| } | ||
|
|
||
| this.setConfig(config) | ||
| this.publishKnownState() |
There was a problem hiding this comment.
Why this is necessary? RAC will send the current values response multiple times on query so if the initial response sets config the next ones will publish these values.
|
Independent validation and a new I tested an installed LW1224IVSM end-to-end against a fully local rethink deployment (stock Wi-Fi module, no LG app/account/cloud): appliance provisioning, MQTT discovery, telemetry, physical-control readback, and commands from Home Assistant. Identifying household data has been removed from the details below. Device details:
The Decoded capability differences versus the LW1022FVSM fixture in this PR include: The most important newly observed difference is the room-temperature scale:
Observed control mapping agrees with this PR: One synchronization detail: temperature changes were pushed asynchronously, but a physical panel/remote change from Energy Saver / 68 F to Cool / about 65 F was not accompanied by mode/setpoint TLVs. A full values query ( Sanitized capability response from the LW1224IVSM: Sanitized values response while in Energy Saver / 68 F / High: Sanitized queried values response after changing the physical controls to Cool / about 65 F / High: The Wi-Fi indicator on the appliance remained dark despite a stable local TLS/MQTT connection, strong RSSI, continuous telemetry, and successful commands. This appears cosmetic and may reflect LG-app/cloud registration state rather than actual Wi-Fi association. Happy to provide additional controlled captures or test a proposed capability-based temperature transform on the live unit. |
Summary
This draft follows the unified RAC direction from #73. It uses sanitized LW1022FVSM / WIN_056905_WW fixtures as regression coverage and only changes the shared RAC path for fixture-proven gaps. I also live-tested the patched RAC path locally against an installed LG LW1022FVSM reporting ThinQ model id
WIN_056905_WW, then restored my local runtime.WIN_056905_WWthroughRAC_056905_WW.WIN_056905_WWdifferences: capability-derived modes/fan modes/temperature limits, raw fan values2/4/6, raw mode8Energy Saver, power-off behavior, the tested off-to-fan-only write path, and manual whole-hour timer controls/readback with protocol-minute writes.Evidence Level
Fixture coverage plus live validation against an installed LG LW1022FVSM /
WIN_056905_WWthrough rethink, MQTT, and Home Assistant.Validation
node --import tsx --test --test-reporter=spec tests/cloud/devices/RAC_056905_WW.LW1022FVSM.test.tsnode --import tsx --test --test-reporter=spec tests/cloud/devices/RAC_056905_WW.test.ts tests/cloud/devices/RAC_056905_WW.LW1022FVSM.test.tsnpm run testnpm run buildnpm exec -- prettier . --check --ignore-path .gitignoregit diff --checkWIN_056905_WWthrough local rethink runtime, MQTT, and Home AssistantResult: LW1022FVSM RAC fixture test passed 18/18, RAC plus LW1022FVSM fixture tests passed 24/24, full suite passed 248/248, build passed, formatting passed, and diff whitespace check passed.
Live result: discovery, modes (
dry,fan_only,cool,off), fan speeds (low,medium,high), target temperature, Energy Saver, Sleep Timer, Turn-off Timer, Turn-on Timer, focused0x1f7A/B behavior, and rollback were tested through the live path. Manual-backed timer behavior is Sleep1hto12h, Turn-off1hto24hwhile running, and Turn-on1hto24hwhile off. Turn-on Timer is accepted/read back when the unit isoff; the unit ignores that command while already running.Focused
0x1f7A/B result: already-on Energy Saver mode writes worked with or without0x1f7=1; the tested off-to-fan-only mode write required0x1f7=1to power the unit on.Notes
WIN_056905_WW.off,cool,dry, andfan_only; fan modeslow,medium, andhigh; no heat or swing fields for the observed capability packet; Energy Saver represented by raw mode8; and Sleep / Turn-on / Turn-off timers exposed as whole-hour controls matching the owner's manual.off, a1hcommand was accepted, published back asstarttimer- 1, and the physical unit showed the timer; clearing it publishedstarttimer- 0.