Skip to content

jourdant/esphome-lgap

Repository files navigation

esphome-lgap

NOTE: This integration works with LG Outdoor Units (ODUs/inverters). If your ODU doesn't have an LGAP/Central Control interface or integration through a board such as the LG PI-485 board, or you're looking to integrate with the indoor wall panel controller instead, check out: JanM321/esphome-lg-controller.

esphome-lgap is an implementation of the LG Aircon Protocol (LGAP) implemented as an esphome component. This enables you to use an ESP8266/ESP32 to interface directly on the interface generally used for building management system integration/control of LG HVAC units.

One of the best benefits of using this integration is you can use a single LGAP interface on your outdoor unit (ODU) to drive multiple different indoor unit (IDU) zones.

homeassistant

homeassistant

homeassistant

homeassistant

Recent Updates (November 2025)

Temperature & Sensors

  • Fixed temperature calculation - Corrected current temperature formula to (192 - raw) / 3 for accurate readings
  • Immediate temperature updates - Temperatures now appear immediately in Home Assistant on startup (rate-limited thereafter)
  • Pipe temperature sensors - Auto-generated sensors for refrigerant inlet and outlet temperatures
  • Temperature limits enforcement - Heat mode: 16-30°C, other modes: 18-30°C (per LG spec)
  • Error code sensor - Exposes LG service error codes (0 = OK)

Load Monitoring (LonWorks Compatible)

  • Zone Active Load - Real-time dynamic load per zone (nvoLoadEstimate)
  • Zone Power State - ON/OFF state flag (nvoOnOff)
  • Zone Design Load - Fixed capacity/duct size index (nciRatedCapacity)
  • ODU Total Load - System-wide compressor load (nvoThermalLoad)

Sleep Timer

  • Persistent timer duration - User sets duration once (0-420 minutes), stays saved
  • Auto-start on power ON - Timer automatically starts countdown when AC turns ON
  • Timer remaining sensor - Real-time countdown display
  • Auto-shutoff - AC turns OFF when timer expires, duration stays saved for next use

Control Locks & Security

  • Control Lock - Master child lock (protocol TX4 bit2)
  • Temperature Lock - Prevent temperature changes
  • Fan Speed Lock - Prevent fan speed changes
  • Mode Lock - Prevent mode changes
  • Power Only Mode - Allow only ON/OFF, lock all other controls
  • Wall controller enforcement - Automatically reverts unauthorized changes made at physical wall controller when locks are active

Optional Features (Opt-In)

  • Plasma ion control - Air purification switch (protocol TX4 bit4) - supports_plasma: true
  • Auto swing mode - Auto airflow for ducted units - supports_auto_swing: true
  • Auto fan speed - Auto fan mode - supports_auto_fan: true
  • Quiet fan mode - Silent operation - supports_quiet_fan: true
  • Turbo fan mode - Maximum power - supports_turbo_fan: true

Quality of Life

  • Reduced log verbosity - Moved frequent messages to VERBOSE level for cleaner logs
  • Race condition fix - Fixed temperature change race condition with write_update_pending flag
  • Clean UI by default - All advanced features disabled by default, opt-in per zone
  • Auto-generated entities - All sensors, numbers, and switches auto-created with smart naming

⚠️ Configuration Requirements

If upgrading from an older version, ensure your YAML includes these base components (required for auto-generated entities):

sensor:
number:
switch:
button:

Features

  • Full Climate Control - Native Home Assistant climate entity with standard controls
  • Multi-Zone Support - Control multiple zones from single ODU interface
  • Advanced Sensors - Pipe temperatures, load monitoring, error codes
  • LonWorks Integration - Compatible with LG's commercial BMS protocol fields
  • Control Locks - Child lock, temperature lock, fan lock, mode lock, power-only mode
  • Sleep Timer - Automatic shutoff timer (0-420 minutes)
  • Wall Controller Enforcement - Reverts unauthorized changes made at physical controller when locks active
  • Optional Features - Plasma ion, auto swing, quiet/turbo fan modes (opt-in per zone)
  • Temperature Accuracy - Corrected LG protocol formulas for accurate readings
  • Smart Updates - Configurable temperature update intervals, immediate first reading

Table of Contents

Build intructions

Disclaimer

This whole exercise has been for my own personal learning and experimentation. There are aspects of integrating with high voltage equipment and looking into unpublished protocols. Attempting anything detailed here is at your own risk, may void the warranty of your unit or worse may result in physical harm.

I've tried to build this using the standard esphome external component method and make it as simple as possible to reference in your esphome configuration.

1. Device selection

I've tried a couple of ESP32-based devices with varying success. Below is a list of known tested devices.

Model Number Price Link Test result
M5Stack Atom Lite + ATOMIC RS485 Base $7.50 USD +
$9.95 USD
https://shop.m5stack.com/products/atom-lite-esp32-development-kit
https://shop.m5stack.com/products/atomic-rs485-base
Recommended
Lilygo T-RSC3 $17.98 USD https://www.lilygo.cc/products/t-rsc3 Onboard RS485 interface not compatible

