Skip to content

WIN_056905_WW: Add LG Window AC support (LW6023IVSM, LW1522IVSM)#73

Open
Technickly90 wants to merge 1 commit into
anszom:masterfrom
Technickly90:add-win-056905-ww
Open

WIN_056905_WW: Add LG Window AC support (LW6023IVSM, LW1522IVSM)#73
Technickly90 wants to merge 1 commit into
anszom:masterfrom
Technickly90:add-win-056905-ww

Conversation

@Technickly90

Copy link
Copy Markdown

Summary

Implements full Home Assistant 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)

Features

  • HVAC modes: off, cool, dry, fan_only
  • Fan modes: low, medium, high
  • Eco / Energy Saver mode via HA preset_mode (wire value 8 on tag 0x1f9)
  • Sleep timer as a number entity (0–7 hours, slider UI)
  • Current temperature and target temperature

Protocol findings (from live packet captures)

Tag Description Wire values
0x1f7 Power 0=off, 1=on
0x1f9 Mode 0=cool, 1=dry, 2=fan_only, 8=eco/Energy Saver
0x1fa Fan speed 2=low, 4=medium, 6=high
0x1fd Current temperature raw/2 = °C
0x1fe Set temperature raw/2 = °C (clamped 16–30°C on write)
0x21a Sleep timer raw value in minutes

Key difference from RAC/POT: Frame discriminator is buf[6]=0xa7 instead of 0x87. One-line fix in tlv_device.ts to accept both variants.

Design notes

  • Eco mode (wire value 8) is exposed as a preset_mode rather than an hvac_mode, since HA only accepts standard HVAC mode values. When eco is active the hvac_mode reports as cool and preset_mode reports as eco.
  • Power-off is handled by writing tag 0x1f7 directly rather than through the mode tag.
  • Sleep timer is exposed in hours to match the RAC pattern; the write transform converts to minutes for the wire.

Tests

Unit test added at tests/cloud/devices/WIN_056905_WW.test.ts using real captured packet data. All 183 tests pass.

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>
@Technickly90

Copy link
Copy Markdown
Author

Heads up: potential conflict with LW1823HRSM

After submitting I noticed the original WIN_056905_WW.ts was written for the LW1823HRSM, which has a different feature set than my units. Since both appear to report as WIN_056905_WW, this PR as-is would break LW1823HRSM support.

Key differences:

Feature LW1823HRSM (original) LW6023/LW1522IVSM (this PR)
Heat mode
Swing
Medium fan
Eco/Energy Saver preset
Dry mode

Happy to split these into two separate files with aliases in ha_bridge.ts if that's the preferred approach, or follow whatever pattern the maintainer prefers. Let me know how you'd like to handle it.

@Technickly90

Copy link
Copy Markdown
Author

Related discussion with full setup notes (Synology/Docker/DNS/pairing process): #74

@anszom

anszom commented Jun 14, 2026

Copy link
Copy Markdown
Owner

My guess is that the underlying principle is similar to what we have observed for RAC_056905_WW, the AC reports some capability bits that can be used to determine which features are available. @maciejsszmigiero has found some way to decode these, maybe his findings would be applicable here.

Actually, from what I can see, the TLV identifiers in your commit match RAC_056905_WW perfectly - can you try running the RAC_056905_WW integration for your device (simply map WIN_056905_WW: RAC_056905_WW) - maybe it would "just work" ?

@Technickly90

Technickly90 commented Jun 14, 2026

Copy link
Copy Markdown
Author

Note: this is my first foray into claude code, so it is kind of just chugging along lol, sorry if it all sounds really robotic.

Looking at this more carefully, merging WIN into RAC makes more sense than the other direction. RAC already has the right architecture — caps detection, dynamic feature enable/disable, filter management, ODU sensors — and WIN would inherit all of that correctly, since its caps bits (0x2cc=0, 0x2cd=0) already zero out the unsupported features.

The differences between WIN and RAC are narrow and parameterizable:

  1. Fan value table — WIN uses wire values 2/4/6 (low/medium/high), RAC uses 2/3/4/5/6/8
  2. Mode table — WIN has eco/Energy Saver at index 8 on tag 0x1f9, RAC's table tops out at index 6
  3. Frame discriminator0xa7 vs 0x87 (already handled in tlv_device.ts)
  4. Min temp — WIN supports 16°C, RAC hardcodes 18°C
  5. Sleep timer — WIN doesn't set 0x2d3 bit 1 in caps, but tag 0x21a is confirmed working

A WIN subclass of RAC that overrides the fan/mode tables and sleep timer detection would get all of RAC's infrastructure for free. Would that be the preferred pattern here, or would you rather see a single merged file with conditional value tables? Happy to rework the PR whichever way fits best.

@maciejsszmigiero

Copy link
Copy Markdown
Collaborator

WIN supports 16°C, RAC hardcodes 18°C

AFAIK some RAC models also support 16°C for heating - this can be autodetected via tags 0x2e1 - 0x2ec at least on RAC, at least on some models.

Sleep timer — WIN doesn't set 0x2d3 bit 1 in caps, but tag 0x21a is confirmed working

Does setting sleep timer makes WIN enable ultra-low fan speed and makes the AC automatically bump set temperature by 2 Celsius after 1 hour? If not then this is not a sleep timer, this is turn-off timer.

