Skip to content

[codex] Add LG power consumption sensors - #170

Open
joeblack2k wants to merge 2 commits into
JanM321:mainfrom
joeblack2k:codex/power-consumption-sensors
Open

[codex] Add LG power consumption sensors#170
joeblack2k wants to merge 2 commits into
JanM321:mainfrom
joeblack2k:codex/power-consumption-sensors

Conversation

@joeblack2k

@joeblack2k joeblack2k commented May 31, 2026

Copy link
Copy Markdown

Summary

Adds optional passive Home Assistant sensors for LG units that publish wired-controller power frames:

  • power_consumption: total energy from type 0xCC / 0xAC / 0x2C messages, published in kWh.
  • current_power: instantaneous power from type 0xCF / 0xAF / 0x2F messages, published in kW.

These sensors are intentionally opt-in. The bundled base.yaml no longer exposes them by default because several units, including my live test unit, expose energy in ThinQ/WiFi but do not send the matching wired-controller frames.

Fix Log

  • Investigated issue Current power consumption #3 and the existing protocol notes for types 0xC and 0xF.
  • Confirmed from the issue discussion that supported units are expected to send these frames periodically; there is no known request/poll command for units that do not emit them.
  • Added optional ESPHome config entries so custom YAML files can opt in without making existing configs incompatible.
  • Kept power_consumption as kWh with total_increasing state class.
  • Changed current_power to kW with one decimal place, matching the examples currently documented in protocol.md.
  • Removed the power sensors from public base.yaml defaults so unsupported units do not get dead entities.
  • Reused the same LG nibble decoder for both fields. This deliberately is not strict BCD because the documented 0xCF examples include A-F nibbles.
  • Restricted publishing to messages sent by the unit, matching the existing handling of status frames.
  • Documented that ThinQ/WiFi energy support does not guarantee that 0xCC or 0xCF frames appear on the wired-controller bus.

Live Test Notes

Tested against an LG wall-mounted A/C model S3-M12JA2DA with modem firmware clip_hna_v1.9.229_RT.

On that unit, ThinQ reports energy data, but ESPHome wired-bus logs did not show 0xCC or 0xCF frames during our test window. The new sensors therefore do not update on this unit, which matches the current upstream understanding from #3: if the indoor unit never emits these frames, this controller cannot currently request them.

Validation

  • git diff --check
  • uvx esphome config template.yaml using a scratch copy with valid local placeholder values and the optional power sensors enabled
  • uvx esphome compile template.yaml using the same scratch copy; build completed successfully

Addresses #3 for units that emit the documented wired-bus power frames.

@joeblack2k
joeblack2k marked this pull request as ready for review June 7, 2026 20:20
@Comodore125

Copy link
Copy Markdown

what unit do you have?

@joeblack2k

Copy link
Copy Markdown
Author

The live unit I tested with is an LG wall-mounted A/C model S3-M12JA2DA (modem firmware clip_hna_v1.9.229_RT).

Important caveat from that test: ThinQ does show energy data for this unit, but the wired-controller bus logs did not show 0xCC or 0xCF frames during our test window. So this PR will not make power data appear on that model unless the unit actually emits those frames.

I updated the PR accordingly:

  • current_power is now exposed as kW, matching the current protocol.md examples.
  • The sensors are opt-in only and no longer included in base.yaml by default.
  • The README and PR body now document that ThinQ/WiFi energy support does not necessarily mean the wired-controller bus exposes the same data.

@WDeenik WDeenik left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I can confirm that this code works on my units (PM07SK.NSA).

There's something to be said about the accuracy of the numbers though, which might have something to do with how to translate what is reported by the units to decimal.

Reported current power is nowhere near the jump I see in power use of my whole house when I turn one of the units on (150-200W reported while I see a jump of ~400W, for instance). The lack of accuracy is all on LG probably, but it might be good to say something about it in documentation. Actually, it looks like interpreting the data in the messages as hexadecimal integers gives the exact same numbers as I see in ThinQ, which is much closer to the power draw I see.

Also the total power consumption does not align with what I see in ThinQ. Currently it reports 00.02.EE, which translates to 35,4kWh using the method of this PR, while ThinQ reports 61.6kWh.

),
cv.Optional(CONF_CURRENT_POWER): sensor.sensor_schema(
unit_of_measurement=UNIT_KILOWATT,
accuracy_decimals=1,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The protocol reports this in 3 decimal accuracy, so better to set it to 3 decimals.

}
}

static float decode_power_nibbles_(const uint8_t* buffer, size_t offset, size_t length, float divisor) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nitpick: the trailing underscore does not align with other naming conventions in this file.