2. Wiring

Refer to the disclaimer above.

On my ODU there are 4 internal pins right next to each other that specify 12V, GND, Central Control A & B. The great thing about the ATOMIC RS485 Base is that you can give it 12V and it will also power the ESP32. That makes the wiring really simple. I wire up each of those pins from the ODU to the pins on the RS485 interface and we're good to go.

img

PI-485 Expansion Board

For older LG ODUs that don't have onboard CEN_A/CEN_B pins, the PI-485 expansion board adds an LGAP interface. This has been tested and confirmed working (thanks to @tolkachev via PR #15).

PI-485 DIP Switch Settings:

Switch Position Purpose
1 ON Enable RS485 communication
2 OFF
3 OFF
4 ON Enable LGAP protocol mode
5 ON
6-8 OFF

Setup Steps:

  1. Set IDU addresses — Each indoor unit must have a unique address set via the wired remote/thermostat. Without this, the PI-485 won't detect the units.
  2. Check the red LED — On PI-485 boot, the red LED blinks once per detected indoor unit. If it doesn't blink, your IDU addresses aren't set.
  3. Wire A to A, B to B — Connect the PI-485 RS485 terminals to the ATOMIC RS485 Base. No need to swap A/B. Termination resistors (120 Ohm) are not required.
  4. Set tx_byte_0: 0x80 in your YAML config (this is the default value in the current code). The PI-485 requires this specific first byte to respond.
  5. Check the green LED — Once ESPHome is running, the green LED should blink indicating RS485 data activity. If it doesn't blink, the PI-485 isn't processing requests.

Confirmed working hardware:

  • ODU: FM40AH UH0 (AGUW406FAO) + 4 IDU
  • Multi-F systems with PI-485
  • M5Stack Atom Lite + ATOMIC RS485 Base

Note: The PI-485 can also be powered from the ODU's 12V pins, same as the direct CEN_A/CEN_B wiring method.

3. Esphome manifest

I am making the assumption that you're also using the M5Stack devices as listed above, here is some sample yaml you can add to an existing yaml config.

💡 TIP: Ready-to-use configuration examples:

external_components:
  - source:
      type: git
      url: https://github.com/mystardious/esphome-lgap  # or jourdant/esphome-lgap
      ref: main
    components: [ "lgap"]
    refresh: 0sec

uart:
  id: lgap_uart1
  tx_pin:
    number: GPIO19
  rx_pin:
    number: GPIO22
  baud_rate: 4800
  data_bits: 8
  stop_bits: 1
  parity: NONE

# Required for auto-generated entities
sensor:
number:
switch:
button:

lgap:
  - id: lgap1
    uart_id: lgap_uart1
    receive_wait_time: 250ms   # Response timeout (default: 500ms, increase to 1000ms if unreliable)
    loop_wait_time: 100ms      # Polling interval (default: 500ms, reduce for faster updates)
    tx_byte_0: 0x80            # Frame header byte (default: 0x80)

climate:
  - platform: lgap
    id: lg_zone_0
    name: "Mohamed Ali Room"
    lgap_id: lgap1
    zone: 5

  - platform: lgap
    id: lg_zone_1
    name: "Cinema Room"
    lgap_id: lgap1
    zone: 1

  - platform: lgap
    id: lg_zone_2
    name: "Living Room A"
    lgap_id: lgap1
    zone: 2

  - platform: lgap
    id: lg_zone_3
    name: "Living Room B"
    lgap_id: lgap1
    zone: 3

  - platform: lgap
    id: lg_zone_4
    name: "Hadi Room"
    lgap_id: lgap1
    zone: 4

Timing Configuration Notes:

  • If you experience communication issues or timeouts, try increasing receive_wait_time to 1000ms
  • The loop_wait_time can be adjusted based on your needs:
    • Lower values (50-100ms) = faster updates, more protocol traffic
    • Higher values (500-1000ms) = slower updates, reduced load
  • Most setups work well with the defaults shown above

If you want to add extra zones, you can reference the same lgap_id on the climate component. It is also possible to have multiple LGAP protocol components using different UART components in the same configuration.

Advanced Features

The LGAP component supports many advanced features that can be optionally enabled per zone. All features are disabled by default for a clean, minimal interface.

Available Configuration Options

climate:
  - platform: lgap
    id: lgap_zone_cinema
    name: 'Cinema Room'
    lgap_id: lgap1
    zone: 2
    
    # Optional: Temperature update rate (default: 300000ms / 5 minutes)
    temperature_publish_time: 300000ms
    
    # Optional: Enable auto airflow mode for ducted units (default: false)
    # Shows "Swing Set: Off or Vertical" in Home Assistant
    supports_auto_swing: true
    
    # Optional: Enable auto fan speed mode (default: false)
    # Adds "Auto" to fan speed options alongside Low/Medium/High
    supports_auto_fan: true
    
    # Optional: Enable quiet/slow fan mode (default: false)
    # Adds "Quiet" fan speed option for silent operation
    supports_quiet_fan: true
    
    # Optional: Enable turbo/power fan mode (default: false)
    # Adds "Focus" fan speed option for maximum cooling/heating
    supports_turbo_fan: true
    
    # Optional: Enable plasma ion air purification control (default: false)
    # Creates a switch entity to control plasma ion feature
    supports_plasma: true

