devices.esphome.io
Lanbon L9 Smart Light Switch
Lanbon L9 Smart Light Switch
Device Type: switchElectrical Standard: usBoard: esp32Difficulty: Plug-n-flash, 2/5
Drivers
- Processor: ESP32-S3-WROOM-1U
- Touchscreen: FT6336U
- Display: ST7789V2
- mmWave Prescence: MoreSense 10G Hand Sweeping Series MS10-3007D26M4
- Power Sensor: HLW8012 (CF pin only)
GPIO Pinout
i80 Display
Pin | Function |
---|---|
GPIO17 | DC Pin |
GPIO21 | CS Pin |
GPIO13 | WR Pin |
GPIO18 | RD Pin |
GPIO6 | Data D0 |
GPIO7 | Data D1 |
GPIO15 | Data D2 |
GPIO16 | Data D3 |
GPIO10 | Data D4 |
GPIO9 | Data D5 |
GPIO46 | Data D6 |
GPIO3 | Data D7 |
I²C (used for touchscreen)
Pin | Function |
---|---|
GPIO0 | i2c SCL |
GPIO35 | i2c SCA |
General Purpose IO
Pin | Function |
---|---|
GPIO32 | LCD Backlight (output, ledc) |
GPIO36 | Load Relay (output, switch) |
GPIO5 | HLW8012 CF Pin (input, pulse_meter) |
GPIO11 | mmWave Proximity Sensor (input, binary_sensor) |
GPIO2 | mmWave Proximity Sensor (output, unknown) |
GPIO1 | mmWave Proximity Sensor (output, unknown) |
Note, programming the proximity sensor for different sensitivity, etc. is not yet possible.
How to Flash
- Open the switch, by removing the terminal covers and the 4 small screws on the cornors.
- The front part of hte switch should "pop off", with a small amount of pressure.
- Connect a USB level shifter to the pin header on the front panel, using the pinout below. Note, you must provide 5v power, while the Tx/Rx pins use a 3.3v level.
- Connect the GPIO0 pin to ground to put the ESP32 into the flash boot mode.
- Once flashed, the screen should power up and display ESPHome, while powered via the 5v supply.
Example Configuration
Below is a hardware only configuration, that enables the display with the ESPHome test card, along with the power meter, relay, and proximity sensor.
esphome: name: lanbon-l9 friendly_name: Lanbon L9
esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf
logger: level: DEBUG baud_rate: 115200 hardware_uart: UART0
api: encryption: key: !secret api_key
ota: - platform: esphome password: !secret ota_password
wifi: ssid: !secret wifi_ssid password: !secret wifi_password
psram: speed: 80MHz
output: - platform: ledc id: lcd_backlight_output pin: number: GPIO42 inverted: false
light: - platform: monochromatic output: lcd_backlight_output name: Display Backlight id: display_backlight restore_mode: ALWAYS_ON
spi: type: octal id: display_spi clk_pin: GPIO21 data_pins: - GPIO6 - GPIO7 - GPIO15 - GPIO16 - GPIO10 - GPIO9 - GPIO46 - GPIO3
display: - platform: mipi_spi id: my_display model: st7789v spi_id: display_spi bus_mode: octal dc_pin: GPIO17 dimensions: height: 320 width: 170 offset_height: 0 offset_width: 35 invert_colors: true show_test_card: true data_rate: 4MHz color_depth: 16BIT color_order: BGR auto_clear_enabled: false update_interval: 250ms
i2c: - id: touchscreen_i2c scl: number: GPIO0 ignore_strapping_warning: true sda: number: GPIO35
touchscreen: - platform: ft63x6 id: my_touchscreen display: my_display i2c_id: touchscreen_i2c calibration: x_min: 0 y_min: 0 x_max: 169 y_max: 319
sensor: - platform: pulse_meter name: Power id: power_pulse_meter pin: GPIO5 unit_of_measurement: 'W' device_class: power state_class: measurement internal_filter_mode: PULSE accuracy_decimals: 1 filters: - filter_out: nan - throttle: 15s - multiply: 0.0813287514318442 # Calibration may be needed
binary_sensor: - platform: gpio name: Proximity Sensor id: proximity_sensor pin: GPIO11
switch: - platform: gpio name: Relay id: relay pin: number: GPIO36
Detailed Configuration with LVGL
The following configuration implements the following features and examples from the LVGL component.
- Button with status update based on load relay gpio
- Screen time-out (backlight) and activation via touch or proximity
- Load power measurement via HLW8012
- Anti-burn
- Header icon showing API status
- Header label showing current time via SNTP
- Footer for page navigation
esphome: name: lanbon-l9 friendly_name: Lanbon L9
esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf
# Enable logginglogger: level: DEBUG baud_rate: 115200 hardware_uart: UART0
# Enable Home Assistant APIapi: encryption: key: !secret api_key reboot_timeout: 0s on_client_connected: - lvgl.label.update: id: label_apistatus text_color: 0x00FF00 on_client_disconnected: - lvgl.label.update: id: label_apistatus text_color: 0xFF0000
ota: - platform: esphome password: !secret ota_password
wifi: ssid: !secret wifi_ssid password: !secret wifi_password
psram: speed: 80MHz
time: - platform: sntp id: my_sntp timezone: America/New_York on_time: - hours: 23,4 minutes: 5 seconds: 0 then: - switch.turn_on: switch_antiburn - hours: 23,4 minutes: 35 seconds: 0 then: - switch.turn_off: switch_antiburn - seconds: 0 minutes: '*' then: - lvgl.label.update: id: label_time text: time_format: "%l:%M %p" time: my_sntp
output: - platform: ledc id: lcd_backlight_output pin: number: GPIO42 inverted: false
light: - platform: monochromatic output: lcd_backlight_output name: Display Backlight id: display_backlight restore_mode: ALWAYS_ON
spi: type: octal id: display_spi clk_pin: GPIO21 data_pins: - GPIO6 - GPIO7 - GPIO15 - GPIO16 - GPIO10 - GPIO9 - GPIO46 - GPIO3
display: - platform: mipi_spi id: my_display model: st7789v spi_id: display_spi bus_mode: octal dc_pin: GPIO17 dimensions: height: 320 width: 170 offset_height: 0 offset_width: 35 invert_colors: true show_test_card: false data_rate: 4MHz color_depth: 16BIT color_order: BGR auto_clear_enabled: false update_interval: 250ms
i2c: - id: touchscreen_i2c scl: number: GPIO0 ignore_strapping_warning: true sda: number: GPIO35
touchscreen: - platform: ft63x6 id: my_touchscreen display: my_display i2c_id: touchscreen_i2c calibration: x_min: 0 y_min: 0 x_max: 169 y_max: 319 on_release: - if: condition: lvgl.is_paused then: - if: condition: lvgl.is_paused then: - logger.log: "LVGL resuming due to screen touch." - lvgl.resume: - lvgl.widget.redraw: - light.turn_on: display_backlight
sensor: - platform: wifi_signal name: Wifi Signal update_interval: 60s entity_category: diagnostic
- platform: uptime name: Uptime entity_category: diagnostic
- platform: pulse_meter name: Power id: power_pulse_meter pin: GPIO5 unit_of_measurement: 'W' device_class: power state_class: measurement internal_filter_mode: PULSE accuracy_decimals: 1 filters: - filter_out: nan - throttle: 15s - multiply: 0.0813287514318442 # Calibration may be needed
binary_sensor: - platform: gpio name: Proximity Sensor id: proximity_sensor pin: GPIO11 on_press: then: - if: condition: lvgl.is_paused then: - logger.log: "LVGL resuming due to proximity sensor." - lvgl.resume: - lvgl.widget.redraw: - light.turn_on: display_backlight
switch: - platform: gpio name: Relay id: relay pin: number: GPIO36 on_turn_on: - lvgl.widget.update: id: light_switch state: checked: true - lvgl.label.update: id: label_light_switch text: "\U000F06E9" text_color: 0xFFEE00 on_turn_off: - lvgl.widget.update: id: light_switch state: checked: false - lvgl.label.update: id: label_light_switch text: "\U000F0336" text_color: 0xFFFFFF
- platform: template name: Antiburn id: switch_antiburn icon: mdi:television-shimmer optimistic: true entity_category: "config" turn_on_action: - logger.log: "Starting Antiburn" - if: condition: lvgl.is_paused then: - lvgl.resume: - lvgl.widget.redraw: - lvgl.pause: show_snow: true - light.turn_off: display_backlight turn_off_action: - logger.log: "Stopping Antiburn" - if: condition: lvgl.is_paused then: - lvgl.resume: - lvgl.widget.redraw:
font: - file: "https://github.com/Pictogrammers/pictogrammers.github.io/raw/refs/heads/main/@mdi/font/7.4.47/fonts/materialdesignicons-webfont.ttf" id: mdi_icons bpp: 4 size: 52 glyphs: [ "\U000F0336", "\U000F06E9" ]
lvgl: displays: - my_display touchscreens: - my_touchscreen buffer_size: 25% log_level: WARN on_idle: timeout: 30s then: - logger.log: "LVGL is idle" - light.turn_off: display_backlight - lvgl.pause: style_definitions: - id: header_footer bg_color: 0x2F8CD8 bg_grad_color: 0x005782 bg_grad_dir: VER bg_opa: COVER border_opa: TRANSP radius: 0 pad_all: 0 pad_row: 0 pad_column: 0 border_color: 0x0077b3 text_color: 0xFFFFFF width: 100% height: 30 top_layer: widgets: - obj: align: TOP_MID styles: header_footer widgets: - label: text: time_format: "%l:%M %p" time: my_sntp id: label_time align: CENTER text_align: CENTER text_color: 0xFFFFFF - label: text: "\uF1EB" id: label_apistatus align: top_right x: -2 y: 7 text_align: right text_color: 0xFFFFFF - buttonmatrix: align: bottom_mid styles: header_footer pad_all: 0 outline_width: 0 id: top_layer items: styles: header_footer rows: - buttons: - id: page_prev text: "\uF053" on_press: then: lvgl.page.previous: - id: page_home text: "\uF015" on_press: then: lvgl.page.show: page_light_switch - id: page_next text: "\uF054" on_press: then: lvgl.page.next: pages: - id: page_light_switch widgets: - button: x: 35 y: 60 width: 100 height: 200 id: light_switch checkable: true on_click: switch.toggle: relay widgets: - label: id: label_light_switch align: CENTER text: "\U000F0336" text_align: CENTER text_font: mdi_icons