From 57e11fc53942015f27d1a61539b218118aeecf14 Mon Sep 17 00:00:00 2001 From: "Adrian A. Baumann" Date: Sun, 11 Jan 2026 22:37:12 +0100 Subject: [PATCH] Ade's office control panel added --- ades-office-control-panel/main.yaml | 874 ++++++++++++++++++++++++++++ 1 file changed, 874 insertions(+) create mode 100644 ades-office-control-panel/main.yaml diff --git a/ades-office-control-panel/main.yaml b/ades-office-control-panel/main.yaml new file mode 100644 index 0000000..3cc7c68 --- /dev/null +++ b/ades-office-control-panel/main.yaml @@ -0,0 +1,874 @@ +substitutions: + device_name: "ades-office-control-panel" + friendly_name: Ade's Office Control Panel + +esphome: + name: $device_name + friendly_name: $friendly_name + on_boot: + - delay: 2s + +esp32: + board: esp32dev + framework: + type: arduino +logger: + +ota: + platform: esphome + password: !secret ota_password + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + fast_connect: true + on_connect: + - lvgl.widget.show: wifiStatusIcon + on_disconnect: + - lvgl.widget.hide: wifiStatusIcon + + +light: + - platform: monochromatic + output: backlight_pwm + name: Display Backlight + id: backlight + restore_mode: ALWAYS_ON + +time: + - platform: homeassistant + id: esptime + +spi: + - id: tft + clk_pin: GPIO14 + mosi_pin: GPIO13 + miso_pin: GPIO12 + +i2c: + sda: GPIO33 + scl: GPIO32 + +touchscreen: + platform: cst816 + id: my_touchscreen + display: mainDisplay + reset_pin: GPIO25 + update_interval: 50ms + transform: + mirror_x: true + mirror_y: true + on_touch: + - lambda: |- + ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d", + touch.x, + touch.y, + touch.x_raw, + touch.y_raw + ); + on_release: + then: + - if: + condition: lvgl.is_paused + then: + - logger.log: "LVGL resuming" + - lvgl.resume: + - lvgl.widget.redraw: + - light.turn_on: backlight + +output: + - platform: ledc + pin: GPIO27 + id: backlight_pwm + +api: + encryption: + key: "FdLcYGMsxFkCFoY8UUu0q/huDesKrcy4+vNQujhbXVE=" + on_client_connected: + - lvgl.widget.show: haStatusIcon + on_client_disconnected: + if: + condition: + api.connected: + then: + - lvgl.widget.show: haStatusIcon + else: + - lvgl.widget.hide: haStatusIcon + +display: + - id: mainDisplay + platform: ili9xxx + model: ili9341 + spi_id: tft + cs_pin: + number: 15 + ignore_strapping_warning: true + dc_pin: + number: 2 + ignore_strapping_warning: true + invert_colors: false + update_interval: never + auto_clear_enabled: false + pixel_mode: 16bit + transform: + mirror_y: true + mirror_x: true + swap_xy: false + dimensions: + height: 320 + width: 240 + color_order: rgb + init_sequence: + - [0x01 ] + - [0xcf, 0x00, 0xC1, 0x30 ] + - [0xed, 0x64, 0x03, 0x12, 0x81 ] # POSC Pwr on seq. ctrl + - [0xe8, 0x85, 0x00, 0x78 ] # DTCA Driver timing ctrl A + - [0xcb, 0x39, 0x2C, 0x00, 0x34, 0x02 ] # PWCTRA Pwr ctrl A + - [0xf7, 0x20 ] # PUMPRC Pump ratio control + - [0xea, 0x00, 0x00 ] # DTCB Driver timing ctrl B + - [0xc0, 0x23 ] # PWCTR1 Pwr ctrl 1 + - [0xc1, 0x10 ] # PWCTR2 Pwr ctrl 2 + - [0xc5, 0x3E, 0x28 ] # VMCTR1 VCOM ctrl 1 + - [0xc7, 0x86 ] # VMCTR2 VCOM ctrl 2 + - [0x36, 0x48 ] + - [0x37, 0x00 ] # VSCRSADD Vertical scrolling start address + - [0x3a, 0x55 ] # PIXFMT COLMOD: Pixel format 16 bits (MCU & interface) + - [0xb1, 0x00, 0x18 ] # FRMCTR1 Frame rate ctrl + - [0xb6, 0x08, 0x82, 0x27 ] # DFUNCTR + - [0xf2, 0x01 ] # ENABLE3G Enable 3 gamma ctrl + - [0x26, 0x01 ] # GAMMASET Gamma curve selected + #- [0xe0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00 ] + #- [0xe1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F ] + - [0x11 ] # SLPOUT Exit sleep + - [0x29 ] # DISPLAY_ON + +sensor: + - platform: adc + pin: 34 + name: "Brightness" + update_interval: 60s + id: lsr + - platform: homeassistant + entity_id: sensor.k2plus_c06b_print_progress + id: sensor_3dprinter_percentage + on_value: + then: + - lvgl.label.update: + id: lbl_3dprinter_percentage + text: + format: "Percentage: %.0f%%" + args: [x] + - platform: homeassistant + entity_id: sensor.k2plus_c06b_nozzle_temperature + id: sensor_3dprinter_nozzle + on_value: + then: + - lvgl.indicator.update: + id: gauge_3dprinter_nozzle_needle + value: !lambda return x; + - lvgl.label.update: + id: gauge_3dprinter_nozzle_text + text: + format: "%.0fC" + args: [ 'x' ] + - platform: homeassistant + entity_id: number.k2plus_c06b_nozzle_target + id: number_3dprinter_nozzle_target + on_value: + then: + - lvgl.arc.update: + id: arc_nozzle_target + value: !lambda return x; + - platform: homeassistant + entity_id: sensor.k2plus_c06b_bed_temperature + id: sensor_3dprinter_bed + on_value: + then: + - lvgl.indicator.update: + id: gauge_3dprinter_bed_needle + value: !lambda return x; + - lvgl.label.update: + id: gauge_3dprinter_bed_text + text: + format: "%.0fC" + args: [ 'x' ] + - platform: homeassistant + entity_id: number.k2plus_c06b_bed_target + id: number_3dprinter_bed_target + on_value: + then: + - lvgl.arc.update: + id: arc_bed_target + value: !lambda return x; + +text_sensor: + - platform: homeassistant + entity_id: sensor.k2plus_c06b_print_status + id: printerStatus + on_value: + then: + - if: + condition: + lambda: 'return x == "printing";' + then: + - lvgl.widget.update: + id: button3dPrinter + state: + disabled: ON + else: + - lvgl.widget.update: + id: button3dPrinter + state: + disabled: OFF + - lvgl.label.update: + id: lbl_3dprinter_status + text: + format: "Status: %s" + args: [x.c_str()] + - platform: homeassistant + entity_id: sensor.k2plus_c06b_current_object + id: printer_modelname + on_value: + then: + - lvgl.label.update: + id: lbl_3dprinter_modelname + text: + format: "Model: %s" + args: [x.c_str()] + - platform: homeassistant + entity_id: sensor.k2plus_c06b_working_layer + id: printer_working_layer + on_value: + then: + - lvgl.label.update: + id: lbl_3dprinter_layer + text: + format: "Layer: %s" + args: [x.c_str()] + - platform: homeassistant + entity_id: sensor.k2plus_c06b_print_time_left + id: printer_print_time_left + on_value: + then: + - lvgl.label.update: + id: lbl_3dprinter_print_time_left + text: + format: "Time remaining: %s" + args: [x.c_str()] +number: + - platform: template + name: "LVGL Screen Timeout" + optimistic: true + id: displayTimeout + unit_of_measurement: "s" + initial_value: 1800 + restore_value: true + min_value: 10 + max_value: 1800 + step: 5 + mode: box + + - platform: homeassistant + id: pcPower + entity_id: sensor.pc_ade_energy_power + on_value: + - if: + condition: + number.in_range: + id: pcPower + below: 5.0 + then: + - lvgl.widget.update: + id: buttonPc + state: + disabled: OFF + else: + - lvgl.widget.update: + id: buttonPc + state: + disabled: ON + - logger.log: "PC button disabled" + +font: + - file: "gfonts://Roboto" + id: roboto_20 + size: 20 + - file: "gfonts://Roboto" + id: roboto_10 + size: 10 + +lvgl: + buffer_size: 25% + theme: + button: + bg_color: 0x2F8CD8 + bg_grad_color: 0x005782 + bg_grad_dir: VER + bg_opa: COVER + border_color: 0x0077b3 + border_width: 1 + text_color: 0xFFFFFF + pressed: # set some button colors to be different in pressed state + bg_color: 0x006699 + bg_grad_color: 0x00334d + checked: # set some button colors to be different in checked state + bg_color: 0x1d5f96 + bg_grad_color: 0x03324A + text_color: 0xfff300 + buttonmatrix: + bg_opa: TRANSP + border_color: 0x0077b3 + border_width: 0 + text_color: 0xFFFFFF + pad_all: 0 + items: # set all your buttonmatrix buttons to use your custom defined styles and font + bg_color: 0x2F8CD8 + bg_grad_color: 0x005782 + bg_grad_dir: VER + bg_opa: COVER + border_color: 0x0077b3 + border_width: 1 + text_color: 0xFFFFFF + pressed: + bg_color: 0x006699 + bg_grad_color: 0x00334d + checked: + bg_color: 0x1d5f96 + bg_grad_color: 0x03324A + text_color: 0xFFFFA0 + switch: + bg_color: 0xC0C0C0 + bg_grad_color: 0xb0b0b0 + bg_grad_dir: VER + bg_opa: COVER + checked: + bg_color: 0x1d5f96 + bg_grad_color: 0x03324A + bg_grad_dir: VER + bg_opa: COVER + knob: + bg_color: 0xFFFFFF + bg_grad_color: 0xC0C0C0 + bg_grad_dir: VER + bg_opa: COVER + slider: + border_width: 1 + border_opa: 15% + bg_color: 0xcccaca + bg_opa: 15% + indicator: + bg_color: 0x1d5f96 + bg_grad_color: 0x03324A + bg_grad_dir: VER + bg_opa: COVER + knob: + bg_color: 0x2F8CD8 + bg_grad_color: 0x005782 + bg_grad_dir: VER + bg_opa: COVER + border_color: 0x0077b3 + border_width: 1 + text_color: 0xFFFFFF + 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: + - label: + id: wifiStatusIcon + x: 210 + y: 5 + text: "\uF1EB" + state: + disabled: true + recolor: false + text_color: white + hidden: true + - label: + id: haStatusIcon + x: 190 + y: 5 + text: "\uF015" + state: + disabled: true + recolor: false + text_color: white + hidden: true + - buttonmatrix: + align: bottom_mid + id: navbar_bottom + styles: header_footer + pad_all: 0 + outline_width: 0 + items: + styles: header_footer + rows: + - buttons: + - id: page_prev + text: "\uF053" + on_press: + then: + lvgl.page.previous: + animation: OUT_RIGHT + time: 300ms + - id: page_home + text: "\uF015" + on_press: + then: + lvgl.page.show: + id: main_page + animation: FADE_IN + time: 300ms + - id: page_next + text: "\uF054" + on_press: + then: + lvgl.page.next: + animation: OUT_LEFT + time: 300ms + pages: + - id: main_page + widgets: + - obj: + align: TOP_MID + id: header_page_main + styles: header_footer + widgets: + - label: + text: "Ade's Office" + align: CENTER + text_align: CENTER + text_color: 0xFFFFFF + - buttonmatrix: + id: matrixId + x: 10 + y: 45 + width: 220 + height: 220 + items: + pressed: + bg_color: 0xFFFF00 + rows: + - buttons: + - id: buttonLights + text: "Lights" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: adesOfficeCeiling + else: + - switch.turn_off: adesOfficeCeiling + - id: buttonDesk + text: "Desk" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: adesDeskLamp + else: + - switch.turn_off: adesDeskLamp + - buttons: + - id: button3dPrinter + text: "3D Printer" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: k2plus + else: + - switch.turn_off: k2plus + - id: buttonLaser + text: "Laser" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: laserCutter + else: + - switch.turn_off: laserCutter + - buttons: + - id: buttonLab + text: "Lab" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: electronicLab + else: + - switch.turn_off: electronicLab + - id: buttonSoldering + text: "Soldering" + control: + checkable: true + - buttons: + - id: buttonPc + text: "PC" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: switchPc + else: + - switch.turn_off: switchPc + - id: buttonScreens + text: "Monitors" + control: + checkable: true + on_value: + then: + - if: + condition: + lambda: 'return x == 1;' + then: + - switch.turn_on: switchScreens + else: + - switch.turn_off: switchScreens + - id: printer_status + widgets: + - obj: + align: TOP_MID + id: header_page_printerstatus + styles: header_footer + widgets: + - label: + text: "K2 Plus" + align: CENTER + text_align: CENTER + text_color: 0xFFFFFF + - label: + long_mode: scroll + align_to: + id: header_page_printerstatus + align: OUT_BOTTOM_LEFT + y: 3 + x: 2 + id: lbl_3dprinter_status + text: + format: "Status: %s" + args: [ 'id(printerStatus).get_state()' ] + - label: + align_to: + id: lbl_3dprinter_status + align: OUT_BOTTOM_LEFT + y: 3 + id: lbl_3dprinter_percentage + text: + format: "Percentage: %d%%" + args: ['id(sensor_3dprinter_percentage).state'] + - label: + align_to: + id: lbl_3dprinter_percentage + align: OUT_BOTTOM_LEFT + y: 3 + long_mode: scroll + id: lbl_3dprinter_modelname + width: 240 + text: "Model: None" + - label: + align_to: + id: lbl_3dprinter_modelname + align: OUT_BOTTOM_LEFT + y: 3 + long_mode: scroll + id: lbl_3dprinter_layer + width: 240 + text: "Layer: 0 of 0" + - label: + align_to: + id: lbl_3dprinter_layer + align: OUT_BOTTOM_LEFT + y: 3 + long_mode: scroll + id: lbl_3dprinter_print_time_left + width: 240 + text: "Print time left: NaN" + - meter: + id: meter_3dprinter_nozzle + align: BOTTOM_LEFT + y: -35 + x: 5 + height: 110 + width: 110 + scales: + - range_from: 0 # scale for the needle value + range_to: 380 + angle_range: 240 + rotation: 150 + indicators: + - line: + id: gauge_3dprinter_nozzle_needle + width: 2 + color: 0xFF0000 + r_mod: -4 + - range_from: 0 # scale for the value labels + range_to: 380 + angle_range: 240 + rotation: 150 + ticks: + width: 1 + count: 41 + length: 4 + color: 0x000000 + major: + stride: 20 + width: 2 + length: 6 + color: 0x404040 + label_gap: 10 + text_font: roboto_10 + widgets: + - label: + id: gauge_3dprinter_nozzle_text + text: "-.-C" + align_to: + id: meter_3dprinter_nozzle + align: CENTER + y: 35 + - label: + text: "Nozzle" + align_to: + id: meter_3dprinter_nozzle + align: CENTER + y: 45 + - arc: + align: BOTTOM_LEFT + y: -35 + x: 5 + height: 110 + width: 110 + id: arc_nozzle_target + value: !lambda "return id(number_3dprinter_nozzle_target).state;" + min_value: 0 + max_value: 380 + adjustable: true + start_angle: 150 + end_angle: 30 + knob: + pad_all: 0 + arc_rounded: false + arc_width: 6 + on_value: + then: + - homeassistant.service: + service: number.set_value + data: + entity_id: number.k2plus_c06b_nozzle_target + value: !lambda "return x;" + - meter: + id: meter_3dprinter_bed + align: BOTTOM_LEFT + y: -35 + x: 125 + height: 110 + width: 110 + scales: + - range_from: 0 # scale for the needle value + range_to: 130 + angle_range: 240 + rotation: 150 + indicators: + - line: + id: gauge_3dprinter_bed_needle + width: 2 + color: 0xFF0000 + r_mod: -4 + - range_from: 0 # scale for the value labels + range_to: 130 + angle_range: 240 + rotation: 150 + ticks: + width: 1 + count: 41 + length: 4 + color: 0x000000 + major: + stride: 20 + width: 2 + length: 6 + color: 0x404040 + label_gap: 10 + text_font: roboto_10 + widgets: + - label: + id: gauge_3dprinter_bed_text + text: "-.-C" + align_to: + id: meter_3dprinter_bed + align: CENTER + y: 35 + - label: + text: "Plate" + align_to: + id: meter_3dprinter_bed + align: CENTER + y: 45 + - arc: + align: BOTTOM_LEFT + y: -35 + x: 125 + height: 110 + width: 110 + id: arc_bed_target + value: !lambda "return id(number_3dprinter_bed_target).state;" + min_value: 0 + max_value: 130 + adjustable: true + start_angle: 150 + end_angle: 30 + knob: + pad_all: 0 + arc_rounded: false + arc_width: 6 + on_value: + then: + - homeassistant.service: + service: number.set_value + data: + entity_id: number.k2plus_c06b_bed_target + value: !lambda "return x;" + + + on_idle: + timeout: !lambda "return (id(displayTimeout).state * 1000);" + then: + - logger.log: "LVGL is idle" + - light.turn_off: backlight + - lvgl.pause: + show_snow: true + +switch: + - platform: homeassistant + id: adesOfficeCeiling + entity_id: light.ade_s_office_ceiling_lights + on_turn_on: + - lvgl.widget.update: + id: buttonLights + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonLights + state: + checked: OFF + + - platform: homeassistant + id: adesDeskLamp + entity_id: light.desklamp_ade + on_turn_on: + - lvgl.widget.update: + id: buttonDesk + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonDesk + state: + checked: OFF + + - platform: homeassistant + id: k2plus + entity_id: switch.creality_k1_max + on_turn_on: + - lvgl.widget.update: + id: button3dPrinter + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: button3dPrinter + state: + checked: OFF + + - platform: homeassistant + id: laserCutter + entity_id: switch.plug5_glowforge + on_turn_on: + - lvgl.widget.update: + id: buttonLaser + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonLaser + state: + checked: OFF + + - platform: homeassistant + id: electronicLab + entity_id: switch.electronics_lab + on_turn_on: + - lvgl.widget.update: + id: buttonLab + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonLab + state: + checked: OFF + + - platform: homeassistant + id: switchPc + entity_id: switch.pc_ade + on_turn_on: + - lvgl.widget.update: + id: buttonPc + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonPc + state: + checked: OFF + + - platform: homeassistant + id: switchScreens + entity_id: switch.officea_4k_monitors + on_turn_on: + - lvgl.widget.update: + id: buttonScreens + state: + checked: ON + on_turn_off: + - lvgl.widget.update: + id: buttonScreens + state: + checked: OFF +