Auto-Generated Sensors

The component automatically creates the following sensors for each zone:

  • Pipe In Temperature - Refrigerant pipe inlet temperature (°C)
  • Pipe Out Temperature - Refrigerant pipe outlet temperature (°C)
  • Error Code - Service error codes (0 = OK)
  • Zone Active Load - Real-time dynamic load index (LonWorks nvoLoadEstimate)
  • Zone Power State - Zone on/off state flag (LonWorks nvoOnOff)
  • Zone Design Load - Fixed design capacity index (LonWorks nciRatedCapacity)
  • ODU Total Load - Total outdoor unit load across all zones (LonWorks nvoThermalLoad)

Auto-Generated Controls

Each zone automatically includes:

  • Sleep Timer - Number input (0-420 minutes, 0 disables timer)
  • Timer Remaining - Countdown sensor showing minutes until auto-shutoff
  • Control Lock - Master lock switch (child lock)
  • Lock Temperature - Prevent temperature changes
  • Lock Fan Speed - Prevent fan speed changes
  • Lock Mode - Prevent mode changes
  • Power Only Mode - Allow only ON/OFF, lock all other controls
  • Plasma - Control plasma ion air purification (only if supports_plasma: true)

Lock Enforcement

All lock switches enforce restrictions both from Home Assistant and from physical wall controller changes. If a user attempts to change a locked parameter at the wall controller, the system will automatically revert the change.

Temperature Limits

The component enforces LG protocol temperature limits:

  • Heat mode: 16-30°C
  • All other modes (Cool/Dry/Fan/Auto): 18-30°C

Example: Full-Featured Configuration

climate:
  - platform: lgap
    id: bedroom
    name: 'Master Bedroom'
    lgap_id: lgap1
    zone: 3
    supports_quiet_fan: true      # Enable quiet mode for night
    supports_plasma: true         # Enable air purification
    
  - platform: lgap
    id: living_room
    name: 'Living Room'
    lgap_id: lgap1
    zone: 4
    supports_auto_swing: true     # Ducted unit with auto airflow
    supports_auto_fan: true       # Enable auto fan speed
    supports_turbo_fan: true      # Enable power cooling/heating
    supports_plasma: true         # Enable air purification

Example: Minimal Configuration

climate:
  - platform: lgap
    id: office
    name: 'Home Office'
    lgap_id: lgap1
    zone: 5
    # Uses defaults: Low/Medium/High fan only, no swing, no plasma
    # Still gets all sensors and lock controls automatically

Troubleshooting

Temperatures not appearing immediately in Home Assistant

The component implements rate-limiting for temperature updates (default: 5 minutes) to reduce protocol overhead. However, the first reading is always published immediately. If temperatures aren't appearing:

  1. Check ESPHome logs for "Processing climate message" entries
  2. Verify zone number matches your LG indoor unit configuration
  3. Adjust temperature_publish_time if you need more frequent updates

Lock switches not preventing changes

Lock enforcement works in two stages:

  1. Home Assistant requests are blocked immediately with a warning log
  2. Wall controller changes are detected and reverted automatically

Check ESPHome logs for messages like "Temperature change blocked - temperature lock is active" or "Mode changed at wall controller while lock active - reverting".

Fan modes not appearing

Fan modes are now opt-in:

  • Default: Low, Medium, High only
  • Auto: Requires supports_auto_fan: true
  • Quiet: Requires supports_quiet_fan: true
  • Turbo/Focus: Requires supports_turbo_fan: true

This ensures a clean UI for units that don't support advanced fan modes.

Swing control not appearing

Swing control is disabled by default. For ducted units with auto airflow capability, add:

supports_auto_swing: true

This will add "Off" and "Vertical" swing options to Home Assistant.

Error code sensor showing non-zero value

Error codes are LG service codes. Common meanings:

  • 0 = No error (normal operation)
  • Non-zero values indicate service alerts or error conditions

Refer to your LG service manual for specific error code meanings, or check the ODU display panel.

Climate Action Inference

Home Assistant allows current action of climate devices to be reported. This shows up in the climate card as something like "Heating to 24°C" or "Idle" etc. I haven't found in the LGAP protocol whether the compressor or heating element is actively running. This component infers the current action based on the operating mode and temperature comparison:

Mode Reported Action
Off OFF
Cool COOLING if current temp > target temp, otherwise IDLE
Heat HEATING if current temp < target temp, otherwise IDLE
Heat/Cool (Auto) COOLING if current > target, HEATING if current < target, otherwise IDLE
Dry DRYING (always, when active)
Fan Only FAN (always, when active)

Note: This is an approximation. The actual compressor state may differ due to factors like defrost cycles, minimum run times, or thermostat deadbands within the unit. If you discover a byte in the LGAP protocol that indicates actual compressor status, please open an issue or PR!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors