Add a second ESPHome fleet display that shares the existing printer pages.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -84,17 +84,22 @@ printer rotation are outside its current scope.
|
||||
|
||||
## Install
|
||||
|
||||
1. Keep `esphome/bambu-printer-display.yaml` and the entire `bambu-display/` folder
|
||||
together in the ESPHome configuration directory. The generated package is checked
|
||||
in, so the ESPHome dashboard can compile it without running the generator first.
|
||||
1. Keep both device files and the entire `bambu-display/` folder together in the
|
||||
ESPHome configuration directory. `bambu-printer-display.yaml` is the first board
|
||||
and `bambu-printer-display-2.yaml` is the second. They share `board.yaml` and the
|
||||
generated fleet package, which is checked in, so the ESPHome dashboard can compile
|
||||
either file without running the generator first.
|
||||
2. Supply the existing `api_encryption_key`, `wifi_iot_ssid` and `wifi_password`
|
||||
entries in that directory's `secrets.yaml`.
|
||||
3. Use ESPHome **2026.9.0 or newer**. Compile and install
|
||||
`bambu-printer-display.yaml` over the board's USB-to-UART bridge for the first
|
||||
flash; subsequent installs can use encrypted OTA.
|
||||
4. Add **Bambu Printer Display** through Home Assistant's ESPHome integration using
|
||||
the same API encryption key. The display only subscribes to entities, so it does
|
||||
not require permission to perform Home Assistant actions.
|
||||
3. Use ESPHome **2026.9.0 or newer**. Compile and install the matching device file
|
||||
over that board's USB-to-UART bridge for the first flash; subsequent installs can
|
||||
use encrypted OTA. Flash `bambu-printer-display.yaml` to the first panel and
|
||||
`bambu-printer-display-2.yaml` to the second. Each file has its own ESPHome name,
|
||||
so both panels can be online together.
|
||||
4. Add **Bambu Printer Display** or **Bambu Printer Display 2** through Home
|
||||
Assistant's ESPHome integration using the same API encryption key. Each display
|
||||
only subscribes to entities, so it does not require permission to perform Home
|
||||
Assistant actions.
|
||||
5. Confirm all pages receive data and verify touch direction and color order on the
|
||||
physical panel. Entity IDs match the repository's `ha-entities.txt` snapshot;
|
||||
renamed or disabled entities in live HA must be corrected/enabled there.
|
||||
@@ -103,7 +108,7 @@ The USB D+/D− GPIO19/20 pins are used by the board's touch bus. Logging theref
|
||||
uses UART0. ESPHome may still warn about these two pins; they are intentional for
|
||||
this board. If GT911 is not found at `0x5D`, inspect the I²C scan and use its reported
|
||||
address (some hardware revisions select `0x14`). Backlight is GPIO2; RGB data pins
|
||||
and timings are explicit in the main YAML rather than borrowed from a 5″ board.
|
||||
and timings are explicit in `board.yaml` rather than borrowed from a 5″ board.
|
||||
|
||||
The display and LVGL both use **big-endian RGB565**. With `mipi_rgb`'s named
|
||||
`red`/`green`/`blue` pin groups, its generated bus pin map already exchanges the
|
||||
@@ -121,7 +126,9 @@ CLI checks from the repository root:
|
||||
|
||||
```sh
|
||||
esphome config esphome/bambu-printer-display.yaml
|
||||
esphome config esphome/bambu-printer-display-2.yaml
|
||||
esphome compile esphome/bambu-printer-display.yaml
|
||||
esphome compile esphome/bambu-printer-display-2.yaml
|
||||
```
|
||||
|
||||
## Change or expand the fleet
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
# Shared Sunton ESP32-8048S043C board for every fleet display.
|
||||
# Device name and friendly name come from the top-level YAML substitutions.
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
friendly_name: ${friendly_name}
|
||||
min_version: 2026.9.0
|
||||
includes:
|
||||
- bambu-display/dashboard.h
|
||||
|
||||
esp32:
|
||||
board: esp32-s3-devkitc-1
|
||||
flash_size: 16MB
|
||||
flash_mode: dio
|
||||
cpu_frequency: 240MHz
|
||||
framework:
|
||||
type: esp-idf
|
||||
sdkconfig_options:
|
||||
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
|
||||
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y"
|
||||
CONFIG_SPIRAM_RODATA: "y"
|
||||
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
||||
logger:
|
||||
hardware_uart: UART0 # GPIO19/20 are the touch bus, not native USB.
|
||||
|
||||
api:
|
||||
id: ha_api
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_iot_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
i2c:
|
||||
id: touch_bus
|
||||
sda: GPIO19
|
||||
scl: GPIO20
|
||||
scan: true
|
||||
|
||||
display:
|
||||
- platform: mipi_rgb
|
||||
id: panel_display
|
||||
model: RPI
|
||||
dimensions: 800x480
|
||||
color_order: RGB
|
||||
# Named RGB data_pins are byte-swapped by mipi_rgb's pin mapping.
|
||||
# Send big-endian RGB565 pixels to match that wiring transformation.
|
||||
byte_order: big_endian
|
||||
de_pin: GPIO40
|
||||
hsync_pin: GPIO39
|
||||
vsync_pin: GPIO41
|
||||
pclk_pin: GPIO42
|
||||
pclk_inverted: true
|
||||
pclk_frequency: 16MHz
|
||||
hsync_front_porch: 8
|
||||
hsync_pulse_width: 4
|
||||
hsync_back_porch: 8
|
||||
vsync_front_porch: 8
|
||||
vsync_pulse_width: 4
|
||||
vsync_back_porch: 8
|
||||
data_pins:
|
||||
red: [GPIO45, GPIO48, GPIO47, GPIO21, GPIO14]
|
||||
green: [GPIO5, GPIO6, GPIO7, GPIO15, GPIO16, GPIO4]
|
||||
blue: [GPIO8, GPIO3, GPIO46, GPIO9, GPIO1]
|
||||
auto_clear_enabled: false
|
||||
update_interval: never
|
||||
|
||||
touchscreen:
|
||||
- platform: gt911
|
||||
id: panel_touch
|
||||
display: panel_display
|
||||
i2c_id: touch_bus
|
||||
address: 0x5D
|
||||
# Polling avoids the GT911 INT pin's boot/address-selection behaviour.
|
||||
update_interval: 20ms
|
||||
|
||||
output:
|
||||
- platform: ledc
|
||||
id: backlight_output
|
||||
pin: GPIO2
|
||||
|
||||
light:
|
||||
- platform: monochromatic
|
||||
id: panel_backlight
|
||||
name: Backlight
|
||||
output: backlight_output
|
||||
restore_mode: ALWAYS_ON
|
||||
default_transition_length: 0s
|
||||
|
||||
time:
|
||||
- platform: homeassistant
|
||||
id: ha_time
|
||||
timezone: America/New_York
|
||||
|
||||
lvgl:
|
||||
id: dashboard
|
||||
displays: [panel_display]
|
||||
touchscreens: [panel_touch]
|
||||
buffer_size: 12%
|
||||
color_depth: 16
|
||||
byte_order: big_endian # Must match mipi_rgb's named RGB pin mapping above.
|
||||
bg_color: 0x000000
|
||||
text_color: 0xEEEEEE
|
||||
default_font: montserrat_18
|
||||
@@ -123,7 +123,7 @@ class FleetTests(unittest.TestCase):
|
||||
pass
|
||||
for tag in ('!secret', '!include'):
|
||||
Loader.add_constructor(tag, lambda loader, node: loader.construct_scalar(node))
|
||||
config = yaml.load((HERE.parent / 'bambu-printer-display.yaml').read_text(), Loader=Loader)
|
||||
config = yaml.load((HERE / 'board.yaml').read_text(), Loader=Loader)
|
||||
display = config['display'][0]
|
||||
pins = display['data_pins']
|
||||
natural = pins['blue'] + pins['green'] + pins['red']
|
||||
@@ -135,6 +135,18 @@ class FleetTests(unittest.TestCase):
|
||||
for i, pin in enumerate(driver))
|
||||
self.assertEqual(panel_word, color, f'RGB565 color {color:#06x} is wired incorrectly')
|
||||
|
||||
def test_both_boards_share_one_hardware_package(self):
|
||||
class Loader(yaml.SafeLoader):
|
||||
pass
|
||||
Loader.add_constructor('!include', lambda loader, node: loader.construct_scalar(node))
|
||||
names = set()
|
||||
for filename in ('bambu-printer-display.yaml', 'bambu-printer-display-2.yaml'):
|
||||
config = yaml.load((HERE.parent / filename).read_text(), Loader=Loader)
|
||||
names.add(config['substitutions']['device_name'])
|
||||
self.assertEqual(config['packages']['board'], 'bambu-display/board.yaml')
|
||||
self.assertEqual(config['packages']['fleet'], 'bambu-display/generated.yaml')
|
||||
self.assertEqual(len(names), 2)
|
||||
|
||||
def test_diagnostic_color_page_is_skipped_during_normal_navigation(self):
|
||||
package = generate(self.printers)
|
||||
page = next(page for page in package['lvgl']['pages'] if page['id'] == 'color_test_page')
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Second Sunton ESP32-8048S043C fleet display. Same pages and hardware as
|
||||
# bambu-printer-display.yaml, with its own ESPHome name so both boards can
|
||||
# join Home Assistant. Edit bambu-display/printers.yaml, then run generate.py.
|
||||
substitutions:
|
||||
device_name: bambu-printer-display-2
|
||||
friendly_name: Bambu Printer Display 2
|
||||
|
||||
packages:
|
||||
board: !include bambu-display/board.yaml
|
||||
fleet: !include bambu-display/generated.yaml
|
||||
@@ -1,121 +1,10 @@
|
||||
# Sunton ESP32-8048S043C: 4.3" 800x480 RGB LCD + GT911 capacitive touch.
|
||||
# Edit bambu-display/printers.yaml, then run its generate.py to change the fleet.
|
||||
# The second board is bambu-printer-display-2.yaml; both include bambu-display/board.yaml.
|
||||
substitutions:
|
||||
device_name: bambu-printer-display
|
||||
friendly_name: Bambu Printer Display
|
||||
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
friendly_name: ${friendly_name}
|
||||
min_version: 2026.9.0
|
||||
includes:
|
||||
- bambu-display/dashboard.h
|
||||
|
||||
esp32:
|
||||
board: esp32-s3-devkitc-1
|
||||
flash_size: 16MB
|
||||
flash_mode: dio
|
||||
cpu_frequency: 240MHz
|
||||
framework:
|
||||
type: esp-idf
|
||||
sdkconfig_options:
|
||||
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
|
||||
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y"
|
||||
CONFIG_SPIRAM_RODATA: "y"
|
||||
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
||||
logger:
|
||||
hardware_uart: UART0 # GPIO19/20 are the touch bus, not native USB.
|
||||
|
||||
api:
|
||||
id: ha_api
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_iot_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
i2c:
|
||||
id: touch_bus
|
||||
sda: GPIO19
|
||||
scl: GPIO20
|
||||
scan: true
|
||||
|
||||
display:
|
||||
- platform: mipi_rgb
|
||||
id: panel_display
|
||||
model: RPI
|
||||
dimensions: 800x480
|
||||
color_order: RGB
|
||||
# Named RGB data_pins are byte-swapped by mipi_rgb's pin mapping.
|
||||
# Send big-endian RGB565 pixels to match that wiring transformation.
|
||||
byte_order: big_endian
|
||||
de_pin: GPIO40
|
||||
hsync_pin: GPIO39
|
||||
vsync_pin: GPIO41
|
||||
pclk_pin: GPIO42
|
||||
pclk_inverted: true
|
||||
pclk_frequency: 16MHz
|
||||
hsync_front_porch: 8
|
||||
hsync_pulse_width: 4
|
||||
hsync_back_porch: 8
|
||||
vsync_front_porch: 8
|
||||
vsync_pulse_width: 4
|
||||
vsync_back_porch: 8
|
||||
data_pins:
|
||||
red: [GPIO45, GPIO48, GPIO47, GPIO21, GPIO14]
|
||||
green: [GPIO5, GPIO6, GPIO7, GPIO15, GPIO16, GPIO4]
|
||||
blue: [GPIO8, GPIO3, GPIO46, GPIO9, GPIO1]
|
||||
auto_clear_enabled: false
|
||||
update_interval: never
|
||||
|
||||
touchscreen:
|
||||
- platform: gt911
|
||||
id: panel_touch
|
||||
display: panel_display
|
||||
i2c_id: touch_bus
|
||||
address: 0x5D
|
||||
# Polling avoids the GT911 INT pin's boot/address-selection behaviour.
|
||||
update_interval: 20ms
|
||||
|
||||
output:
|
||||
- platform: ledc
|
||||
id: backlight_output
|
||||
pin: GPIO2
|
||||
|
||||
light:
|
||||
- platform: monochromatic
|
||||
id: panel_backlight
|
||||
name: Backlight
|
||||
output: backlight_output
|
||||
restore_mode: ALWAYS_ON
|
||||
default_transition_length: 0s
|
||||
|
||||
time:
|
||||
- platform: homeassistant
|
||||
id: ha_time
|
||||
timezone: America/New_York
|
||||
|
||||
packages:
|
||||
board: !include bambu-display/board.yaml
|
||||
fleet: !include bambu-display/generated.yaml
|
||||
|
||||
lvgl:
|
||||
id: dashboard
|
||||
displays: [panel_display]
|
||||
touchscreens: [panel_touch]
|
||||
buffer_size: 12%
|
||||
color_depth: 16
|
||||
byte_order: big_endian # Must match mipi_rgb's named RGB pin mapping above.
|
||||
bg_color: 0x000000
|
||||
text_color: 0xEEEEEE
|
||||
default_font: montserrat_18
|
||||
|
||||
Reference in New Issue
Block a user