Comment on lines +1288 to +1296
static float decode_power_nibbles_(const uint8_t* buffer, size_t offset, size_t length, float divisor) {
// Power payloads use LG's nibble format rather than binary integers. Some documented
// current-power examples contain A-F nibbles, so this intentionally is not strict BCD.
uint32_t result = 0;
for (size_t i = 0; i < length; i++) {
result = result * 100 + ((buffer[offset + i] >> 4) & 0xF) * 10 + (buffer[offset + i] & 0xF);
}
return result / divisor;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

So I'm not quite sure if this is actually how these numbers should be interpreted. The current implementation leads to a power consumption sensor that rolls back every now and then on my units, whenever the trailing nibble goes from F to 0. It might also happen for the other nibbles but I haven't seen those roll over from F to 0 yet.

It surely seems like the numbers in the protocol act like normal hexidecimal numbers, i.e. 00.02.DF becomes 00.02.E0 when 1 is added. However, interpreting it as a normal hexadecimal number gives very different results from what is reported in protocol.md.

Here's the moment it rolled over from 33.5 to 33.0, which probably corresponded with 00.02.CF to 00.02.D0. Didn't catch it live in the logs yet, but I'm trying to see it happen there as well.
Image

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The other option is that the numbers should still be interpreted this way, but the implementation of it by LG in my units is flawed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I just discovered that interpreting the reported current power as hexadecimal gives me the exact same numbers as ThinQ reports (in watts), so at least for current power on my units that seems to be the way. ThinQ shows at what moment it retrieved the power use, so I can align it exactly with what was logged. Example:

At the moment that ThinQ retrieved a power use of 0.55kW, my logs show this message: CF.02.00.02.29.00.04.52.00.00.00.00.07. Hex 229 translates to 553 decimal.

That still leaves the question if that's also the case for total power usage. Interpretating 00.02.EE as hex gives 750, and I have no idea how to translate that to the 61.6 kWh ThinQ reports. I'll keep tabs on different values over time to see if I can find some logic there.

@joeblack2k joeblack2k Aug 3, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I think the encoding can now be determined with fairly high confidence. Both values appear to be normal unsigned 24-bit big-endian binary integers, rather than LG’s nibble-decimal format.

For current power:

00 02 29 = 0x0229 = 553 W, which matches ThinQ.

For accumulated energy, the counter probably has a resolution of 0.1 kWh:

00 02 EE = 0x02EE = 750 → 75.0 kWh

This also explains and fixes the observed rollback:

  • 00 02 CF = 0x02CF = 719 → 71.9 kWh
  • 00 02 D0 = 0x02D0 = 720 → 72.0 kWh

With the current nibble-based decoder, those values incorrectly become 33.5 and 33.0 kWh.

The difference between the resulting 75.0 kWh and ThinQ’s 61.6 kWh is therefore probably not an encoding issue. It looks more like a difference in scope or reset point.

Since these are multisplit indoor units, the CC value may represent the total consumption of the complete system, while ThinQ allocates consumption to each indoor unit separately. It would be useful to check whether the ThinQ consumption of the other indoor unit or units adds up to 13.4 kWh:

61.6 + 13.4 = 75.0 kWh

Alternatively, ThinQ may show consumption since a monthly/app reset, while the wired-bus counter uses a different starting point.

There is another interesting clue in the same CF frame:

CF.02.00.02.29.00.04.52.00.00.00.00.07

  • 00 02 29 = 0x0229 = 553 W
  • 00 04 52 = 0x0452 = 1106 W

1106 W is exactly twice 553 W. This may be a second system-wide power field, while the first field is allocated to the individual indoor unit, although more captures are needed to confirm that.

My suggested decoding would therefore be:

  • CF, bytes 2–4: unsigned 24-bit big-endian value in watts
  • CC, bytes 3–5: unsigned 24-bit big-endian value in 0.1 kWh

It would be useful to monitor the deltas as well. For example, 00 02 EE → 00 02 EF should mean 75.0 → 75.1 kWh, and 00 02 FF → 00 03 00 should mean 76.7 → 76.8 kWh.

@WDeenik WDeenik Aug 3, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No the other unit has a total power consumption of 28.4kWh in ThinQ, so I don't think it's a total for the whole system. For that unit the message has a value of 00.01.66, which translates to 16.6kWh using the method of this PR, and 358 when interpreting it as a hex integer.

What did cross my mind was that this power consumption counter might be non-zero out of the factory because of unknown reasons, and it's just a different offset. I'm planning to collect some more values over time and see if it's a constant offset or not.

@WDeenik WDeenik Aug 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I have checked the values again, but there is no stable offset that makes the data I get from the unit itself match ThinQ's data.

My own conclusion is that the power consumption data is wildly inaccurate, both reported by the unit and by ThinQ. One of my units was on intermittently during the night yesterday. I checked it's power consumption through four ways:

  1. As reported by the unit itself
  2. Through ThinQ
  3. Using an integral sensor that uses the current power reported by the unit as input
  4. Subtracting a normal night's power usage of my whole home from yesterday night's power usage, as the only difference was the AC being on every now and then.

The results:

  1. 0.3kWh (regardless of which method was used to interpret the data, it went from 00 03 30 to 00 03 33)
  2. 0.0kWh
  3. 0.6kWh
  4. 0.63kWh

This shows that setting up an integral helper sensor on the current power sensor of the AC unit is very accurate, as it matches the increase in power consumption that the power meter of my house shows. I don't see any reason to use any data reported by LG, it's so far off that there's no point using it in my opinion.

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.

3 participants