Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efc3feb031 | ||
|
|
1ec3e1879f | ||
|
|
7ae92918d3 | ||
|
|
aa58222296 | ||
|
|
b12b6a7d69 | ||
|
|
088db53a47 | ||
|
|
92ed59f869 | ||
|
|
51bdcac3e0 | ||
|
|
34c06a3e0b | ||
|
|
279319ed0c | ||
|
|
ec3acfe28e | ||
|
|
50f2a042ab | ||
|
|
f649343222 | ||
|
|
559f7341db | ||
|
|
e847fcf275 | ||
|
|
7a38fcf857 | ||
|
|
7a80fc62a7 | ||
|
|
1ff5a53285 | ||
|
|
0bdb67e20e | ||
|
|
3e4654b4e0 | ||
|
|
f1e722cd3b | ||
|
|
01020a20d0 | ||
|
|
147a99cd8a | ||
|
|
868cf2ab70 | ||
|
|
0752709e09 | ||
|
|
cc88e7ba21 | ||
|
|
6525a0b400 | ||
|
|
e46215e7fb | ||
|
|
3b5cbb362c | ||
|
|
6bc1297eab | ||
|
|
95657fcb08 | ||
|
|
302c4a88f8 | ||
|
|
44778ddb2a | ||
|
|
6de0d94dca | ||
|
|
3325e95bf1 | ||
|
|
34ef0d0f99 | ||
|
|
c1cde0f159 | ||
|
|
e81582f7da | ||
|
|
c5bdb903c0 | ||
|
|
b726af5c72 | ||
|
|
6531708579 | ||
|
|
262bb7dd0d | ||
|
|
c345fe0f0b | ||
|
|
485fa923fb | ||
|
|
c03360a381 | ||
|
|
72ce117299 | ||
|
|
8815f5e113 | ||
|
|
13763326ce | ||
|
|
3fa067ba37 | ||
|
|
b1271c8c12 | ||
|
|
bf606810b7 | ||
|
|
aa262f7546 | ||
|
|
54d1e432f3 | ||
|
|
1b2e11ed8c | ||
|
|
946ae2c6d1 | ||
|
|
db555ce359 | ||
|
|
7b238ac2d8 | ||
|
|
6de381b32f | ||
|
|
aaa1d6421d | ||
|
|
ae34e28ed2 | ||
|
|
f0a99c50fd | ||
|
|
5efc0b7671 | ||
|
|
11a0ef1ff0 | ||
|
|
8f460f5cb9 | ||
|
|
4536e15b7b | ||
|
|
46c003cf08 | ||
|
|
0446120b22 | ||
|
|
f4f8ba7df9 | ||
|
|
3d32a8011e | ||
|
|
c5faa2b273 | ||
|
|
efad62ee5b | ||
|
|
c844b89a19 | ||
|
|
f2bde56ab7 | ||
|
|
be8ccc5690 | ||
|
|
41d833774c | ||
|
|
3d8ad96fbb | ||
|
|
9fbe63ccfb | ||
|
|
44900c5709 | ||
|
|
98365cde0a | ||
|
|
440d4de667 | ||
|
|
cd6116b304 | ||
|
|
8dfddadac3 | ||
|
|
2c4d6afccc | ||
|
|
12ad7abb7d | ||
|
|
f55bb9030b | ||
|
|
18f65f0017 | ||
|
|
89cf1a5a36 | ||
|
|
cf582bbfeb | ||
|
|
ff73696639 | ||
|
|
e9ae543c05 | ||
|
|
edc775ea2a | ||
|
|
c2ccee1e0e | ||
|
|
16e5e2ffd1 | ||
|
|
e1ab32ecc9 | ||
|
|
24bda6eb76 | ||
|
|
93d28b7213 | ||
|
|
2ba6f609a6 | ||
|
|
311eb98c62 | ||
|
|
fd59035739 | ||
|
|
b0fb1169f2 | ||
|
|
dedb79ad58 | ||
|
|
b7c9e830b2 | ||
|
|
eca2a7c6b9 | ||
|
|
377a6e8194 | ||
|
|
b4964ed223 | ||
|
|
ec4d6830b1 | ||
|
|
24b7412674 | ||
|
|
38649f8135 | ||
|
|
c93a22ef53 | ||
|
|
6fb5ff9864 | ||
|
|
d7ceb43164 | ||
|
|
e1e5d1bba2 | ||
|
|
bb7b7c1faa | ||
|
|
79e1fc162a | ||
|
|
ee365d95b7 | ||
|
|
065577cbf0 | ||
|
|
7fd8bb0505 | ||
|
|
ae8e8fb003 | ||
|
|
014bd6f9ea |
@@ -0,0 +1 @@
|
||||
.vscode/settings.json
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
+30
-2
@@ -2,6 +2,34 @@
|
||||
|
||||
*work in progress*
|
||||
|
||||
## Introduction
|
||||
## Initial firmware load
|
||||
|
||||
TODO
|
||||
### Required
|
||||
|
||||
- Button+ Base Module
|
||||
- 1x Button+ Main Display
|
||||
- 1x Button+ BAR module
|
||||
- USB-C cable
|
||||
- ESPHome installed on Home-Assistant
|
||||
- [Getting started guide by @balk77](./GettingStarted.md)
|
||||
- [Official ESPhome guide](https://esphome.io/guides/getting_started_hassio.html)
|
||||
- Chrome/Edge or a [WebSerial compatible Browser](https://webserial.io/)
|
||||
|
||||
### Steps
|
||||
|
||||
1. Go to ESPHome in Home Assistant.
|
||||
2. Click on the bottom right on "Add Device"
|
||||
3. Click "Continue"
|
||||
4. Give the device a name you can remember (e.g. "Button+ Kitchen") and click "Next"
|
||||
5. Click "Skip This Step"
|
||||
6. Select the "ESP32-S3"
|
||||
7. Click "Skip"
|
||||
8. On the ESPHome main screen find the device you've just created, on the device card click "Edit"
|
||||
9. Find in the links below the initial script for your setup. Copy
|
||||
- [1 BAR 1 Display](../Examples/1BAR_1Display_Basic.yaml)
|
||||
- [2 BAR 1 Display](../Examples/2BAR_1Display_Basic.yaml)
|
||||
- [3 BAR 1 Display](../Examples/3BAR_1Display_Basic.yaml)
|
||||
10. Klik rechts boven in op "Save" en vervolgens op "Install"
|
||||
11. Kies "Plug into this computer" en volg de instructies. Als je Firefox gebruikt kun je ook "Manual Download" kiezen en de image met ESP tool laden
|
||||
|
||||
Na de initiële upload met USB kun je de Button+ met de Wireless optie laden.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Getting Started
|
||||
|
||||
In order to get started with a 3 bar module, you should
|
||||
1. Make sure you have [ESPHome](https://esphome.io) installed
|
||||
2. Copy the file [3pages_TotalExample.yml](/examples/3pages_TotalExample.yml) to the root of the repository
|
||||
3. Create a file secrets.yaml and add the following
|
||||
```
|
||||
wifi_ssid: "YOUR_SSID"
|
||||
wifi_password: "YOUR_PASSWORD"
|
||||
```
|
||||
5. modify the yml file to your liking (optional)
|
||||
6. Compile (Install, manual download) and download in modern format
|
||||
7. Connect the B+ to your computer
|
||||
8. Open a compatible browser such as Chrome and visit https://web.esphome.io
|
||||
9. Load the downloaded file to your device and enjoy
|
||||
@@ -0,0 +1,183 @@
|
||||
packages:
|
||||
remote_package_files:
|
||||
url: https://github.com/dixi83/ESPHome_ButtonPlus
|
||||
files:
|
||||
- 'package/1bar_1display.yaml'
|
||||
ref: main
|
||||
refresh: 1d
|
||||
|
||||
substitutions:
|
||||
nr_of_pages: '1'
|
||||
|
||||
globals:
|
||||
- id: !extend page_names
|
||||
initial_value: '{"Page 1"}'
|
||||
- id: !extend active_page_name
|
||||
initial_value: ""
|
||||
|
||||
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: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
|
||||
- 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"
|
||||
- platform: template
|
||||
name: BAR1 button Right event
|
||||
id: bar1_btn_right_event
|
||||
event_types:
|
||||
- "press page 0"
|
||||
- "release page 0"
|
||||
- "long press page 0"
|
||||
|
||||
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;
|
||||
}
|
||||
on_release:
|
||||
lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
id(bar1_btn_left_event).trigger("release page 0");
|
||||
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;
|
||||
}
|
||||
- id: !extend bar1_btn_right
|
||||
on_click:
|
||||
lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
id(bar1_btn_right_event).trigger("press page 0");
|
||||
break;
|
||||
}
|
||||
on_release:
|
||||
lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
id(bar1_btn_right_event).trigger("release page 0");
|
||||
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;
|
||||
}
|
||||
|
||||
display:
|
||||
#########
|
||||
# MAIN ##
|
||||
#########
|
||||
- id: !extend main_display
|
||||
# data_rate: 40MHz
|
||||
lambda: |-
|
||||
id(all_pages_main).execute();
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
it.print(100, 160, id(font_arial20), "This is page 0!");
|
||||
break;
|
||||
}
|
||||
|
||||
script:
|
||||
- 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());
|
||||
- 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;
|
||||
}
|
||||
- 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;
|
||||
}
|
||||
@@ -4,11 +4,16 @@ packages:
|
||||
files:
|
||||
- 'package/2bar_1display.yaml'
|
||||
ref: main
|
||||
refresh: 10s
|
||||
refresh: 1d
|
||||
|
||||
substitutions:
|
||||
nr_of_pages: '1'
|
||||
|
||||
globals:
|
||||
- id: !extend nr_of_pages
|
||||
initial_value: '1'
|
||||
- id: !extend page_names
|
||||
initial_value: '{"Page 1"}'
|
||||
- id: !extend active_page_name
|
||||
initial_value: ""
|
||||
|
||||
font:
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
@@ -87,7 +92,6 @@ event:
|
||||
- "release page 0"
|
||||
- "long press page 0"
|
||||
|
||||
|
||||
binary_sensor:
|
||||
- id: !extend main_display_btn_left
|
||||
on_click:
|
||||
|
||||
@@ -4,11 +4,16 @@ packages:
|
||||
files:
|
||||
- 'package/3bar_1display.yaml'
|
||||
ref: main
|
||||
refresh: 10s
|
||||
refresh: 1d
|
||||
|
||||
substitutions:
|
||||
nr_of_pages: '1'
|
||||
|
||||
globals:
|
||||
- id: !extend nr_of_pages
|
||||
initial_value: '1'
|
||||
- id: !extend page_names
|
||||
initial_value: '{"Page 1"}'
|
||||
- id: !extend active_page_name
|
||||
initial_value: ""
|
||||
|
||||
font:
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
@@ -101,7 +106,6 @@ event:
|
||||
- "release page 0"
|
||||
- "long press page 0"
|
||||
|
||||
|
||||
binary_sensor:
|
||||
- id: !extend main_display_btn_left
|
||||
on_click:
|
||||
|
||||
+110
-104
@@ -29,6 +29,7 @@ wifi:
|
||||
password: !secret wifi_password
|
||||
|
||||
substitutions:
|
||||
nr_of_pages: '3'
|
||||
music_card_enity_id: 'media_player.media_keuken_2'
|
||||
music_card_text_color: FFFFFF
|
||||
music_card_icon_main_color: FF7F00
|
||||
@@ -40,12 +41,12 @@ packages:
|
||||
files:
|
||||
- 'package/3bar_1display.yaml'
|
||||
- 'package/cards/music.yaml'
|
||||
ref: serialize-displays
|
||||
refresh: 10s
|
||||
ref: main
|
||||
refresh: 1d
|
||||
|
||||
globals:
|
||||
- id: !extend nr_of_pages
|
||||
initial_value: '3'
|
||||
- id: !extend page_names
|
||||
initial_value: '{"page 2","Music","Page 3"}'
|
||||
|
||||
font:
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
@@ -105,80 +106,80 @@ event:
|
||||
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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
- 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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
- 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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
- 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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
- 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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
- 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"
|
||||
- "press page 3"
|
||||
- "release page 3"
|
||||
- "long press page 3"
|
||||
|
||||
binary_sensor:
|
||||
- id: !extend main_display_btn_left
|
||||
@@ -191,29 +192,29 @@ binary_sensor:
|
||||
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");
|
||||
id(music_card_vol_down).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar1_btn_left_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar1_btn_left_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -221,43 +222,43 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar1_btn_left_event).trigger("long press page 3");
|
||||
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");
|
||||
id(music_card_vol_up).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar1_btn_right_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar1_btn_right_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -265,43 +266,43 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar1_btn_right_event).trigger("long press page 3");
|
||||
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");
|
||||
id(music_card_prev).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar2_btn_left_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar2_btn_left_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -309,43 +310,43 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar2_btn_left_event).trigger("long press page 3");
|
||||
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");
|
||||
id(music_card_next).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar2_btn_right_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar2_btn_right_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -353,43 +354,43 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar2_btn_right_event).trigger("long press page 3");
|
||||
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");
|
||||
id(music_card_power).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar3_btn_left_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar3_btn_left_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -397,43 +398,43 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar3_btn_left_event).trigger("long press page 3");
|
||||
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");
|
||||
id(music_card_playpause).execute();
|
||||
break;
|
||||
case 3:
|
||||
id(bar3_btn_right_event).trigger("press page 3");
|
||||
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;
|
||||
case 3:
|
||||
id(bar3_btn_right_event).trigger("release page 3");
|
||||
break;
|
||||
}
|
||||
on_multi_click:
|
||||
- timing:
|
||||
@@ -441,15 +442,15 @@ binary_sensor:
|
||||
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;
|
||||
case 3:
|
||||
id(bar3_btn_right_event).trigger("long press page 3");
|
||||
break;
|
||||
}
|
||||
|
||||
sensor:
|
||||
@@ -488,13 +489,15 @@ display:
|
||||
lambda: |-
|
||||
id(all_pages_main).execute();
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
id(containers).execute();
|
||||
break;
|
||||
case 1:
|
||||
id(music_card).execute(20, 125);
|
||||
id(containers).execute();
|
||||
// Example display item
|
||||
id(displayitem).execute(160,2,"External","size_3_label","orange",id(outside_temperature).state,1,"","size_3_value","white","°C","size_3_unit","grey","TOP_LEFT");
|
||||
break;
|
||||
case 2:
|
||||
id(music_card).execute(20, 125);
|
||||
break;
|
||||
case 3:
|
||||
it.print(100, 160, id(font_arial20), "This is page 3!");
|
||||
break;
|
||||
}
|
||||
@@ -535,6 +538,9 @@ script:
|
||||
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));
|
||||
//
|
||||
//>>> Show page name at bottom of display
|
||||
id(main_display).printf(160, 238, id(font_arial20), id(white), TextAlign::BASELINE_CENTER, "%s", id(active_page_name).c_str());
|
||||
//
|
||||
//>>> 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);
|
||||
@@ -550,13 +556,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("volume_down");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
@@ -564,13 +570,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("volume_up");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
@@ -578,13 +584,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("prev");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
@@ -592,13 +598,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("next");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
@@ -606,13 +612,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("power");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
@@ -620,13 +626,13 @@ script:
|
||||
then:
|
||||
- lambda: |-
|
||||
switch (id(actual_page)){
|
||||
case 0:
|
||||
case 1:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
id(music_card_bar).execute("playpause");
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ packages:
|
||||
url: https://github.com/dixi83/ESPHome_ButtonPlus
|
||||
files: [package/1bar_1display.yaml]
|
||||
ref: main
|
||||
refresh: 10s
|
||||
refresh: 1d
|
||||
|
||||
font:
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
|
||||
*ESPHome documentation and examples to make ESPHome working on the Button+*
|
||||
|
||||
<img src="./Docs/ButtonPlusImage.png" alt="Buttonplus running ESPhome" width="300" height="397"/>
|
||||
|
||||
## Button+
|
||||
|
||||
The Button+ is a modular control panel for home automation systems. It is designed to work with MQTT. It has several modules: a "Base module", a "Main display" and "BAR modules" where the position and amount can be changed according your needs.
|
||||
|
||||
__You can order the Button+ on there [website](https://button.plus).__ this is also the place to find the original firmware, in case you want to revert back.
|
||||
|
||||
To make the Button+ work with ESPHome we needed at least a list of used components and a pinout/IO-list. I spend a couple of evenings with my multimeter, making my wife crazy with the beeps, googled and collected data sheets of the components, broke a the display of 1 BAR module and did a trail-on-error to make stuf work with ESPHome. Here in this repo you'll find the [results](./Components) of my journy.
|
||||
To make the Button+ work with ESPHome we needed at least a list of used components and a pinout/IO-list. I spend a couple of evenings with my multimeter, making my wife crazy with the beeps, googled and collected data sheets of the components, broke a the display of 1 BAR module and did a trail-on-error to make stuff work with ESPHome. Here in this repo you'll find the [results](./Components) of my journey.
|
||||
|
||||
The ESPHome integration adds more flexebility and features, but also add some more complexity. To minimize the complexity I started this repo to collect examples and improve my work.
|
||||
The ESPHome integration adds more flexibility and features, but also add some more complexity. To minimize the complexity I started this repo to collect examples and improve my work.
|
||||
|
||||
> Want to help? Pull requests are welcome!
|
||||
|
||||
@@ -19,29 +21,48 @@ The ESPHome integration adds more flexebility and features, but also add some mo
|
||||
[English support topic on Home Assistant Community:](https://)
|
||||
TODO
|
||||
-->
|
||||
|
||||
## Usefull Links
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation of the Button+ ESPHome integration can be found in the [Docs directory](./Docs/DOCS.md)
|
||||
|
||||
## Useful Links
|
||||
|
||||
* Display Items: https://esphome.io/components/display/
|
||||
* Fonts: https://esphome.io/components/font#display-fonts
|
||||
* Icon's and images: https://esphome.io/components/image#display-image
|
||||
|
||||
## Changes:
|
||||
|
||||
## Documentation
|
||||
### NEXT: 0.2.0
|
||||
#### NEW:
|
||||
- added [display item card](./package/cards/display_item.md) (thanks @balk77)
|
||||
- menu can now be controlled from HA and has page naming (thanks @balk77)
|
||||
- the [music card](./package/cards/music.md) now changes the play/pause icon depending on the players state (thanks @balk77)
|
||||
|
||||
The documentaion of the Button+ ESPHome integration can befound in the [Docs directory](./Docs)
|
||||
#### BREAKING:
|
||||
- global `nr_of_pages` is now replaced by `nr_of_pages` ***substitution***, if you have compile errors please see the basic examples
|
||||
- paging is now indexed by 1 > first page has number 1. Page 0>1, 1>2 etc.
|
||||
|
||||
|
||||
### 0.1.1
|
||||
Serialized the mini displays, by toggling the CS pins we need only 1 display instance now.
|
||||
|
||||
### 0.1.0
|
||||
Created a Package
|
||||
|
||||
### Before 0.1.0
|
||||
versions with first prove of concepts
|
||||
|
||||
## Status
|
||||
|
||||
All the features, i the Buton+ has to offer should work with the [`basic_example.yaml`](./Examples/basic_example.yaml). Please reffer the ESPHome documentaion for more information on how to build your own menu or ... (?)
|
||||
All the features the Button+ has to offer should work with the [`3pages_TotalExample.yaml`](./Examples/3pages_TotalExample.yml). Please refer the ESPHome documentation for more information on how to build your own menu or ... (?)
|
||||
|
||||
The documentaion is yet to be made... Again If you want to help... Pull requests are welcome!
|
||||
The documentation is work in progress.. Again If you want to help... Pull requests are welcome!
|
||||
|
||||
## TODO:
|
||||
|
||||
- [x] Neonleds
|
||||
- [x] figure out how to control them individually. [> maybe with Light Partition](https://esphome.io/components/light/partition)
|
||||
- [x] find correct [type](https://esphome.io/components/light/neopixelbus.html#configuration-variables)
|
||||
- [x] Temperature sensor STS35
|
||||
- [ ] Make a basic [package](https://esphome.io/components/packages.html) so there is less initial code to be copied.
|
||||
- [ ] Documentation
|
||||
- [x] initial firmware load
|
||||
- [ ] links to the card documentation
|
||||
- [ ] More examples
|
||||
|
||||
@@ -113,7 +113,7 @@ output:
|
||||
number: 5
|
||||
mode:
|
||||
output: true
|
||||
inverted: false
|
||||
inverted: true
|
||||
- id: cs_pin_bar1_right
|
||||
platform: gpio
|
||||
pin:
|
||||
@@ -121,7 +121,7 @@ output:
|
||||
number: 1
|
||||
mode:
|
||||
output: true
|
||||
inverted: false
|
||||
inverted: true
|
||||
|
||||
display:
|
||||
####################
|
||||
@@ -130,9 +130,10 @@ display:
|
||||
- id: main_display
|
||||
platform: ili9xxx
|
||||
model: ili9341
|
||||
invert_colors: false
|
||||
color_order: rgb
|
||||
update_interval: 30s
|
||||
invert_colors: false
|
||||
color_palette: 8BIT
|
||||
dc_pin:
|
||||
number: GPIO37
|
||||
allow_other_uses: true
|
||||
@@ -160,6 +161,7 @@ display:
|
||||
allow_other_uses: true
|
||||
invert_colors: false
|
||||
show_test_card: false
|
||||
auto_clear_enabled: false
|
||||
dimensions:
|
||||
height: 160
|
||||
width: 80
|
||||
|
||||
@@ -19,7 +19,7 @@ script:
|
||||
id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_270_DEGREES);
|
||||
id(bar1_left_draw).execute();
|
||||
id(bar_display).update();
|
||||
delay(1);
|
||||
delay(2);
|
||||
id(cs_pin_bar1_left).turn_off();
|
||||
- id: update_bar1_right
|
||||
then:
|
||||
@@ -30,7 +30,7 @@ script:
|
||||
id(bar_display).set_rotation(display::DisplayRotation::DISPLAY_ROTATION_90_DEGREES);
|
||||
id(bar1_right_draw).execute();
|
||||
id(bar_display).update();
|
||||
delay(1);
|
||||
delay(2);
|
||||
id(cs_pin_bar1_right).turn_off();
|
||||
##################################
|
||||
### setup mini display scripts ###
|
||||
@@ -63,19 +63,3 @@ script:
|
||||
- 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
|
||||
|
||||
@@ -165,7 +165,7 @@ output:
|
||||
- id: cs_pin_bar1_left
|
||||
platform: gpio
|
||||
pin:
|
||||
mcp23xxx: base_J1
|
||||
mcp23xxx: base_J2
|
||||
number: 5
|
||||
mode:
|
||||
output: true
|
||||
@@ -173,7 +173,7 @@ output:
|
||||
- id: cs_pin_bar1_right
|
||||
platform: gpio
|
||||
pin:
|
||||
mcp23xxx: base_J1
|
||||
mcp23xxx: base_J2
|
||||
number: 1
|
||||
mode:
|
||||
output: true
|
||||
@@ -181,7 +181,7 @@ output:
|
||||
- id: cs_pin_bar2_left
|
||||
platform: gpio
|
||||
pin:
|
||||
mcp23xxx: base_J2
|
||||
mcp23xxx: base_J3
|
||||
number: 5
|
||||
mode:
|
||||
output: true
|
||||
@@ -189,7 +189,7 @@ output:
|
||||
- id: cs_pin_bar2_right
|
||||
platform: gpio
|
||||
pin:
|
||||
mcp23xxx: base_J2
|
||||
mcp23xxx: base_J3
|
||||
number: 1
|
||||
mode:
|
||||
output: true
|
||||
@@ -202,9 +202,10 @@ display:
|
||||
- id: main_display
|
||||
platform: ili9xxx
|
||||
model: ili9341
|
||||
color_order: rgb
|
||||
invert_colors: false
|
||||
color_order: rgb
|
||||
update_interval: 30s
|
||||
color_palette: 8BIT
|
||||
dc_pin:
|
||||
number: GPIO37
|
||||
allow_other_uses: true
|
||||
@@ -232,6 +233,7 @@ display:
|
||||
allow_other_uses: true
|
||||
invert_colors: false
|
||||
show_test_card: false
|
||||
auto_clear_enabled: false
|
||||
dimensions:
|
||||
height: 160
|
||||
width: 80
|
||||
|
||||
@@ -107,19 +107,3 @@ script:
|
||||
- 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
|
||||
|
||||
@@ -42,7 +42,7 @@ binary_sensor:
|
||||
############################
|
||||
- platform: gpio
|
||||
id: 'main_display_btn_left'
|
||||
name: "Display button Left"
|
||||
name: "Main Display button Left"
|
||||
pin:
|
||||
mcp23xxx: base_J0
|
||||
number: 6
|
||||
@@ -50,7 +50,7 @@ binary_sensor:
|
||||
inverted: true
|
||||
- platform: gpio
|
||||
id: 'main_display_btn_right'
|
||||
name: "Display button Right"
|
||||
name: "Main Display button Right"
|
||||
pin:
|
||||
mcp23xxx: base_J0
|
||||
number: 2
|
||||
@@ -277,6 +277,7 @@ display:
|
||||
invert_colors: false
|
||||
color_order: rgb
|
||||
update_interval: 30s
|
||||
color_palette: 8BIT
|
||||
dc_pin:
|
||||
number: GPIO37
|
||||
allow_other_uses: true
|
||||
@@ -308,4 +309,4 @@ display:
|
||||
dimensions:
|
||||
height: 160
|
||||
width: 80
|
||||
offset_width: 24
|
||||
offset_width: 24
|
||||
|
||||
@@ -154,9 +154,15 @@ script:
|
||||
- id: update_all
|
||||
then:
|
||||
- component.update: main_display
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar1_left
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar1_right
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar2_left
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar2_right
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar3_left
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar3_right
|
||||
|
||||
+50
-17
@@ -13,7 +13,7 @@ esp32:
|
||||
interval:
|
||||
- interval: 1min
|
||||
then:
|
||||
- logger.log: "ESPHome for Button+ v0.1.1"
|
||||
- logger.log: "ESPHome for Button+ v0.2.0_dev"
|
||||
|
||||
i2c:
|
||||
- id: temperature_sensor
|
||||
@@ -29,12 +29,15 @@ spi:
|
||||
mosi_pin: GPIO35
|
||||
|
||||
globals:
|
||||
- id: nr_of_pages
|
||||
type: int
|
||||
initial_value: '1'
|
||||
- id: actual_page
|
||||
type: int
|
||||
initial_value: '0'
|
||||
initial_value: '1'
|
||||
- id: page_names
|
||||
type: std::vector<std::string>
|
||||
initial_value: '{"Page 1"}'
|
||||
- id: active_page_name
|
||||
type: std::string
|
||||
initial_value: ""
|
||||
|
||||
output:
|
||||
- platform: ledc
|
||||
@@ -57,7 +60,17 @@ sensor:
|
||||
name: "Temperature"
|
||||
address: 0x4A
|
||||
update_interval: 10s
|
||||
|
||||
- platform: template
|
||||
name: "Active Page ID"
|
||||
id: active_page_id_ha
|
||||
update_interval: never
|
||||
|
||||
text_sensor:
|
||||
- platform: template
|
||||
name: "Active Page Name"
|
||||
id: active_page_name_ha
|
||||
update_interval: never
|
||||
|
||||
light:
|
||||
- platform: neopixelbus
|
||||
id: neopixels
|
||||
@@ -82,23 +95,43 @@ time:
|
||||
- platform: homeassistant
|
||||
id: datetime
|
||||
|
||||
number:
|
||||
# Creates a number entity in Home Assistant
|
||||
# It sets the menu of the Button Plus
|
||||
- platform: template
|
||||
name: "Menu Selector"
|
||||
id: menu_selector
|
||||
optimistic: true
|
||||
min_value: 1
|
||||
max_value: ${nr_of_pages}
|
||||
step: 1
|
||||
on_value:
|
||||
then:
|
||||
- globals.set:
|
||||
id: actual_page
|
||||
value: !lambda 'return x;'
|
||||
- script.execute: update_page_naming
|
||||
- script.execute: update_all
|
||||
|
||||
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
|
||||
- number.increment:
|
||||
id: menu_selector
|
||||
- id: prev_page
|
||||
then:
|
||||
- number.decrement:
|
||||
id: menu_selector
|
||||
- id: update_page_naming
|
||||
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
|
||||
id(active_page_name) = id(page_names)[id(actual_page) - 1];
|
||||
- sensor.template.publish:
|
||||
id: active_page_id_ha
|
||||
state: !lambda 'return id(actual_page);'
|
||||
- text_sensor.template.publish:
|
||||
id: active_page_name_ha
|
||||
state: !lambda 'return id(active_page_name);'
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# ESPHome Button+ - Music card
|
||||
|
||||
## Usage
|
||||
|
||||
* Add the music card file to the package files
|
||||
```
|
||||
package:
|
||||
remote_package_files:
|
||||
url: https://github.com/dixi83/ESPHome_ButtonPlus
|
||||
files: [<other files>,'package/cards/display_item.yaml']
|
||||
```
|
||||
* Add the display item card to the (main) display `lambda` and give it the position and [parameters](#parameters) you want
|
||||
It requires fonts and colors to be defined, this can be called as lambda, for instance:
|
||||
```
|
||||
//id(display_item).execute(x, y, label, labelfont, labelcolor, valuenum, decimals, valuestr, valuefont, valuecolor, unit, unitfont, unitcolor, align)
|
||||
id(display_item).execute(160, 2, "External", "size_3_label", "orange", id(outside_temperature).state, 1, "", "size_3_value", "white", "°C", "size_3_unit", "grey", "TOP_LEFT");
|
||||
```
|
||||
This will position a block with label "External" in size 3 and color orange, below that a value with 1 decimal, in white, size 3. Next to that unit "°C", size 3 in grey, anchored at x,y = 160,2 top left corner
|
||||
|
||||
|
||||
## Parameters:
|
||||
|
||||
```
|
||||
x: int x of anchor point
|
||||
y: int y of anchor point
|
||||
label: string label, to be shown above the value
|
||||
labelfont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
labelcolor: string any of white, orange, red, green or grey
|
||||
valuenum: float value to display (numerical)
|
||||
decimals: int rounding of value to display
|
||||
valuestr: string if left empty it will select display the value float
|
||||
valuefont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
valuecolor: string any of white, orange, red, green or grey
|
||||
unit: string displayed unit
|
||||
unitfont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
unitcolor: string any of white, orange, red, green or grey
|
||||
align: string TOP_LEFT, TOP_CENTER or TOP_RIGHT
|
||||
```
|
||||
@@ -0,0 +1,210 @@
|
||||
|
||||
#####################################################
|
||||
##
|
||||
## FILENAME: cards/display_item.yaml
|
||||
## NAME: Display item constructor
|
||||
## DESCRIPTION: creates display items like
|
||||
## the original firmware
|
||||
## PARAMETERS:
|
||||
## x: int x of anchor point
|
||||
## y: int y of anchor point
|
||||
## label: string label, to be shown above the value
|
||||
## labelfont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
## labelcolor: string any of white, orange, red, green or grey
|
||||
## valuenum: float value to display (numerical)
|
||||
## decimals: int rounding of value to display
|
||||
## valuestr: string if left empty it will select display the value float
|
||||
## valuefont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
## valuecolor: string any of white, orange, red, green or grey
|
||||
## unit: string displayed unit
|
||||
## unitfont: string any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
## unitcolor: string any of white, orange, red, green or grey
|
||||
## align: string TOP_LEFT, TOP_CENTER or TOP_RIGHT
|
||||
## USAGE:
|
||||
## package:
|
||||
## remote_package_files:
|
||||
## url: https://github.com/dixi83/ESPHome_ButtonPlus
|
||||
## files: [<other files>,'package/cards/display_item.yaml']
|
||||
##
|
||||
## display:
|
||||
## - id: !extend main_display
|
||||
## lambda: |-
|
||||
## id(display_item).execute(160,2,"External","size_3_label","orange",id(outside_temperature).state,1,"","size_3_value","white","°C","size_3_unit","grey","TOP_LEFT");
|
||||
##
|
||||
#####################################################
|
||||
|
||||
font:
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_1_label
|
||||
size: 10
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_2_label
|
||||
size: 12
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_3_label
|
||||
size: 14
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_1_value
|
||||
size: 15
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_2_value
|
||||
size: 20
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_3_value
|
||||
size: 20
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_1_unit
|
||||
size: 15
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_2_unit
|
||||
size: 20
|
||||
bpp: 4
|
||||
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
|
||||
id: display_item_size_3_unit
|
||||
size: 20
|
||||
bpp: 4
|
||||
|
||||
color:
|
||||
- id: display_item_red
|
||||
hex: FF0000
|
||||
- id: display_item_blue
|
||||
hex: 0000FF
|
||||
- id: display_item_yellow
|
||||
hex: FFFF00
|
||||
- id: display_item_green
|
||||
hex: 00FF00
|
||||
- id: display_item_orange
|
||||
hex: FF7F00
|
||||
- id: display_item_white
|
||||
hex: FFFFFF
|
||||
- id: display_item_grey
|
||||
hex: A6A6A6
|
||||
|
||||
script:
|
||||
- id: display_item
|
||||
parameters:
|
||||
x: int # x of anchor point
|
||||
y: int # y of anchor point
|
||||
label: string # label, to be shown above the value
|
||||
labelfont: string # any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
labelcolor: string # any of white, orange, red, green or grey
|
||||
valuenum: float # value to display (numerical)
|
||||
decimals: int # rounding of value to display
|
||||
valuestr: string # if left empty it will select display the value float
|
||||
valuefont: string # any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
valuecolor: string # any of white, orange, red, green or grey
|
||||
unit: string # displayed unit
|
||||
unitfont: string # any of size_1_value, size_2_unit, size_3_label and everything in between
|
||||
unitcolor: string # any of white, orange, red, green or grey
|
||||
align: string # TOP_LEFT, TOP_CENTER or TOP_RIGHT
|
||||
then:
|
||||
lambda: |-
|
||||
// Helper to get the font object from its ID string
|
||||
// This lambda function maps font ID strings to their corresponding font objects.
|
||||
// If the provided font_id matches a known font, it returns the appropriate font object.
|
||||
// Otherwise, it returns nullptr.
|
||||
auto get_font = [](const std::string &font_id) -> esphome::font::Font* {
|
||||
if (font_id == "size_1_value") return id(display_item_size_1_value);
|
||||
if (font_id == "size_1_label") return id(display_item_size_1_label);
|
||||
if (font_id == "size_1_unit") return id(display_item_size_1_unit);
|
||||
if (font_id == "size_2_value") return id(display_item_size_2_value);
|
||||
if (font_id == "size_2_label") return id(display_item_size_2_label);
|
||||
if (font_id == "size_2_unit") return id(display_item_size_2_unit);
|
||||
if (font_id == "size_3_value") return id(display_item_size_3_value);
|
||||
if (font_id == "size_3_label") return id(display_item_size_3_label);
|
||||
if (font_id == "size_3_unit") return id(display_item_size_3_unit);
|
||||
return nullptr; // Return nullptr if the font ID doesn't match any known font.
|
||||
};
|
||||
|
||||
auto get_color = [](const std::string &color_id) -> esphome::Color {
|
||||
if (color_id == "white") return id(display_item_white);
|
||||
if (color_id == "blue") return id(display_item_blue);
|
||||
if (color_id == "orange") return id(display_item_orange);
|
||||
if (color_id == "red") return id(display_item_red);
|
||||
if (color_id == "green") return id(display_item_green);
|
||||
if (color_id == "grey") return id(display_item_grey);
|
||||
return esphome::Color::WHITE; // Default color if no match
|
||||
};
|
||||
|
||||
esphome::Color labelcolor_script = get_color(labelcolor);
|
||||
esphome::Color valuecolor_script = get_color(valuecolor);
|
||||
esphome::Color unitcolor_script = get_color(unitcolor);
|
||||
|
||||
// Resolve font objects based on the provided font IDs.
|
||||
// These objects will later be used to measure text dimensions and render text on the display.
|
||||
auto *labelfont_obj = get_font(labelfont);
|
||||
auto *valuefont_obj = get_font(valuefont);
|
||||
auto *unitfont_obj = get_font(unitfont);
|
||||
|
||||
// Format the numeric value as a string with the specified number of decimals.
|
||||
// snprintf safely formats the float into a fixed-width character buffer.
|
||||
char value_str[40];
|
||||
// Check if valuestr is not empty
|
||||
if (valuestr.empty()) { // Check if valuestr has any content
|
||||
snprintf(value_str, sizeof(value_str), "%.*f", decimals, valuenum);
|
||||
} else {
|
||||
// If valuestr is empty, copy a default or alternative string into value_str
|
||||
strncpy(value_str, valuestr.c_str(), sizeof(value_str)); // Example default value
|
||||
value_str[sizeof(value_str) - 1] = '\0'; // Ensure null-termination
|
||||
}
|
||||
|
||||
// Helper function to calculate text dimensions.
|
||||
// This lambda takes a font object and a text string as input,
|
||||
// and it calculates the text's width and height (returned via reference parameters).
|
||||
auto calculate_text_dimensions = [](esphome::font::Font *font, const char *text, int &width, int &baseline) {
|
||||
int x_offset = 0, height = 0;
|
||||
font->measure(text, &width, &x_offset, &baseline, &height);
|
||||
};
|
||||
|
||||
// Calculate the dimensions of the label text.
|
||||
int label_width = 0, label_height = 0;
|
||||
calculate_text_dimensions(labelfont_obj, label.c_str(), label_width, label_height);
|
||||
|
||||
// Calculate the dimensions of the value text.
|
||||
int value_width = 0, value_height = 0;
|
||||
calculate_text_dimensions(valuefont_obj, value_str, value_width, value_height);
|
||||
|
||||
// Calculate the dimensions of the unit text.
|
||||
int unit_width = 0, unit_height = 0;
|
||||
calculate_text_dimensions(unitfont_obj, unit.c_str(), unit_width, unit_height);
|
||||
|
||||
if (align == "TOP_RIGHT" ){
|
||||
// Render the label on the display at the specified position (x, y).
|
||||
id(main_display).printf(x, y, labelfont_obj, labelcolor_script, TextAlign::TOP_RIGHT, "%s", label.c_str());
|
||||
|
||||
// Render the value below the label with a vertical offset equal to the label's height.
|
||||
id(main_display).printf(x - unit_width, y - 2 + label_height , valuefont_obj, valuecolor_script, TextAlign::TOP_RIGHT, "%s", value_str);
|
||||
|
||||
// Render the unit text to the right of the value text with appropriate offsets.
|
||||
id(main_display).printf(x, y - 2 + label_height + value_height - unit_height, unitfont_obj, unitcolor_script, TextAlign::TOP_RIGHT, "%s", unit.c_str());
|
||||
} else if (align == "TOP_CENTER" ){
|
||||
// Calculate the maximum width of the display item, being the label or value+unit
|
||||
// subtract half of that from the anchor point and position based on top left corner of the text fields
|
||||
int offset = (std::max(label_width, value_width + unit_width) + 1) / 2;
|
||||
|
||||
// Render the label on the display at the specified position (x, y).
|
||||
id(main_display).printf(x - offset, y, labelfont_obj, labelcolor_script, TextAlign::TOP_LEFT, "%s", label.c_str());
|
||||
|
||||
// Render the value below the label with a vertical offset equal to the label's height.
|
||||
id(main_display).printf(x - offset, y - 2 + label_height , valuefont_obj, valuecolor_script, TextAlign::TOP_LEFT, "%s", value_str);
|
||||
|
||||
// Render the unit text to the right of the value text with appropriate offsets.
|
||||
id(main_display).printf(x - offset + value_width, y -2+ label_height + value_height - unit_height, unitfont_obj, unitcolor_script, TextAlign::TOP_LEFT, "%s", unit.c_str());
|
||||
} else {
|
||||
// Render the label on the display at the specified position (x, y).
|
||||
id(main_display).printf(x, y, labelfont_obj, labelcolor_script, TextAlign::TOP_LEFT, "%s", label.c_str());
|
||||
|
||||
// Render the value below the label with a vertical offset equal to the label's height.
|
||||
id(main_display).printf(x, y - 2 + label_height , valuefont_obj, valuecolor_script, TextAlign::TOP_LEFT, "%s", value_str);
|
||||
|
||||
// Render the unit text to the right of the value text with appropriate offsets.
|
||||
id(main_display).printf(x + value_width, y - 2 + label_height + value_height - unit_height , unitfont_obj, unitcolor_script, TextAlign::TOP_LEFT, "%s", unit.c_str());
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Usage
|
||||
|
||||
* Add the music card file to youre files and supply the `entity_id`
|
||||
* Add the music card file to the package files and supply the `entity_id`
|
||||
```
|
||||
substitutions:
|
||||
music_card_enity_id: 'media_player.media_keuken_2'
|
||||
|
||||
+36
-14
@@ -14,66 +14,84 @@
|
||||
##
|
||||
## 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
|
||||
## lambda: |-
|
||||
## id(music_card).execute(20, 125);
|
||||
##
|
||||
#####################################################
|
||||
|
||||
image:
|
||||
- file: mdi:music-box-outline
|
||||
type: binary
|
||||
id: icon_music_album
|
||||
resize: 20x20
|
||||
- file: mdi:account-music
|
||||
type: binary
|
||||
id: icon_music_artist
|
||||
resize: 20x20
|
||||
- file: mdi:music-note
|
||||
type: binary
|
||||
id: icon_music_songtitle
|
||||
resize: 20x20
|
||||
- file: mdi:power-off
|
||||
type: binary
|
||||
id: icon_music_off
|
||||
resize: 75x75
|
||||
- file: mdi:power-on
|
||||
type: binary
|
||||
id: icon_music_on
|
||||
resize: 75x75
|
||||
- file: mdi:power
|
||||
type: binary
|
||||
id: icon_music_power
|
||||
resize: 75x75
|
||||
- file: mdi:timer-sand-empty
|
||||
type: binary
|
||||
id: icon_music_idle
|
||||
resize: 75x75
|
||||
- file: mdi:play-pause
|
||||
type: binary
|
||||
id: icon_music_playpause
|
||||
resize: 75x75
|
||||
- file: mdi:play-box-outline
|
||||
id: icon_music_play
|
||||
type: binary
|
||||
id: icon_music_play_box
|
||||
resize: 75x75
|
||||
- file: mdi:pause-box-outline
|
||||
id: icon_music_pause
|
||||
type: binary
|
||||
id: icon_music_pause_box
|
||||
resize: 75x75
|
||||
- file: mdi:power
|
||||
type: binary
|
||||
id: icon_music_standby
|
||||
resize: 75x75
|
||||
- file: mdi:download-box-outline
|
||||
type: binary
|
||||
id: icon_music_buffering
|
||||
resize: 75x75
|
||||
- file: mdi:volume-plus
|
||||
type: binary
|
||||
id: icon_music_vol_up
|
||||
resize: 75x75
|
||||
- file: mdi:volume-minus
|
||||
type: binary
|
||||
id: icon_music_vol_down
|
||||
resize: 75x75
|
||||
- file: mdi:skip-forward
|
||||
type: binary
|
||||
id: icon_music_next
|
||||
resize: 75x75
|
||||
- file: mdi:skip-backward
|
||||
type: binary
|
||||
id: icon_music_prev
|
||||
resize: 75x75
|
||||
- file: mdi:play
|
||||
type: binary
|
||||
id: icon_music_play
|
||||
resize: 75x75
|
||||
- file: mdi:pause
|
||||
type: binary
|
||||
id: icon_music_pause
|
||||
resize: 75x75
|
||||
|
||||
color:
|
||||
- id: music_card_text_color
|
||||
@@ -106,7 +124,7 @@ text_sensor:
|
||||
id: music_playerstate
|
||||
entity_id: ${music_card_enity_id}
|
||||
on_value:
|
||||
- script.execute: update_main
|
||||
- script.execute: update_all
|
||||
|
||||
script:
|
||||
- id: music_card
|
||||
@@ -123,9 +141,9 @@ script:
|
||||
} 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));
|
||||
id(main_display).image(x, 1+y, id(icon_music_play_box), 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));
|
||||
id(main_display).image(x, 1+y, id(icon_music_pause_box), 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) {
|
||||
@@ -157,7 +175,11 @@ script:
|
||||
} 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));
|
||||
if (strcmp(id(music_playerstate).state.c_str(), "playing") == 0) {
|
||||
id(bar_display).image(80, 2, id(icon_music_pause), ImageAlign::TOP_CENTER, id(music_card_icon_bar_color));
|
||||
} else {
|
||||
id(bar_display).image(80, 2, id(icon_music_play), 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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user