RAC already has the right architecture — caps detection, dynamic feature enable/disable, filter management, ODU sensors

Does RAC filter management actually work on WIN? Do you see the filter usage counter increasing?


Do you see other RAC parameters being correct on WIN? I'm especially asking about the reverse engineered ones - nominal capacity, EEV opening, pipe and ODU temperature sensors.

@anszom

anszom commented Jun 14, 2026

Copy link
Copy Markdown
Owner

A WIN subclass of RAC that overrides the fan/mode tables and sleep timer detection would get all of RAC's infrastructure for free. Would that be the preferred pattern here, or would you rather see a single merged file with conditional value tables? Happy to rework the PR whichever way fits best.

My hunch is that RAC & WIN are essentially the same device, and we can extend the RAC implementation to cover both, if we implement all the capability flags correctly. This would be the preferred direction.

@Technickly90

Technickly90 commented Jun 14, 2026

Copy link
Copy Markdown
Author

Does setting sleep timer makes WIN enable ultra-low fan speed and makes the AC automatically bump set temperature by 2 Celsius after 1 hour? If not then this is not a sleep timer, this is turn-off timer.

It does both, it sets it to ultra low fan speed and bump the temp, but also turns off the unit after the timer ends

Does RAC filter management actually work on WIN? Do you see the filter usage counter increasing?

This is not showing in the WIN driver, would have to test

Do you see other RAC parameters being correct on WIN? I'm especially asking about the reverse engineered ones - nominal capacity, EEV opening, pipe and ODU temperature sensors.

Here are RAC related sensors:

Several RAC sensors DO appear in the WIN values response. Here's what's meaningful and what isn't:

Present and likely correct:

  • 0x2b3 = 183 → power consumption: 183 - 60 = 123W — very plausible for a running 6k BTU inverter AC ✓
  • 0x22a/0x32f = 15 → compressor Hz — makes sense, inverter window ACs have variable-frequency compressors ✓
  • 0x32c = 162 → labeled "ODU HEX temp" in RAC, but on a window unit this would be the condenser coil temperature — physically real, just different meaning
  • 0x332 = 133 → labeled "ODU air temp" in RAC, on a window unit this is likely condenser intake air temp — also physically real
  • 0x32e = 12 → nominal capacity — might be in units of 500 BTU (12 × 500 = 6,000 BTU matching the LW6023IVSM), or kBTU for the 14k unit
  • 0x221 = 0 → error code, no error ✓

Present but misleading:

  • 0x330 = 0 → EEV opening — window ACs use capillary tubes, not electronic expansion valves, so this will always be 0. RAC would add it as a sensor since 0 != null, but
    it would be a permanently useless entity.

Not present at all (as expected):

  • 0x2f9, 0x2fa → pipe liquid/gas temps — absent, makes sense since there are no refrigerant lines to an outdoor unit.

So most of the RAC sensors carry over meaningfully, with the RAC's addOptionalSensorField pattern naturally handling the pipe temps by simply not adding them. The only
one to watch out for is EEV showing as a stuck-at-0 entity.

@maciejsszmigiero

maciejsszmigiero commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

0x32c = 162 → labeled "ODU HEX temp"

~ 33 C so plausible with the unit running in summer.

0x332 = 133 → labeled "ODU air temp"

~ 23 C so also plausible in summer.

But these probably need more testing, like whether these temperatures match each other once the unit has been idle for some time, whether they match during lower temperatures in the night, etc.

0x32e = 12 → nominal capacity

If that's 6 kBTU / hour unit then the value in this tag is wrong.

@Technickly90

Copy link
Copy Markdown
Author

0x32c = 162 → labeled "ODU HEX temp"

~ 33 C so plausible with the unit running in summer.

0x332 = 133 → labeled "ODU air temp"

~ 23 C so also plausible in summer.

But these probably need more testing, like whether these temperatures match each other once the unit has been idle for some time, whether they match during lower temperatures in the night, etc.

0x32e = 12 → nominal capacity

If that's 6 kBTU / hour unit then the value in this tag is wrong.

I'll have to do more testing, I have two 14k BTU units and a single 6k unit connected currently so i'll have to distinguish between them or try exposing them to HA for easier viewing/labeling. It is about 92F outside here so my house is sitting around 75-80F. I'll also have to try adding these units locally again vs. the official app method and see if I can narrow down where the pairing fails.

@maciejsszmigiero

Copy link
Copy Markdown
Collaborator

92F outside

So it's 33 C then.

The 23 C alleged outside air temperature looks a bit suspicious in these conditions.
Unless the AC unit is in a deep shade but that 92 F / 33 C was measured in a sun-lit place.

@gonkey42

Copy link
Copy Markdown

I’m following the WIN_056905_WW work here and have another tested datapoint that may help the capability-driven RAC/WIN direction discussed above.

I have an LG LW1022IVSM that also reports WIN_056905_WW. I collected sanitized TLV capability/value/write fixtures and local tests. This unit did not advertise heat or swing in its capability packet, but it did advertise dry, medium fan, Energy Saver, and Sleep/Turn-on/Turn-off timers.

I don’t want to create extra review churn or open a parallel implementation if you’d rather centralize the data here. Would it be most useful for me to share the sanitized fixtures/test expectations in this thread, open a small draft PR referencing this PR, or wait and adapt after the RAC/WIN shape is decided? I’m happy to follow whatever path is easiest to review.

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.

4 participants