Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efc3feb031 | ||
|
|
1ec3e1879f | ||
|
|
7ae92918d3 | ||
|
|
aa58222296 | ||
|
|
b12b6a7d69 | ||
|
|
088db53a47 | ||
|
|
92ed59f869 | ||
|
|
51bdcac3e0 | ||
|
|
34c06a3e0b | ||
|
|
279319ed0c | ||
|
|
ec3acfe28e | ||
|
|
0bdb67e20e | ||
|
|
3e4654b4e0 | ||
|
|
f1e722cd3b | ||
|
|
01020a20d0 | ||
|
|
147a99cd8a | ||
|
|
868cf2ab70 | ||
|
|
0752709e09 | ||
|
|
cc88e7ba21 | ||
|
|
6525a0b400 | ||
|
|
e46215e7fb | ||
|
|
3b5cbb362c | ||
|
|
6bc1297eab | ||
|
|
95657fcb08 | ||
|
|
302c4a88f8 | ||
|
|
6de0d94dca | ||
|
|
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 |
@@ -0,0 +1 @@
|
||||
.vscode/settings.json
|
||||
+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.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# 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
|
||||
@@ -6,9 +6,14 @@ packages:
|
||||
ref: main
|
||||
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"
|
||||
|
||||
@@ -6,9 +6,14 @@ packages:
|
||||
ref: main
|
||||
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"
|
||||
|
||||
@@ -6,9 +6,14 @@ packages:
|
||||
ref: main
|
||||
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"
|
||||
|
||||
+105
-108
@@ -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
|
||||
@@ -44,14 +45,8 @@ packages:
|
||||
refresh: 1d
|
||||
|
||||
globals:
|
||||
- id: !extend nr_of_pages
|
||||
initial_value: '3'
|
||||
- id: page_names
|
||||
type: std::vector<std::string>
|
||||
initial_value: '{"Page 1","Music","Page 3"}'
|
||||
- id: active_page_name
|
||||
type: std::string
|
||||
initial_value: ""
|
||||
- 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"
|
||||
@@ -111,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
|
||||
@@ -197,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:
|
||||
@@ -227,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:
|
||||
@@ -271,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:
|
||||
@@ -315,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:
|
||||
@@ -359,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:
|
||||
@@ -403,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:
|
||||
@@ -447,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:
|
||||
@@ -494,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;
|
||||
}
|
||||
@@ -559,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;
|
||||
}
|
||||
@@ -573,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;
|
||||
}
|
||||
@@ -587,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;
|
||||
}
|
||||
@@ -601,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;
|
||||
}
|
||||
@@ -615,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;
|
||||
}
|
||||
@@ -629,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;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ The Button+ is a modular control panel for home automation systems. It is design
|
||||
|
||||
__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!
|
||||
|
||||
@@ -21,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
|
||||
|
||||
@@ -133,6 +133,7 @@ display:
|
||||
invert_colors: false
|
||||
color_order: rgb
|
||||
update_interval: 30s
|
||||
color_palette: 8BIT
|
||||
dc_pin:
|
||||
number: GPIO37
|
||||
allow_other_uses: true
|
||||
|
||||
@@ -61,8 +61,5 @@ script:
|
||||
- id: update_all
|
||||
then:
|
||||
- component.update: main_display
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar1_left
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar1_right
|
||||
- delay: 0.1s
|
||||
|
||||
@@ -205,6 +205,7 @@ display:
|
||||
invert_colors: false
|
||||
color_order: rgb
|
||||
update_interval: 30s
|
||||
color_palette: 8BIT
|
||||
dc_pin:
|
||||
number: GPIO37
|
||||
allow_other_uses: true
|
||||
|
||||
@@ -103,12 +103,7 @@ script:
|
||||
- id: update_all
|
||||
then:
|
||||
- component.update: main_display
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar1_left
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar1_right
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar2_left
|
||||
- delay: 0.1s
|
||||
- script.execute: update_bar2_right
|
||||
- delay: 0.1s
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -154,15 +154,15 @@ script:
|
||||
- id: update_all
|
||||
then:
|
||||
- component.update: main_display
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar1_left
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar1_right
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar2_left
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar2_right
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar3_left
|
||||
- delay: 0.1s
|
||||
- delay: 5ms
|
||||
- script.execute: update_bar3_right
|
||||
|
||||
+23
-36
@@ -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
|
||||
@@ -93,25 +96,22 @@ time:
|
||||
id: datetime
|
||||
|
||||
number:
|
||||
## Creates a number entity in Home Assistant
|
||||
# Creates a number entity in Home Assistant
|
||||
# It sets the menu of the Button Plus
|
||||
- platform: template
|
||||
name: "Menu Selector"
|
||||
id: menuselector
|
||||
id: menu_selector
|
||||
optimistic: true
|
||||
min_value: 0 # keep at 0
|
||||
max_value: 10 # TODO replace page numbers with substitution
|
||||
min_value: 1
|
||||
max_value: ${nr_of_pages}
|
||||
step: 1
|
||||
on_value:
|
||||
then:
|
||||
- lambda: |-
|
||||
if(id(menuselector).state >= id(nr_of_pages)) {
|
||||
id(actual_page) = id(nr_of_pages)-1;
|
||||
} else {
|
||||
id(actual_page) = id(menuselector).state;
|
||||
}
|
||||
# # Refresh the screen
|
||||
# - script.execute: update_page <<< this ends in an loop...
|
||||
- globals.set:
|
||||
id: actual_page
|
||||
value: !lambda 'return x;'
|
||||
- script.execute: update_page_naming
|
||||
- script.execute: update_all
|
||||
|
||||
script:
|
||||
######################
|
||||
@@ -119,32 +119,19 @@ script:
|
||||
######################
|
||||
- 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_page
|
||||
- number.increment:
|
||||
id: menu_selector
|
||||
- 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_page
|
||||
- id: update_page
|
||||
- number.decrement:
|
||||
id: menu_selector
|
||||
- id: update_page_naming
|
||||
then:
|
||||
- lambda: |-
|
||||
id(active_page_name) = id(page_names)[id(actual_page)];
|
||||
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);'
|
||||
- number.set:
|
||||
id: menuselector
|
||||
value: !lambda 'return id(actual_page);'
|
||||
- script.execute: update_all
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -14,70 +14,82 @@
|
||||
##
|
||||
## 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
|
||||
type: binary
|
||||
id: icon_music_play_box
|
||||
resize: 75x75
|
||||
- file: mdi:pause-box-outline
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user