Skip to content

Login + TimeSync endpoints changed in newer LG ESS firmware (PMS 10.05+) #37

Description

@blueleo076

Summary

Newer LG ESS Home firmware (PMS 10.05.x and above) has shortened the auth endpoints. The library still calls the old paths, so every login attempt to a current device fails with password mismatched (the ESS returns 404 for the old URL, which the client mis-interprets as a wrong password), and the time-sync step then loops. This issue describes the problem and proposes a fix.

Environment

  • Device: LG ESS Home 10 Hybrid inverter
  • Model: D010KE1N211
  • Serial: DE2112BKRE0078C5
  • Firmware:
    • PMS 10.05.7438
    • PCS LG 05.00.01.00
    • BMS 02.03.00.04
  • Library version tested: pyess 0.1.15 (also reproducible on 0.1.23)
  • Used by: dkarv/ha-lg-ess (Home Assistant integration)

Endpoint mismatch

Step pyess (old, hard-coded) Newer LG firmware actually exposes
Login (auth_key) PUT /v1/user/setting/login PUT /v1/login
Time sync PUT /v1/user/setting/timesync PUT /v1/timesync (returns 404 on this firmware — see note)

The old login path now returns 404 from the device. The client never sees a real password mismatched body, so the failure surfaces as wrong password in ESSAuthException, which is misleading — the password is fine.

The timesync path is a separate story: PUT /v1/timesync is not implemented on this PMS 10.05 build (returns 404). Time sync is harmless to skip on current firmware, but the library currently treats that 404 as a JSON-decode error and retries the whole login in a tight loop, which is what breaks long-running integrations (HA logs fill with sign invalid / repeated retries).

Reproduction

# 1. Direct check — what the firmware actually answers:
curl -i -k -X PUT 'https://<ess-ip>/v1/login' \
     -H 'Content-Type: application/json' \
     -d '{"password":"YOUR_PASSWORD"}'
# HTTP/1.1 200 OK  + {"auth_key":"...","status":"success"}

curl -i -k -X PUT 'https://<ess-ip>/v1/user/setting/login' \
     -H 'Content-Type: application/json' \
     -d '{"password":"YOUR_PASSWORD"}'
# HTTP/1.1 404 Not Found

# 2. From pyess, the same call produces:
# pyess.aio_ess.ESSAuthException: wrong password
# (root cause: the URL is wrong, not the password)

Where the URLs live in the code

pyess/constants.py:

PREFIX = "https://{}/"
LOGIN_URL = f"{PREFIX}v1/user/setting/login"
TIMESYNC_URL = f"{PREFIX}v1/user/setting/timesync"

pyess/aio_ess.py (line 50/63):

url = LOGIN_URL.format(self.ip)               # _login()
...
async with self.session.put(TIMESYNC_URL.format(self.ip), json=timesync_info) as r:

Proposed fix

Two changes, both small:

  1. Update the URL constants in pyess/constants.py to the new shorter paths:

    PREFIX = "https://{}/"
    LOGIN_URL = f"{PREFIX}v1/login"
    TIMESYNC_URL = f"{PREFIX}v1/timesync"
  2. Make time-sync tolerant in pyess/aio_ess.py _login(): if the timesync PUT returns 404 (or any non-2xx with a non-JSON body), treat it as "not supported on this firmware" and continue with self.auth_key = auth_key; self.logged_in = True. The login itself works fine without timesync on PMS 10.05+ — the device's own clock is good enough for the polling intervals the library uses.

Optionally, also normalise the error message: if LOGIN_URL returns 404, retry once with the legacy path (/v1/user/setting/login) before raising ESSAuthException("wrong password"). That way both old and new firmware keep working without forcing the user to pick a version.

Workaround in the meantime

Until a release is cut, I (and other HA users) are patching the installed copy with a sed hook in our HA image build, because the HA container image update otherwise silently overwrites the fix:

sed -i 's|v1/user/setting/login|v1/login|g' \
     /usr/src/homeassistant/homeassistant/components/lg_ess/pyess/constants.py
sed -i 's|v1/user/setting/timesync|v1/timesync|g' \
     /usr/src/homeassistant/homeassistant/components/lg_ess/pyess/constants.py

That's not a long-term solution — it gets clobbered on every image update — so an upstream fix in pyess would unblock everyone on current LG firmware.

Happy to send a PR with the changes above if useful; just let me know which fix shape you prefer (auto-fallback vs. just-point-at-new-URL).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions