diff --git a/Components/Display_Module.md b/Components/Display_Module.md index da2e627..a350e8b 100644 --- a/Components/Display_Module.md +++ b/Components/Display_Module.md @@ -99,4 +99,3 @@ PIN Description Destination 15 Main Display Backlight anode - 16 Neopixel Data OUT - 17 Neopixel Data IN - -``` diff --git a/Examples/3pages_TotalExample.yml b/Examples/3pages_TotalExample.yml new file mode 100644 index 0000000..73595c5 --- /dev/null +++ b/Examples/3pages_TotalExample.yml @@ -0,0 +1,632 @@ +esphome: + name: button-keuken + friendly_name: Button+ Keuken + +esp32: + board: esp32-s3-devkitc-1 + flash_size: 16MB + framework: + type: arduino + +# Enable logging +logger: + level: DEBUG + +debug: + update_interval: 5s + +# Enable Home Assistant API +api: + encryption: + key: "*" + +ota: + - platform: esphome + password: "*" + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +substitutions: + music_card_enity_id: 'media_player.media_keuken_2' + music_card_text_color: FFFFFF + music_card_icon_main_color: FF7F00 + music_card_icon_bar_color: FF7F00 + +packages: + remote_package_files: + url: https://github.com/dixi83/ESPHome_ButtonPlus + files: + - 'package/3bar_1display.yaml' + - 'package/cards/music.yaml' + ref: serialize-displays + refresh: 10s + +globals: + - id: !extend nr_of_pages + initial_value: '3' + +font: + - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" + id: font_arial20 + size: 20 + bpp: 4 + - file: "https://torinak.com/font/7segment.ttf" + id: font_clock + size: 64 + bpp: 4 + - file: "https://torinak.com/font/7segment.ttf" + id: font_date + size: 24 + bpp: 4 + +image: + - file: mdi:lightbulb + id: lightbulb + resize: 80x80 + - file: mdi:alert + id: alert + resize: 80x80 + - file: mdi:chevron-right + id: icon_next_page + resize: 30x30 + - file: mdi:chevron-left + id: icon_prev_page + resize: 30x30 + - file: mdi:sun-thermometer-outline + id: icon_temp_outside + resize: 40x40 + - file: mdi:home-thermometer-outline + id: icon_temp_inside + resize: 40x40 + - file: mdi:trash-can + id: icon_trashcan + resize: 20x20 + +color: + - id: red + hex: FF0000 + - id: blue + hex: 0000FF + - id: yellow + hex: FFFF00 + - id: green + hex: 00FF00 + - id: orange + hex: FF7F00 + - id: white + hex: FFFFFF + - id: grey + hex: A6A6A6 + +event: + - platform: template + name: BAR1 button Left event + id: bar1_btn_left_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + - platform: template + name: BAR1 button Right event + id: bar1_btn_right_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + - platform: template + name: BAR2 button Left event + id: bar2_btn_left_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + - platform: template + name: BAR2 button Right event + id: bar2_btn_right_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + - platform: template + name: BAR3 button Left event + id: bar3_btn_left_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + - platform: template + name: BAR3 button Right event + id: bar3_btn_right_event + event_types: + - "press page 0" + - "release page 0" + - "long press page 0" + - "press page 1" + - "release page 1" + - "long press page 1" + - "press page 2" + - "release page 2" + - "long press page 2" + +binary_sensor: + - id: !extend main_display_btn_left + on_click: + - script.execute: prev_page + - id: !extend main_display_btn_right + on_click: + - script.execute: next_page + - id: !extend bar1_btn_left + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_left_event).trigger("press page 0"); + break; + case 1: + id(bar1_btn_left_event).trigger("press page 1"); + id(music_card_vol_down).execute(); + break; + case 2: + id(bar1_btn_left_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_left_event).trigger("release page 0"); + break; + case 1: + id(bar1_btn_left_event).trigger("release page 1"); + break; + case 2: + id(bar1_btn_left_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_left_event).trigger("long press page 0"); + break; + case 1: + id(bar1_btn_left_event).trigger("long press page 1"); + break; + case 2: + id(bar1_btn_left_event).trigger("long press page 2"); + break; + } + - id: !extend bar1_btn_right + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_right_event).trigger("press page 0"); + break; + case 1: + id(bar1_btn_right_event).trigger("press page 1"); + id(music_card_vol_up).execute(); + break; + case 2: + id(bar1_btn_right_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_right_event).trigger("release page 0"); + break; + case 1: + id(bar1_btn_right_event).trigger("release page 1"); + break; + case 2: + id(bar1_btn_right_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar1_btn_right_event).trigger("long press page 0"); + break; + case 1: + id(bar1_btn_right_event).trigger("long press page 1"); + break; + case 2: + id(bar1_btn_right_event).trigger("long press page 2"); + break; + } + - id: !extend bar2_btn_left + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_left_event).trigger("press page 0"); + break; + case 1: + id(bar2_btn_left_event).trigger("press page 1"); + id(music_card_prev).execute(); + break; + case 2: + id(bar2_btn_left_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_left_event).trigger("release page 0"); + break; + case 1: + id(bar2_btn_left_event).trigger("release page 1"); + break; + case 2: + id(bar2_btn_left_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_left_event).trigger("long press page 0"); + break; + case 1: + id(bar2_btn_left_event).trigger("long press page 1"); + break; + case 2: + id(bar2_btn_left_event).trigger("long press page 2"); + break; + } + - id: !extend bar2_btn_right + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_right_event).trigger("press page 0"); + break; + case 1: + id(bar2_btn_right_event).trigger("press page 1"); + id(music_card_next).execute(); + break; + case 2: + id(bar2_btn_right_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_right_event).trigger("release page 0"); + break; + case 1: + id(bar2_btn_right_event).trigger("release page 1"); + break; + case 2: + id(bar2_btn_right_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar2_btn_right_event).trigger("long press page 0"); + break; + case 1: + id(bar2_btn_right_event).trigger("long press page 1"); + break; + case 2: + id(bar2_btn_right_event).trigger("long press page 2"); + break; + } + - id: !extend bar3_btn_left + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_left_event).trigger("press page 0"); + break; + case 1: + id(bar3_btn_left_event).trigger("press page 1"); + id(music_card_power).execute(); + break; + case 2: + id(bar3_btn_left_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_left_event).trigger("release page 0"); + break; + case 1: + id(bar3_btn_left_event).trigger("release page 1"); + break; + case 2: + id(bar3_btn_left_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_left_event).trigger("long press page 0"); + break; + case 1: + id(bar3_btn_left_event).trigger("long press page 1"); + break; + case 2: + id(bar3_btn_left_event).trigger("long press page 2"); + break; + } + - id: !extend bar3_btn_right + on_click: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_right_event).trigger("press page 0"); + break; + case 1: + id(bar3_btn_right_event).trigger("press page 1"); + id(music_card_playpause).execute(); + break; + case 2: + id(bar3_btn_right_event).trigger("press page 2"); + break; + } + on_release: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_right_event).trigger("release page 0"); + break; + case 1: + id(bar3_btn_right_event).trigger("release page 1"); + break; + case 2: + id(bar3_btn_right_event).trigger("release page 2"); + break; + } + on_multi_click: + - timing: + - ON for at least 2s + then: + lambda: |- + switch (id(actual_page)){ + case 0: + id(bar3_btn_right_event).trigger("long press page 0"); + break; + case 1: + id(bar3_btn_right_event).trigger("long press page 1"); + break; + case 2: + id(bar3_btn_right_event).trigger("long press page 2"); + break; + } + +sensor: + - platform: homeassistant + entity_id: sensor.gw1100a_outdoor_temperature + id: outside_temperature + ################### + ### containers: ### + ################### + - platform: debug + free: + name: "Heap Free" + loop_time: + name: "Loop Time" + +text_sensor: + - platform: homeassistant + id: container_first + entity_id: sensor.afvalinfo_containers_first_trash + - platform: homeassistant + id: container_first_color + entity_id: sensor.afvalinfo_containers_first_trash_color + - platform: homeassistant + id: container_second + entity_id: sensor.afvalinfo_containers_second_trash + - platform: homeassistant + id: container_second_color + entity_id: sensor.afvalinfo_containers_second_trash_color + +display: + ######### + # MAIN ## + ######### + - id: !extend main_display + # data_rate: 40MHz + lambda: |- + id(all_pages_main).execute(); + switch (id(actual_page)){ + case 0: + id(containers).execute(); + break; + case 1: + id(music_card).execute(20, 125); + break; + case 2: + it.print(100, 160, id(font_arial20), "This is page 3!"); + break; + } + +script: + - id: containers + then: + - lambda: |- + // first trashcan: + int x = 23; + int y = 125; + if(strcmp(id(container_first_color).state.c_str(), "grey") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(grey)); + } else if (strcmp(id(container_first_color).state.c_str(), "green") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(green)); + } else if (strcmp(id(container_first_color).state.c_str(), "blue") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(blue)); + } else if (strcmp(id(container_first_color).state.c_str(), "orange") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(orange)); + } + id(main_display).print(x+22, y, id(font_arial20), id(music_card_text_color), TextAlign::TOP_LEFT , id(container_first).state.c_str()); + // secomnd trashcan: + y = 151; + if(strcmp(id(container_second_color).state.c_str(), "grey") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(grey)); + } else if (strcmp(id(container_second_color).state.c_str(), "green") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(green)); + } else if (strcmp(id(container_second_color).state.c_str(), "blue") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(blue)); + } else if (strcmp(id(container_second_color).state.c_str(), "orange") == 0) { + id(main_display).image(x, y+4, id(icon_trashcan), ImageAlign::TOP_LEFT, id(orange)); + } + id(main_display).print(x+22, y, id(font_arial20), id(music_card_text_color), TextAlign::TOP_LEFT , id(container_second).state.c_str()); + - id: all_pages_main + then: + - lambda: |- + //>>> prev/next icons next to butotns + id(main_display).image(0, 208, id(icon_prev_page), ImageAlign::TOP_LEFT, id(red)); + id(main_display).image(320, 208, id(icon_next_page), ImageAlign::TOP_RIGHT, id(red)); + // + //>>> temperature inside: + id(main_display).image(36, 15, id(icon_temp_inside), ImageAlign::TOP_CENTER, id(red)); + id(main_display).printf(36, 80, id(font_arial20), id(white), TextAlign::TOP_CENTER , "%.1f°", id(inside_temperature).state); + // + //>>> print time and date + id(main_display).strftime(160, 5, id(font_clock), TextAlign::TOP_CENTER, "%H:%M", id(datetime).now()); + id(main_display).strftime(160, 80, id(font_date), TextAlign::TOP_CENTER, "%d-%m-%Y", id(datetime).now()); + // + //>>> outside temperature + id(main_display).image(285, 15, id(icon_temp_outside), ImageAlign::TOP_CENTER, id(red)); + id(main_display).printf(285, 80, id(font_arial20), id(white), TextAlign::TOP_CENTER , "%.1f°", id(outside_temperature).state); + - id: !extend bar1_left_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("volume_down"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } + - id: !extend bar1_right_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("volume_up"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } + - id: !extend bar2_left_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("prev"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } + - id: !extend bar2_right_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("next"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } + - id: !extend bar3_left_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("power"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } + - id: !extend bar3_right_draw + then: + - lambda: |- + switch (id(actual_page)){ + case 0: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); + break; + case 1: + id(music_card_bar).execute("playpause"); + break; + case 2: + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); + break; + } diff --git a/README.md b/README.md index 16e9f3a..d532ba0 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The ESPHome integration adds more flexebility and features, but also add some mo [Dutch support topic on Tweakers.net](https://gathering.tweakers.net/forum/list_messages/2270086) ## Usefull Links diff --git a/Tests/24-11-25_new_script.yaml b/Tests/24-11-25_new_script.yaml new file mode 100644 index 0000000..fbb7f06 --- /dev/null +++ b/Tests/24-11-25_new_script.yaml @@ -0,0 +1,529 @@ +esphome: + name: buttonplus-test + friendly_name: ButtonPlus_test + on_boot: + priority: -100 + then: + - script.execute: setup_bar_displays + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right + - script.execute: update_bar3_left + - script.execute: update_bar3_right + +esp32: + board: esp32-s3-devkitc-1 + flash_size: 16MB + framework: + type: arduino + +debug: + update_interval: 5s + +text_sensor: + - platform: debug + device: + name: "Device Info" + reset_reason: + name: "Reset Reason" + +# Logger must be at least debug (default) +logger: + level: debug + +# Enable Home Assistant API +api: + encryption: + key: "" + +ota: + - platform: esphome + password: "" + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + output_power: 15.5dB + +i2c: + - id: temperature_sensor + sda: GPIO1 + scl: GPIO2 + - id: buttons + sda: GPIO47 + scl: GPIO48 + frequency: 400khz + +spi: + clk_pin: GPIO36 + mosi_pin: GPIO35 + +mcp23008: + - id: base_J0 + i2c_id: buttons + address: 0x20 + - id: base_J1 + i2c_id: buttons + address: 0x21 + - id: base_J2 + i2c_id: buttons + address: 0x22 + - id: base_J3 + i2c_id: buttons + address: 0x23 + +output: + - platform: ledc + pin: GPIO3 + id: display_main_backlight_pwm + inverted: True + max_power: 1.0 + frequency: 500Hz + - platform: ledc + pin: GPIO46 + id: displays_mini_backlight_pwm + inverted: True + max_power: 0.6 + frequency: 500Hz + - id: cs_pin_bar1_left + platform: gpio + pin: + mcp23xxx: base_J1 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar1_right + platform: gpio + pin: + mcp23xxx: base_J1 + number: 1 + mode: + output: true + inverted: true + - id: cs_pin_bar2_left + platform: gpio + pin: + mcp23xxx: base_J2 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar2_right + platform: gpio + pin: + mcp23xxx: base_J2 + number: 1 + mode: + output: true + inverted: true + - id: cs_pin_bar3_left + platform: gpio + pin: + mcp23xxx: base_J3 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar3_right + platform: gpio + pin: + mcp23xxx: base_J3 + number: 1 + mode: + output: true + inverted: true + +sensor: + - platform: sts3x + id: inside_temperature + i2c_id: temperature_sensor + name: "Temperature" + address: 0x4A + update_interval: 10s + - platform: homeassistant + entity_id: sensor.gw1100a_outdoor_temperature + id: outside_temperature + - platform: debug + free: + name: "Heap Free" + block: + name: "Heap Max Block" + loop_time: + name: "Loop Time" + psram: + name: "Free PSRAM" + +time: + - platform: homeassistant + id: datetime + +font: + - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" + id: font_arial20 + size: 20 + bpp: 4 + - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" + id: font_arial15 + size: 15 + bpp: 4 + - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" + id: font_arial40 + size: 40 + bpp: 4 + - file: "https://torinak.com/font/7segment.ttf" + id: font_clock + size: 80 + bpp: 4 + - file: "https://torinak.com/font/7segment.ttf" + id: font_date + size: 30 + bpp: 4 + +image: + - file: mdi:lightbulb + id: lightbulb + resize: 80x80 + - file: mdi:alert + id: alert + resize: 80x80 + - file: mdi:chevron-right + id: icon_next_page + resize: 30x30 + - file: mdi:chevron-left + id: icon_prev_page + resize: 30x30 + - file: mdi:sun-thermometer-outline + id: icon_temp_outside + resize: 40x40 + - file: mdi:home-thermometer-outline + id: icon_temp_inside + resize: 40x40 + +color: + - id: red + hex: FF0000 + - id: blue + hex: 0000FF + - id: yellow + hex: FFFF00 + - id: green + hex: 00FF00 + - id: orange + hex: FF7F00 + - id: white + hex: FFFFFF + +binary_sensor: + - platform: gpio + id: 'main_display_btn_left' + name: "Main Display button Left" + pin: + mcp23xxx: base_J2 + number: 6 + mode: INPUT_PULLUP + inverted: true + on_click: + - script.execute: prev_page_all + - platform: gpio + id: 'main_display_btn_right' + name: "Main Display button Right" + pin: + mcp23xxx: base_J2 + number: 2 + mode: INPUT_PULLUP + inverted: true + on_click: + - script.execute: next_page_all + - platform: gpio + id: 'bar1_btn_left' + name: "BAR 1 button Left" + pin: + mcp23xxx: base_J3 + number: 6 + mode: INPUT_PULLUP + inverted: true + - platform: gpio + id: 'bar1_btn_right' + name: "BAR 1 button Right" + pin: + mcp23xxx: base_J3 + number: 2 + mode: INPUT_PULLUP + inverted: true + +light: + - platform: neopixelbus + id: neopixels + type: RGB + variant: WS2812 + pin: GPIO4 + num_leds: 5 + - platform: monochromatic + output: display_main_backlight_pwm + gamma_correct : 2.2 + name: "Main Display Backlight" + id: display_main_backlight + restore_mode: ALWAYS_ON + - platform: monochromatic + output: displays_mini_backlight_pwm + gamma_correct : 2.2 + name: "Mini Display Backlight" + id: displays_mini_backlight + restore_mode: ALWAYS_ON + - platform: partition + name: "BAR 1 Left RGB Front" + id: bar1_left_rgb_front + segments: + - id: neopixels + from: 0 + to: 0 + - platform: partition + name: "BAR 1 Left RGB Back" + id: bar1_left_rgb_back + segments: + - id: neopixels + from: 1 + to: 1 + - platform: partition + name: "BAR 1 Right RGB Front" + id: bar1_right_rgb_front + segments: + - id: neopixels + from: 2 + to: 2 + - platform: partition + name: "BAR 1 Right RGB Back" + id: bar1_right_rgb_back + segments: + - id: neopixels + from: 3 + to: 3 + +display: + - id: main_display + platform: ili9xxx + model: ili9341 + color_order: rgb + update_interval: 30s + invert_colors: false + dc_pin: + number: GPIO37 + allow_other_uses: true + cs_pin: + mcp23xxx: base_J0 + number: 5 + mode: + output: true + inverted: false + show_test_card: false + dimensions: + height: 240 + width: 320 + rotation: 180 + pages: + - id: page1 + lambda: |- + id(all_pages).execute(); + it.print(100, 160, id(font_arial20), "This is page 1!"); + - id: bar_display + platform: ili9xxx + model: ST7735 + color_order: bgr + update_interval: never + dc_pin: + number: GPIO37 + allow_other_uses: true + invert_colors: false + show_test_card: false + auto_clear_enabled: false + dimensions: + height: 160 + width: 80 + offset_width: 24 + +script: + - id: update_bar1_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); // << + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar1_left_page1).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_left).turn_off(); + - id: update_bar1_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_on(); // << + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar1_right_page1).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_right).turn_off(); + - id: update_bar2_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_on(); // << + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + // + id(bar_display).fill(id(orange)); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_left).turn_off(); + - id: update_bar2_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_on(); // << + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + // + id(bar_display).fill(id(orange)); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_right).turn_off(); + - id: update_bar3_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_on(); // << + id(cs_pin_bar3_right).turn_off(); + // + id(bar_display).fill(id(orange)); + id(bar_display).update(); + delay(1); + id(cs_pin_bar3_left).turn_off(); + - id: update_bar3_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_on(); + // + id(bar_display).fill(id(orange)); + id(bar_display).update(); + delay(1); + id(cs_pin_bar3_right).turn_off(); + - id: bar1_left_page1 + then: + - lambda: |- + id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(orange)); + - id: bar1_right_page1 + then: + - lambda: |- + id(bar_display).image(80, 0, id(alert), ImageAlign::TOP_CENTER, id(red)); + - id: setup_bar_displays + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_left).turn_off(); + delay(5); + id(cs_pin_bar1_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_right).turn_off(); + delay(5); + id(cs_pin_bar2_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar2_left).turn_off(); + delay(5); + id(cs_pin_bar2_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar2_right).turn_off(); + delay(5); + id(cs_pin_bar3_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar3_left).turn_off(); + delay(5); + id(cs_pin_bar3_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar3_right).turn_off(); + - id: update_main + then: + - component.update: main_display + - id: update_all + then: + - component.update: main_display + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right + - script.execute: update_bar3_left + - script.execute: update_bar3_right + - id: next_page_main + then: + - display.page.show_next: main_display + - script.execute: update_main + - id: next_page_all + then: + - display.page.show_next: main_display + - script.execute: update_all + - id: prev_page_main + then: + - display.page.show_previous: main_display + - script.execute: update_main + - id: prev_page_all + then: + - display.page.show_previous: main_display + - script.execute: update_all + - id: all_pages + then: + - lambda: |- + //>>> make a border arround the display + id(main_display).filled_rectangle( 0, 0, 320, 3, id(red)); + id(main_display).filled_rectangle( 0, 0, 3, 240, id(red)); + id(main_display).filled_rectangle( 0, 237, 320, 3, id(red)); + //id(main_display).filled_rectangle( 0, 206, 320, 3, id(red)); + id(main_display).filled_rectangle(317, 0, 3, 240, id(red)); + // + //>>> prev/next icons next to butotns + id(main_display).image(0, 208, id(icon_prev_page), ImageAlign::TOP_LEFT, id(orange)); + id(main_display).image(320, 208, id(icon_next_page), ImageAlign::TOP_RIGHT, id(orange)); + // + //>>> temperature inside: + id(main_display).image(36, 15, id(icon_temp_inside), ImageAlign::TOP_CENTER, id(orange)); + id(main_display).printf(36, 85, id(font_arial20), id(white), TextAlign::BASELINE_CENTER , "%.1f°", id(inside_temperature).state); + // + //>>> vertical line: + id(main_display).filled_rectangle(70, 0, 3, 115, id(red)); + // + //>>> print time and date + id(main_display).strftime(160, 5, id(font_clock), TextAlign::TOP_CENTER, "%H:%M", id(datetime).now()); + id(main_display).strftime(160, 80, id(font_date), TextAlign::TOP_CENTER, "%d-%m-%Y", id(datetime).now()); + // + //>>> vertical line: + id(main_display).filled_rectangle(250, 0, 3, 115, id(red)); + // + //>>> outside temperature + id(main_display).image(285, 15, id(icon_temp_outside), ImageAlign::TOP_CENTER, id(orange)); + id(main_display).printf(285, 85, id(font_arial20), id(white), TextAlign::BASELINE_CENTER , "%.1f°", id(outside_temperature).state); + // + //>>> horizontal line: + id(main_display).filled_rectangle(0, 115, 320, 3, id(red)); + diff --git a/package/1bar_1display.yaml b/package/1bar_1display.yaml index c03757f..1e4422a 100644 --- a/package/1bar_1display.yaml +++ b/package/1bar_1display.yaml @@ -8,6 +8,15 @@ packages: base: !include base.yaml + scripts: !include 1bar_1display_scripts.yaml + +esphome: + on_boot: + priority: -100 + then: + - script.execute: setup_bar_displays + - script.execute: update_bar1_left + - script.execute: update_bar1_right mcp23008: - id: 'base_J2' @@ -22,16 +31,16 @@ binary_sensor: ### Buttons Main Display ### ############################ - platform: gpio - id: 'base_j2_btn_left' - name: "Display button Left" + id: 'main_display_btn_left' + name: "Main Display button Left" pin: mcp23xxx: base_J2 number: 6 mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j2_btn_right' - name: "Display button Right" + id: 'main_display_btn_right' + name: "Main Display button Right" pin: mcp23xxx: base_J2 number: 2 @@ -42,16 +51,16 @@ binary_sensor: ### Buttons BAR module 1 ### ############################ - platform: gpio - id: 'base_j3_btn_left' - name: "BAR button Left" + id: 'bar1_btn_left' + name: "BAR 1 button Left" pin: mcp23xxx: base_J3 number: 6 mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j3_btn_right' - name: "BAR button Right" + id: 'bar1_btn_right' + name: "BAR 1 button Right" pin: mcp23xxx: base_J3 number: 2 @@ -65,42 +74,64 @@ light: ### RGB LED's BAR module ### ############################ - platform: partition - name: "BAR J3 Left RGB Front" - id: bar_j3_left_rgb_front + name: "BAR 1 Left RGB Front" + id: bar1_left_rgb_front segments: - id: neopixels from: 0 to: 0 - platform: partition - name: "BAR J3 Left RGB Back" - id: bar_j3_left_rgb_back + name: "BAR 1 Left RGB Back" + id: bar1_left_rgb_back segments: - id: neopixels from: 1 to: 1 - platform: partition - name: "BAR J3 Right RGB Front" - id: bar_j3_right_rgb_front + name: "BAR 1 Right RGB Front" + id: bar1_right_rgb_front segments: - id: neopixels from: 2 to: 2 - platform: partition - name: "BAR J3 Right RGB Back" - id: bar_j3_right_rgb_back + name: "BAR 1 Right RGB Back" + id: bar1_right_rgb_back segments: - id: neopixels from: 3 to: 3 +output: + ####################################### + ### CS pins to control BAR Displays ### + ####################################### + - id: cs_pin_bar1_left + platform: gpio + pin: + mcp23xxx: base_J3 + number: 5 + mode: + output: true + inverted: false + - id: cs_pin_bar1_right + platform: gpio + pin: + mcp23xxx: base_J3 + number: 1 + mode: + output: true + inverted: false + display: #################### ### Main Display ### #################### - - id: display_j2_main + - id: main_display platform: ili9xxx model: ili9341 color_order: rgb + update_interval: 30s invert_colors: false dc_pin: number: GPIO37 @@ -111,7 +142,6 @@ display: mode: output: true inverted: false - update_interval: 500ms show_test_card: false dimensions: height: 240 @@ -120,45 +150,17 @@ display: ################## ### BAR module ### ################## - - id: display_j3_Left + - id: bar_display platform: ili9xxx model: ST7735 color_order: bgr + update_interval: never dc_pin: number: GPIO37 allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 5 - mode: - output: true - inverted: false invert_colors: false show_test_card: false dimensions: height: 160 width: 80 offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j3_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s diff --git a/package/1bar_1display_scripts.yaml b/package/1bar_1display_scripts.yaml new file mode 100644 index 0000000..1d08129 --- /dev/null +++ b/package/1bar_1display_scripts.yaml @@ -0,0 +1,81 @@ +############################################## +## ## +## filename: 1bar_1display_scripts.yaml ## +## description: Specific pre-defined ## +## scripts for 1 BAR 1 Display setup ## +## ## +############################################## + +script: +###################### +### update scripts ### +###################### + - id: update_bar1_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); // << + id(cs_pin_bar1_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar1_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_left).turn_off(); + - id: update_bar1_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_on(); // << + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar1_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_right).turn_off(); +################################## +### setup mini display scripts ### +################################## + - id: setup_bar_displays + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_left).turn_off(); + delay(5); + id(cs_pin_bar1_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_right).turn_off(); +#################### +### draw scripts ### +#################### + - id: bar1_left_draw + then: + - id: bar1_right_draw + then: +############################## +### other handling scripts ### +############################## + - id: update_main + then: + - component.update: main_display + - id: update_all + then: + - component.update: main_display + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - id: next_page_main + then: + - display.page.show_next: main_display + - script.execute: update_main + - id: next_page_all + then: + - display.page.show_next: main_display + - script.execute: update_all + - id: prev_page_main + then: + - display.page.show_previous: main_display + - script.execute: update_main + - id: prev_page_all + then: + - display.page.show_previous: main_display + - script.execute: update_all diff --git a/package/2bar_1display.yaml b/package/2bar_1display.yaml index 56eb870..582b896 100644 --- a/package/2bar_1display.yaml +++ b/package/2bar_1display.yaml @@ -8,6 +8,17 @@ packages: base: !include base.yaml + scripts: !include 2bar_1display_scripts.yaml + +esphome: + on_boot: + priority: -100 + then: + - script.execute: setup_bar_displays + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right mcp23008: - id: 'base_J1' @@ -25,16 +36,16 @@ binary_sensor: ### Buttons Main Display ### ############################ - platform: gpio - id: 'base_j1_btn_left' - name: "Display button Left" + id: 'main_display_btn_left' + name: "Main Display button Left" pin: mcp23xxx: base_J1 number: 6 mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j1_btn_right' - name: "Display button Right" + id: 'main_display_btn_right' + name: "Main Display button Right" pin: mcp23xxx: base_J1 number: 2 @@ -45,7 +56,7 @@ binary_sensor: ### Buttons BAR module 1 ### ############################ - platform: gpio - id: 'base_j2_btn_left' + id: 'bar1_btn_left' name: "BAR 1 button Left" pin: mcp23xxx: base_J2 @@ -53,7 +64,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j2_btn_right' + id: 'bar1_btn_right' name: "BAR 1 button Right" pin: mcp23xxx: base_J2 @@ -65,7 +76,7 @@ binary_sensor: ### Buttons BAR module 2 ### ############################ - platform: gpio - id: 'base_j3_btn_left' + id: 'bar2_btn_left' name: "BAR 2 button Left" pin: mcp23xxx: base_J3 @@ -73,7 +84,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j3_btn_right' + id: 'bar2_btn_right' name: "BAR 2 button Right" pin: mcp23xxx: base_J3 @@ -89,28 +100,28 @@ light: ############################## - platform: partition name: "BAR 1 Left RGB Front" - id: bar_1_left_rgb_front + id: bar1_left_rgb_front segments: - id: neopixels from: 0 to: 0 - platform: partition name: "BAR 1 Left RGB Back" - id: bar_1_left_rgb_back + id: bar1_left_rgb_back segments: - id: neopixels from: 1 to: 1 - platform: partition name: "BAR 1 Right RGB Front" - id: bar_1_right_rgb_front + id: bar1_right_rgb_front segments: - id: neopixels from: 2 to: 2 - platform: partition name: "BAR 1 Right RGB Back" - id: bar_1_right_rgb_back + id: bar1_right_rgb_back segments: - id: neopixels from: 3 @@ -120,42 +131,80 @@ light: ############################## - platform: partition name: "BAR 2 Left RGB Front" - id: bar_2_left_rgb_front + id: bar2_left_rgb_front segments: - id: neopixels from: 4 to: 4 - platform: partition name: "BAR 2 Left RGB Back" - id: bar_2_left_rgb_back + id: bar2_left_rgb_back segments: - id: neopixels from: 5 to: 5 - platform: partition name: "BAR 2 Right RGB Front" - id: bar_2_right_rgb_front + id: bar2_right_rgb_front segments: - id: neopixels from: 6 to: 6 - platform: partition name: "BAR 2 Right RGB Back" - id: bar_2_right_rgb_back + id: bar2_right_rgb_back segments: - id: neopixels from: 7 to: 7 +output: + ####################################### + ### CS pins to control BAR Displays ### + ####################################### + - id: cs_pin_bar1_left + platform: gpio + pin: + mcp23xxx: base_J1 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar1_right + platform: gpio + pin: + mcp23xxx: base_J1 + number: 1 + mode: + output: true + inverted: true + - id: cs_pin_bar2_left + platform: gpio + pin: + mcp23xxx: base_J2 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar2_right + platform: gpio + pin: + mcp23xxx: base_J2 + number: 1 + mode: + output: true + inverted: true + display: #################### ### Main Display ### #################### - - id: display_j1_main + - id: main_display platform: ili9xxx model: ili9341 color_order: rgb invert_colors: false + update_interval: 30s dc_pin: number: GPIO37 allow_other_uses: true @@ -165,99 +214,25 @@ display: mode: output: true inverted: false - update_interval: 200ms show_test_card: false dimensions: height: 240 width: 320 rotation: 180 - #################### - ### BAR module 1 ### - #################### - - id: display_j2_Left + ################### + ### BAR modules ### + ################### + - id: bar_display platform: ili9xxx model: ST7735 color_order: bgr + update_interval: never dc_pin: number: GPIO37 allow_other_uses: true - cs_pin: - mcp23xxx: base_J2 - number: 5 - mode: - output: true - inverted: false invert_colors: false show_test_card: false dimensions: height: 160 width: 80 offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j2_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J2 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s - #################### - ### BAR module 2 ### - #################### - - id: display_j3_Left - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 5 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j3_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s diff --git a/package/2bar_1display_scripts.yaml b/package/2bar_1display_scripts.yaml new file mode 100644 index 0000000..aa7914e --- /dev/null +++ b/package/2bar_1display_scripts.yaml @@ -0,0 +1,133 @@ +############################################## +## ## +## filename: 1bar_1display_scripts.yaml ## +## description: Specific pre-defined ## +## scripts for 2 BAR 1 Display setup ## +## ## +############################################## + +script: +###################### +### update scripts ### +###################### + - id: update_bar1_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); // << + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar1_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_left).turn_off(); + - id: update_bar1_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_on(); // << + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar1_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_right).turn_off(); + - id: update_bar2_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_on(); // << + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar2_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_left).turn_off(); + - id: update_bar2_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_on(); // << + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar2_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_right).turn_off(); +################################## +### setup mini display scripts ### +################################## + - id: setup_bar_displays + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_left).turn_off(); + delay(5); + id(cs_pin_bar1_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar1_right).turn_off(); + delay(5); + id(cs_pin_bar2_left).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar2_left).turn_off(); + delay(5); + id(cs_pin_bar2_right).turn_on(); + id(bar_display).setup(); + id(cs_pin_bar2_right).turn_off(); +#################### +### draw scripts ### +#################### + - id: bar1_left_draw + then: + - id: bar1_right_draw + then: + - id: bar2_left_draw + then: + - id: bar2_right_draw + then: +############################## +### other handling scripts ### +############################## + - id: update_main + then: + - component.update: main_display + - id: update_all + then: + - component.update: main_display + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right + - id: next_page_main + then: + - display.page.show_next: main_display + - script.execute: update_main + - id: next_page_all + then: + - display.page.show_next: main_display + - script.execute: update_all + - id: prev_page_main + then: + - display.page.show_previous: main_display + - script.execute: update_main + - id: prev_page_all + then: + - display.page.show_previous: main_display + - script.execute: update_all diff --git a/package/3bar_1display.yaml b/package/3bar_1display.yaml index 6627695..73f68d0 100644 --- a/package/3bar_1display.yaml +++ b/package/3bar_1display.yaml @@ -8,6 +8,25 @@ packages: base: !include base.yaml + scripts: !include 3bar_1display_scripts.yaml + +esphome: + on_boot: + priority: -100 + then: + - logger.log: "ESPHome for Button+ v0.1.0_dev" + - script.execute: setup_bar_displays + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right + - script.execute: update_bar3_left + - script.execute: update_bar3_right + +interval: + - interval: 1min + then: + - logger.log: "ESPHome for Button+ v0.1.0_dev" mcp23008: - id: 'base_J0' @@ -28,7 +47,7 @@ binary_sensor: ### Buttons Main Display ### ############################ - platform: gpio - id: 'base_j0_btn_left' + id: 'main_display_btn_left' name: "Display button Left" pin: mcp23xxx: base_J0 @@ -36,7 +55,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j0_btn_right' + id: 'main_display_btn_right' name: "Display button Right" pin: mcp23xxx: base_J0 @@ -48,7 +67,7 @@ binary_sensor: ### Buttons BAR module 1 ### ############################ - platform: gpio - id: 'base_j1_btn_left' + id: 'bar1_btn_left' name: "BAR 1 button Left" pin: mcp23xxx: base_J1 @@ -56,7 +75,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j1_btn_right' + id: 'bar1_btn_right' name: "BAR 1 button Right" pin: mcp23xxx: base_J1 @@ -68,7 +87,7 @@ binary_sensor: ### Buttons BAR module 2 ### ############################ - platform: gpio - id: 'base_j2_btn_left' + id: 'bar2_btn_left' name: "BAR 2 button Left" pin: mcp23xxx: base_J2 @@ -76,7 +95,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j2_btn_right' + id: 'bar2_btn_right' name: "BAR 2 button Right" pin: mcp23xxx: base_J2 @@ -88,7 +107,7 @@ binary_sensor: ### Buttons BAR module 3 ### ############################ - platform: gpio - id: 'base_j3_btn_left' + id: 'bar3_btn_left' name: "BAR 3 button Left" pin: mcp23xxx: base_J3 @@ -96,7 +115,7 @@ binary_sensor: mode: INPUT_PULLUP inverted: true - platform: gpio - id: 'base_j3_btn_right' + id: 'bar3_btn_right' name: "BAR 3 button Right" pin: mcp23xxx: base_J3 @@ -112,28 +131,28 @@ light: ############################## - platform: partition name: "BAR 1 Left RGB Front" - id: bar_1_left_rgb_front + id: bar1_left_rgb_front segments: - id: neopixels from: 0 to: 0 - platform: partition name: "BAR 1 Left RGB Back" - id: bar_1_left_rgb_back + id: bar1_left_rgb_back segments: - id: neopixels from: 1 to: 1 - platform: partition name: "BAR 1 Right RGB Front" - id: bar_1_right_rgb_front + id: bar1_right_rgb_front segments: - id: neopixels from: 2 to: 2 - platform: partition name: "BAR 1 Right RGB Back" - id: bar_1_right_rgb_back + id: bar1_right_rgb_back segments: - id: neopixels from: 3 @@ -143,28 +162,28 @@ light: ############################## - platform: partition name: "BAR 2 Left RGB Front" - id: bar_2_left_rgb_front + id: bar2_left_rgb_front segments: - id: neopixels from: 4 to: 4 - platform: partition name: "BAR 2 Left RGB Back" - id: bar_2_left_rgb_back + id: bar2_left_rgb_back segments: - id: neopixels from: 5 to: 5 - platform: partition name: "BAR 2 Right RGB Front" - id: bar_2_right_rgb_front + id: bar2_right_rgb_front segments: - id: neopixels from: 6 to: 6 - platform: partition name: "BAR 2 Right RGB Back" - id: bar_2_right_rgb_back + id: bar2_right_rgb_back segments: - id: neopixels from: 7 @@ -174,42 +193,96 @@ light: ############################## - platform: partition name: "BAR 3 Left RGB Front" - id: bar_3_left_rgb_front + id: bar3_left_rgb_front segments: - id: neopixels from: 8 to: 8 - platform: partition name: "BAR 3 Left RGB Back" - id: bar_3_left_rgb_back + id: bar3_left_rgb_back segments: - id: neopixels from: 9 to: 9 - platform: partition name: "BAR 3 Right RGB Front" - id: bar_3_right_rgb_front + id: bar3_right_rgb_front segments: - id: neopixels from: 10 to: 10 - platform: partition name: "BAR 3 Right RGB Back" - id: bar_3_right_rgb_back + id: bar3_right_rgb_back segments: - id: neopixels from: 11 to: 11 +output: + ####################################### + ### CS pins to control BAR Displays ### + ####################################### + - id: cs_pin_bar1_left + platform: gpio + pin: + mcp23xxx: base_J1 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar1_right + platform: gpio + pin: + mcp23xxx: base_J1 + number: 1 + mode: + output: true + inverted: true + - id: cs_pin_bar2_left + platform: gpio + pin: + mcp23xxx: base_J2 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar2_right + platform: gpio + pin: + mcp23xxx: base_J2 + number: 1 + mode: + output: true + inverted: true + - id: cs_pin_bar3_left + platform: gpio + pin: + mcp23xxx: base_J3 + number: 5 + mode: + output: true + inverted: true + - id: cs_pin_bar3_right + platform: gpio + pin: + mcp23xxx: base_J3 + number: 1 + mode: + output: true + inverted: true + display: #################### ### Main Display ### #################### - - id: display_j0_main + - id: main_display platform: ili9xxx model: ili9341 invert_colors: false color_order: rgb + update_interval: 30s dc_pin: number: GPIO37 allow_other_uses: true @@ -219,144 +292,26 @@ display: mode: output: true inverted: false - update_interval: 200ms show_test_card: false dimensions: height: 240 width: 320 rotation: 180 - #################### - ### BAR module 1 ### - #################### - - id: display_j1_Left + ################### + ### BAR modules ### + ################### + - id: bar_display platform: ili9xxx model: ST7735 color_order: bgr + update_interval: never dc_pin: number: GPIO37 allow_other_uses: true - cs_pin: - mcp23xxx: base_J1 - number: 5 - mode: - output: true - inverted: false invert_colors: false show_test_card: false + auto_clear_enabled: false dimensions: height: 160 width: 80 - offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j1_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J1 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s - #################### - ### BAR module 2 ### - #################### - - id: display_j2_Left - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J2 - number: 5 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j2_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J2 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s - #################### - ### BAR module 3 ### - #################### - - id: display_j3_Left - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 5 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 270 - update_interval: 1s - - id: display_j3_Right - platform: ili9xxx - model: ST7735 - color_order: bgr - dc_pin: - number: GPIO37 - allow_other_uses: true - cs_pin: - mcp23xxx: base_J3 - number: 1 - mode: - output: true - inverted: false - invert_colors: false - show_test_card: false - dimensions: - height: 160 - width: 80 - offset_width: 24 - rotation: 90 - update_interval: 1s + offset_width: 24 \ No newline at end of file diff --git a/package/3bar_1display_scripts.yaml b/package/3bar_1display_scripts.yaml new file mode 100644 index 0000000..3aac20d --- /dev/null +++ b/package/3bar_1display_scripts.yaml @@ -0,0 +1,162 @@ +############################################## +## ## +## filename: 1bar_1display_scripts.yaml ## +## description: Specific pre-defined ## +## scripts for 3 BAR 1 Display setup ## +## ## +############################################## + +script: +###################### +### update scripts ### +###################### + - id: update_bar1_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); // << + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar1_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_left).turn_off(); + - id: update_bar1_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_on(); // << + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar1_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar1_right).turn_off(); + - id: update_bar2_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_on(); // << + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar2_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_left).turn_off(); + - id: update_bar2_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_on(); // << + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar2_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar2_right).turn_off(); + - id: update_bar3_left + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_on(); // << + id(cs_pin_bar3_right).turn_off(); + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES); + id(bar3_left_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar3_left).turn_off(); + - id: update_bar3_right + then: + - lambda: |- + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_on(); // << + id(bar_display).clear(); + id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES); + id(bar3_right_draw).execute(); + id(bar_display).update(); + delay(1); + id(cs_pin_bar3_right).turn_off(); +#################################### +### setup mini display's scripts ### +#################################### + - id: setup_bar_displays + then: + - lambda: |- + id(cs_pin_bar1_left).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar1_left).turn_off(); + id(cs_pin_bar1_right).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar1_right).turn_off(); + id(cs_pin_bar2_left).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar2_left).turn_off(); + id(cs_pin_bar2_right).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar2_right).turn_off(); + id(cs_pin_bar3_left).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar3_left).turn_off(); + id(cs_pin_bar3_right).turn_on(); + id(bar_display).setup(); + delay(5); + id(cs_pin_bar3_right).turn_off(); +############################### +### pre-define draw scripts ### +############################### + - id: bar1_left_draw + then: + - id: bar1_right_draw + then: + - id: bar2_left_draw + then: + - id: bar2_right_draw + then: + - id: bar3_left_draw + then: + - id: bar3_right_draw + then: +###################### +### update scripts ### +###################### + - id: update_main + then: + - component.update: main_display + - id: update_all + then: + - component.update: main_display + - script.execute: update_bar1_left + - script.execute: update_bar1_right + - script.execute: update_bar2_left + - script.execute: update_bar2_right + - script.execute: update_bar3_left + - script.execute: update_bar3_right diff --git a/package/base.yaml b/package/base.yaml index 0e1823c..c1b39c6 100644 --- a/package/base.yaml +++ b/package/base.yaml @@ -23,6 +23,14 @@ spi: clk_pin: GPIO36 mosi_pin: GPIO35 +globals: + - id: nr_of_pages + type: int + initial_value: '1' + - id: actual_page + type: int + initial_value: '0' + output: - platform: ledc pin: GPIO3 @@ -34,7 +42,7 @@ output: pin: GPIO46 id: displays_mini_backlight_pwm inverted: True - max_power: 0.4 + max_power: 0.6 frequency: 500Hz sensor: @@ -68,3 +76,24 @@ light: time: - platform: homeassistant id: datetime + +script: +###################### +### paging scripts ### +###################### + - id: next_page + then: + - lambda: |- + id(actual_page) = id(actual_page) + 1; + if(id(actual_page) >= id(nr_of_pages)) { + id(actual_page) = 0; + } + - script.execute: update_all + - id: prev_page + then: + - lambda: |- + id(actual_page) = id(actual_page) - 1; + if(id(actual_page) < 0) { + id(actual_page) = id(nr_of_pages) - 1; + } + - script.execute: update_all diff --git a/package/cards/music.md b/package/cards/music.md new file mode 100644 index 0000000..a3a6989 --- /dev/null +++ b/package/cards/music.md @@ -0,0 +1,44 @@ +# ESPHome Button+ - Music card + +## Usage + +* Add the music card file to youre files and supply the `entity_id` + ``` + substitutions: + music_card_enity_id: 'media_player.media_keuken_2' + package: + remote_package_files: + url: https://github.com/dixi83/ESPHome_ButtonPlus + files: [,'package/cards/music.yaml'] + ``` +* Add the music card to the main display `lambda` and give it the position you want + ``` + id(music_card).execute(20, 125); + ``` + +* Add the icons buttons to the BAR's + + Select one of the folowing types: + * `volume_up` + * `volume_down` + * `next` + * `prev` + * `playpause` + * `power` + + ``` + id(music_card_bar).execute("volume_up"); + ``` + +* add actions to the buttons + Select the a matching action for the button: + * `music_card_vol_up` + * `music_card_vol_down` + * `music_card_next` + * `music_card_prev` + * `music_card_playpause` + * `music_card_power` + + ``` + id(music_card_vol_up).execute(); + ``` diff --git a/package/cards/music.yaml b/package/cards/music.yaml new file mode 100644 index 0000000..ac54855 --- /dev/null +++ b/package/cards/music.yaml @@ -0,0 +1,199 @@ +##################################################### +## +## FILENAME: cards/music.yaml +## DESCRIPTION: card that shows info +## about the current played song and +## players current state +## USAGE: +## substitutions: +## music_card_enity_id: 'media_player.media_keuken_2' +## package: +## remote_package_files: +## url: https://github.com/dixi83/ESPHome_ButtonPlus +## files: [,'package/cards/music.yaml'] +## +## display: +## - id: !extend main_display +## pages: +## - id: player_page +## lambda: |- +## id(all_pages).execute(); +## // insert music card: +## // >> id(music_card).execute(x, y); +## id(music_card).execute(20, 125); +## - id: !extend bar1_left +## +##################################################### + +image: + - file: mdi:music-box-outline + id: icon_music_album + resize: 20x20 + - file: mdi:account-music + id: icon_music_artist + resize: 20x20 + - file: mdi:music-note + id: icon_music_songtitle + resize: 20x20 + - file: mdi:power-off + id: icon_music_off + resize: 75x75 + - file: mdi:power-on + id: icon_music_on + resize: 75x75 + - file: mdi:power + id: icon_music_power + resize: 75x75 + - file: mdi:timer-sand-empty + id: icon_music_idle + resize: 75x75 + - file: mdi:play-pause + id: icon_music_playpause + resize: 75x75 + - file: mdi:play-box-outline + id: icon_music_play + resize: 75x75 + - file: mdi:pause-box-outline + id: icon_music_pause + resize: 75x75 + - file: mdi:power + id: icon_music_standby + resize: 75x75 + - file: mdi:download-box-outline + id: icon_music_buffering + resize: 75x75 + - file: mdi:volume-plus + id: icon_music_vol_up + resize: 75x75 + - file: mdi:volume-minus + id: icon_music_vol_down + resize: 75x75 + - file: mdi:skip-forward + id: icon_music_next + resize: 75x75 + - file: mdi:skip-backward + id: icon_music_prev + resize: 75x75 + +color: + - id: music_card_text_color + hex: ${music_card_text_color} + - id: music_card_icon_main_color + hex: ${music_card_icon_main_color} + - id: music_card_icon_bar_color + hex: ${music_card_icon_bar_color} + +text_sensor: + - platform: homeassistant + id: music_album + entity_id: ${music_card_enity_id} + attribute: media_album_name + on_value: + - delay: 500ms + - script.execute: update_main + - platform: homeassistant + id: music_artist + entity_id: ${music_card_enity_id} + attribute: media_artist + - platform: homeassistant + id: music_title + entity_id: ${music_card_enity_id} + attribute: media_title + on_value: + - delay: 500ms + - script.execute: update_main + - platform: homeassistant + id: music_playerstate + entity_id: ${music_card_enity_id} + on_value: + - script.execute: update_main + +script: + - id: music_card + parameters: + x: int + y: int + then: + - lambda: |- + // player state + if (strcmp(id(music_playerstate).state.c_str(), "off") == 0) { + id(main_display).image(x, 1+y, id(icon_music_off), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "on") == 0) { + id(main_display).image(x, 1+y, id(icon_music_on), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "idle") == 0) { + id(main_display).image(x, 1+y, id(icon_music_idle), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "playing") == 0) { + id(main_display).image(x, 1+y, id(icon_music_play), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "paused") == 0) { + id(main_display).image(x, 1+y, id(icon_music_pause), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "standby") == 0) { + id(main_display).image(x, 1+y, id(icon_music_standby), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } else if (strcmp(id(music_playerstate).state.c_str(), "buffering") == 0) { + id(main_display).image(x, 1+y, id(icon_music_buffering), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + } + // + // album + id(main_display).image(75+3+x, 4+y, id(icon_music_album), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + id(main_display).print(75+25+x, 0+y, id(font_arial20), id(music_card_text_color), TextAlign::TOP_LEFT , id(music_album).state.c_str()); + // + // artist + id(main_display).image(75+3+x, 30+y, id(icon_music_artist), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + id(main_display).print(75+25+x, 26+y, id(font_arial20), id(music_card_text_color), TextAlign::TOP_LEFT , id(music_artist).state.c_str()); + // + // song title + id(main_display).image(75+3+x, 56+y, id(icon_music_songtitle), ImageAlign::TOP_LEFT, id(music_card_icon_main_color)); + id(main_display).print(75+25+x, 52+y, id(font_arial20), id(music_card_text_color), TextAlign::TOP_LEFT , id(music_title).state.c_str()); + - id: music_card_bar + parameters: + type: string + then: + - lambda: |- + if (strcmp(type.c_str(), "volume_up") == 0) { // button "volume_up" + id(bar_display).image(80, 2, id(icon_music_vol_up), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } else if (strcmp(type.c_str(), "volume_down") == 0) { // button "volume_down" + id(bar_display).image(80, 2, id(icon_music_vol_down), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } else if (strcmp(type.c_str(), "next") == 0) { // button "next" + id(bar_display).image(80, 2, id(icon_music_next), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } else if (strcmp(type.c_str(), "prev") == 0) { // button "prev" + id(bar_display).image(80, 2, id(icon_music_prev), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } else if (strcmp(type.c_str(), "playpause") == 0) { // button "playpause" + id(bar_display).image(80, 2, id(icon_music_playpause), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } else if (strcmp(type.c_str(), "power") == 0) { // button "power" + id(bar_display).image(80, 2, id(icon_music_power), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color)); + } + - id: music_card_vol_up + then: + - homeassistant.action: + action: media_player.volume_up + data: + entity_id: ${music_card_enity_id} + - id: music_card_vol_down + then: + - homeassistant.action: + action: media_player.volume_down + data: + entity_id: ${music_card_enity_id} + - id: music_card_next + then: + - homeassistant.action: + action: media_player.media_next_track + data: + entity_id: ${music_card_enity_id} + - id: music_card_prev + then: + - homeassistant.action: + action: media_player.media_previous_track + data: + entity_id: ${music_card_enity_id} + - id: music_card_playpause + then: + - homeassistant.action: + action: media_player.media_play_pause + data: + entity_id: ${music_card_enity_id} + - id: music_card_power + then: + - homeassistant.action: + action: media_player.toggle + data: + entity_id: ${music_card_enity_id}