59 Commits
Author SHA1 Message Date
Martijn efc3feb031 Merge pull request #17 from dixi83/dev_arduino_framework_3.x
merge: Dev arduino framework 3.x
2025-11-27 21:50:33 +01:00
Martijn 1ec3e1879f added 'color_palette' 2025-11-27 21:47:29 +01:00
Martijn 7ae92918d3 added 'color_palette' 2025-11-27 21:27:30 +01:00
Martijn aa58222296 Revert "try inverted"
This reverts commit b12b6a7d69.
2025-11-27 21:03:42 +01:00
Martijn b12b6a7d69 try inverted 2025-11-26 20:23:10 +01:00
Martijn 088db53a47 Revert "display invert"
This reverts commit 34c06a3e0b.
2025-11-26 18:22:19 +01:00
Martijn 92ed59f869 Merge branch 'dev_arduino_framework_3.x' of https://github.com/dixi83/ESPhome_ButtonPlus into dev_arduino_framework_3.x 2025-11-26 18:13:24 +01:00
Martijn 51bdcac3e0 display invert 2025-11-26 18:07:48 +01:00
Martijn 34c06a3e0b display invert 2025-11-26 16:37:12 +01:00
Martijn 279319ed0c Merge pull request #16 from dixi83/main
update README from main
2025-11-26 14:28:22 +01:00
Martijn ec3acfe28e added type: binary 2025-10-18 14:37:36 +02:00
Martijn 0bdb67e20e update _all should be done at latest to show the most actual data 2024-12-30 12:11:43 +01:00
Martijn 3e4654b4e0 updated todo list changed doc link 2024-12-30 12:11:01 +01:00
Martijn f1e722cd3b added links to cards documentation and added change to the music card 2024-12-29 18:32:57 +01:00
Martijn 01020a20d0 added some missing id's 2024-12-29 17:42:04 +01:00
Martijn 147a99cd8a increase version number 2024-12-29 16:13:15 +01:00
Martijn 868cf2ab70 Merge pull request #13 from dixi83/main
merge music card changes to dev
2024-12-29 16:05:53 +01:00
Martijn 0752709e09 Merge pull request #12 from dixi83/dev-cards
New display item card to dev branche
2024-12-29 16:03:30 +01:00
Martijn cc88e7ba21 Update base.yaml 2024-12-29 16:03:09 +01:00
Martijn 6525a0b400 Update base.yaml 2024-12-29 15:54:43 +01:00
Martijn e46215e7fb updated readme and example to match new changes 2024-12-29 15:36:08 +01:00
Martijn 3b5cbb362c added display item card 2024-12-29 15:06:38 +01:00
Martijn 6bc1297eab made it equal with the main branch 2024-12-29 15:06:12 +01:00
Martijn 95657fcb08 simplified/corrected some instructions on the music card 2024-12-29 15:05:06 +01:00
Martijn 302c4a88f8 local settings should not be in the repo 2024-12-29 15:04:17 +01:00
Martijn 6de0d94dca Merge pull request #9 from balk77/balk77-patch-1
Addition of display item script
- [ ] @dixi83 convert to card
2024-12-29 11:31:44 +01:00
Martijn 34ef0d0f99 11 2024-12-27 22:28:40 +01:00
Martijn c1cde0f159 10 2024-12-27 22:23:01 +01:00
Martijn e81582f7da 9 2024-12-27 22:15:36 +01:00
Martijn c5bdb903c0 8 2024-12-27 22:14:47 +01:00
Martijn b726af5c72 7 2024-12-27 22:12:39 +01:00
Martijn 6531708579 6 2024-12-27 22:05:20 +01:00
Martijn 262bb7dd0d 6 2024-12-27 22:04:36 +01:00
Martijn c345fe0f0b 5 2024-12-27 22:01:15 +01:00
Martijn 485fa923fb 4 2024-12-27 21:53:46 +01:00
Martijn c03360a381 3 2024-12-27 21:45:26 +01:00
Martijn 72ce117299 2 2024-12-27 21:41:12 +01:00
Martijn 8815f5e113 paging is now indexed on 1 2024-12-27 21:36:39 +01:00
Martijn 13763326ce test 2024-12-27 21:29:47 +01:00
Martijn 3fa067ba37 test 2024-12-27 21:26:27 +01:00
Martijn b1271c8c12 substitution cannot be a string? 2024-12-27 21:14:13 +01:00
Martijn bf606810b7 test 2024-12-27 21:12:26 +01:00
Martijn aa262f7546 test 2024-12-27 21:06:51 +01:00
Martijn 54d1e432f3 semicolon 2024-12-27 21:00:33 +01:00
Martijn 1b2e11ed8c typo 2024-12-27 20:59:18 +01:00
Martijn 946ae2c6d1 simplified paging logic 2024-12-27 20:58:13 +01:00
Martijn db555ce359 it does not like the value being written somehow... 2024-12-27 20:49:09 +01:00
Martijn 7b238ac2d8 test if casting works 2024-12-27 20:44:46 +01:00
Martijn 6de381b32f test if number is working now 2024-12-27 20:25:51 +01:00
Martijn aaa1d6421d prev commit kept working, failure is in script.update_page 2024-12-27 20:20:29 +01:00
Martijn ae34e28ed2 prev commit made the device running again... 2024-12-27 20:13:30 +01:00
Martijn f0a99c50fd test 2024-12-27 20:10:57 +01:00
Martijn 5efc0b7671 test dev 2024-12-27 20:08:56 +01:00
Martijn 11a0ef1ff0 Updated documentation 2024-12-27 19:59:31 +01:00
Martijn 8f460f5cb9 keep personal settings out of the repo 2024-12-27 19:58:58 +01:00
Martijn 4536e15b7b page update is now out of the loop. 2024-12-27 19:58:18 +01:00
Martijn 46c003cf08 nr_of_pages is now a substitution, page_names is now a global 2024-12-27 19:56:25 +01:00
balk77 0446120b22 Example display item 2024-12-25 18:33:52 +01:00
balk77 f4f8ba7df9 Addition of display item constructor 2024-12-25 18:28:07 +01:00
19 changed files with 491 additions and 188 deletions
+1
View File
@@ -0,0 +1 @@
.vscode/settings.json
+30 -2
View File
@@ -2,6 +2,34 @@
*work in progress* *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 # Getting Started
In order to get started with a 3 bar module, you should In order to get started with a 3 bar module, you should
1. Make sure you have [ESPHome](https://esphome.io) installed 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 2. Copy the file [3pages_TotalExample.yml](/examples/3pages_TotalExample.yml) to the root of the repository
+7 -2
View File
@@ -6,9 +6,14 @@ packages:
ref: main ref: main
refresh: 1d refresh: 1d
substitutions:
nr_of_pages: '1'
globals: globals:
- id: !extend nr_of_pages - id: !extend page_names
initial_value: '1' initial_value: '{"Page 1"}'
- id: !extend active_page_name
initial_value: ""
font: font:
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
+7 -2
View File
@@ -6,9 +6,14 @@ packages:
ref: main ref: main
refresh: 1d refresh: 1d
substitutions:
nr_of_pages: '1'
globals: globals:
- id: !extend nr_of_pages - id: !extend page_names
initial_value: '1' initial_value: '{"Page 1"}'
- id: !extend active_page_name
initial_value: ""
font: font:
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
+7 -2
View File
@@ -6,9 +6,14 @@ packages:
ref: main ref: main
refresh: 1d refresh: 1d
substitutions:
nr_of_pages: '1'
globals: globals:
- id: !extend nr_of_pages - id: !extend page_names
initial_value: '1' initial_value: '{"Page 1"}'
- id: !extend active_page_name
initial_value: ""
font: font:
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" - file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf"
+105 -108
View File
@@ -29,6 +29,7 @@ wifi:
password: !secret wifi_password password: !secret wifi_password
substitutions: substitutions:
nr_of_pages: '3'
music_card_enity_id: 'media_player.media_keuken_2' music_card_enity_id: 'media_player.media_keuken_2'
music_card_text_color: FFFFFF music_card_text_color: FFFFFF
music_card_icon_main_color: FF7F00 music_card_icon_main_color: FF7F00
@@ -44,14 +45,8 @@ packages:
refresh: 1d refresh: 1d
globals: globals:
- id: !extend nr_of_pages - id: !extend page_names
initial_value: '3' initial_value: '{"page 2","Music","Page 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: ""
font: font:
- file: "https://github.com/web-fonts/ttf/raw/refs/heads/master/bpg-ingiri-arial-webfont.ttf" - 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 name: BAR1 button Left event
id: bar1_btn_left_event id: bar1_btn_left_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
- platform: template - platform: template
name: BAR1 button Right event name: BAR1 button Right event
id: bar1_btn_right_event id: bar1_btn_right_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
- platform: template - platform: template
name: BAR2 button Left event name: BAR2 button Left event
id: bar2_btn_left_event id: bar2_btn_left_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
- platform: template - platform: template
name: BAR2 button Right event name: BAR2 button Right event
id: bar2_btn_right_event id: bar2_btn_right_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
- platform: template - platform: template
name: BAR3 button Left event name: BAR3 button Left event
id: bar3_btn_left_event id: bar3_btn_left_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
- platform: template - platform: template
name: BAR3 button Right event name: BAR3 button Right event
id: bar3_btn_right_event id: bar3_btn_right_event
event_types: event_types:
- "press page 0"
- "release page 0"
- "long press page 0"
- "press page 1" - "press page 1"
- "release page 1" - "release page 1"
- "long press page 1" - "long press page 1"
- "press page 2" - "press page 2"
- "release page 2" - "release page 2"
- "long press page 2" - "long press page 2"
- "press page 3"
- "release page 3"
- "long press page 3"
binary_sensor: binary_sensor:
- id: !extend main_display_btn_left - id: !extend main_display_btn_left
@@ -197,29 +192,29 @@ binary_sensor:
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_left_event).trigger("press page 0");
break;
case 1: case 1:
id(bar1_btn_left_event).trigger("press page 1"); id(bar1_btn_left_event).trigger("press page 1");
id(music_card_vol_down).execute();
break; break;
case 2: case 2:
id(bar1_btn_left_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_left_event).trigger("release page 0");
break;
case 1: case 1:
id(bar1_btn_left_event).trigger("release page 1"); id(bar1_btn_left_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar1_btn_left_event).trigger("release page 2"); id(bar1_btn_left_event).trigger("release page 2");
break; break;
case 3:
id(bar1_btn_left_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -227,43 +222,43 @@ binary_sensor:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_left_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar1_btn_left_event).trigger("long press page 1"); id(bar1_btn_left_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar1_btn_left_event).trigger("long press page 2"); id(bar1_btn_left_event).trigger("long press page 2");
break; break;
case 3:
id(bar1_btn_left_event).trigger("long press page 3");
break;
} }
- id: !extend bar1_btn_right - id: !extend bar1_btn_right
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_right_event).trigger("press page 0");
break;
case 1: case 1:
id(bar1_btn_right_event).trigger("press page 1"); id(bar1_btn_right_event).trigger("press page 1");
id(music_card_vol_up).execute();
break; break;
case 2: case 2:
id(bar1_btn_right_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_right_event).trigger("release page 0");
break;
case 1: case 1:
id(bar1_btn_right_event).trigger("release page 1"); id(bar1_btn_right_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar1_btn_right_event).trigger("release page 2"); id(bar1_btn_right_event).trigger("release page 2");
break; break;
case 3:
id(bar1_btn_right_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -271,43 +266,43 @@ binary_sensor:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar1_btn_right_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar1_btn_right_event).trigger("long press page 1"); id(bar1_btn_right_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar1_btn_right_event).trigger("long press page 2"); id(bar1_btn_right_event).trigger("long press page 2");
break; break;
case 3:
id(bar1_btn_right_event).trigger("long press page 3");
break;
} }
- id: !extend bar2_btn_left - id: !extend bar2_btn_left
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_left_event).trigger("press page 0");
break;
case 1: case 1:
id(bar2_btn_left_event).trigger("press page 1"); id(bar2_btn_left_event).trigger("press page 1");
id(music_card_prev).execute();
break; break;
case 2: case 2:
id(bar2_btn_left_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_left_event).trigger("release page 0");
break;
case 1: case 1:
id(bar2_btn_left_event).trigger("release page 1"); id(bar2_btn_left_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar2_btn_left_event).trigger("release page 2"); id(bar2_btn_left_event).trigger("release page 2");
break; break;
case 3:
id(bar2_btn_left_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -315,43 +310,43 @@ binary_sensor:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_left_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar2_btn_left_event).trigger("long press page 1"); id(bar2_btn_left_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar2_btn_left_event).trigger("long press page 2"); id(bar2_btn_left_event).trigger("long press page 2");
break; break;
case 3:
id(bar2_btn_left_event).trigger("long press page 3");
break;
} }
- id: !extend bar2_btn_right - id: !extend bar2_btn_right
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_right_event).trigger("press page 0");
break;
case 1: case 1:
id(bar2_btn_right_event).trigger("press page 1"); id(bar2_btn_right_event).trigger("press page 1");
id(music_card_next).execute();
break; break;
case 2: case 2:
id(bar2_btn_right_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_right_event).trigger("release page 0");
break;
case 1: case 1:
id(bar2_btn_right_event).trigger("release page 1"); id(bar2_btn_right_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar2_btn_right_event).trigger("release page 2"); id(bar2_btn_right_event).trigger("release page 2");
break; break;
case 3:
id(bar2_btn_right_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -359,43 +354,43 @@ binary_sensor:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar2_btn_right_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar2_btn_right_event).trigger("long press page 1"); id(bar2_btn_right_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar2_btn_right_event).trigger("long press page 2"); id(bar2_btn_right_event).trigger("long press page 2");
break; break;
case 3:
id(bar2_btn_right_event).trigger("long press page 3");
break;
} }
- id: !extend bar3_btn_left - id: !extend bar3_btn_left
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_left_event).trigger("press page 0");
break;
case 1: case 1:
id(bar3_btn_left_event).trigger("press page 1"); id(bar3_btn_left_event).trigger("press page 1");
id(music_card_power).execute();
break; break;
case 2: case 2:
id(bar3_btn_left_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_left_event).trigger("release page 0");
break;
case 1: case 1:
id(bar3_btn_left_event).trigger("release page 1"); id(bar3_btn_left_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar3_btn_left_event).trigger("release page 2"); id(bar3_btn_left_event).trigger("release page 2");
break; break;
case 3:
id(bar3_btn_left_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -403,43 +398,43 @@ binary_sensor:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_left_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar3_btn_left_event).trigger("long press page 1"); id(bar3_btn_left_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar3_btn_left_event).trigger("long press page 2"); id(bar3_btn_left_event).trigger("long press page 2");
break; break;
case 3:
id(bar3_btn_left_event).trigger("long press page 3");
break;
} }
- id: !extend bar3_btn_right - id: !extend bar3_btn_right
on_click: on_click:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_right_event).trigger("press page 0");
break;
case 1: case 1:
id(bar3_btn_right_event).trigger("press page 1"); id(bar3_btn_right_event).trigger("press page 1");
id(music_card_playpause).execute();
break; break;
case 2: case 2:
id(bar3_btn_right_event).trigger("press page 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; break;
} }
on_release: on_release:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_right_event).trigger("release page 0");
break;
case 1: case 1:
id(bar3_btn_right_event).trigger("release page 1"); id(bar3_btn_right_event).trigger("release page 1");
break; break;
case 2: case 2:
id(bar3_btn_right_event).trigger("release page 2"); id(bar3_btn_right_event).trigger("release page 2");
break; break;
case 3:
id(bar3_btn_right_event).trigger("release page 3");
break;
} }
on_multi_click: on_multi_click:
- timing: - timing:
@@ -447,15 +442,15 @@ binary_sensor:
then: then:
lambda: |- lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(bar3_btn_right_event).trigger("long press page 0");
break;
case 1: case 1:
id(bar3_btn_right_event).trigger("long press page 1"); id(bar3_btn_right_event).trigger("long press page 1");
break; break;
case 2: case 2:
id(bar3_btn_right_event).trigger("long press page 2"); id(bar3_btn_right_event).trigger("long press page 2");
break; break;
case 3:
id(bar3_btn_right_event).trigger("long press page 3");
break;
} }
sensor: sensor:
@@ -494,13 +489,15 @@ display:
lambda: |- lambda: |-
id(all_pages_main).execute(); id(all_pages_main).execute();
switch (id(actual_page)){ switch (id(actual_page)){
case 0:
id(containers).execute();
break;
case 1: 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; break;
case 2: case 2:
id(music_card).execute(20, 125);
break;
case 3:
it.print(100, 160, id(font_arial20), "This is page 3!"); it.print(100, 160, id(font_arial20), "This is page 3!");
break; break;
} }
@@ -559,13 +556,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("volume_down"); id(music_card_bar).execute("volume_down");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
@@ -573,13 +570,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("volume_up"); id(music_card_bar).execute("volume_up");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
@@ -587,13 +584,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("prev"); id(music_card_bar).execute("prev");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
@@ -601,13 +598,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("next"); id(music_card_bar).execute("next");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
@@ -615,13 +612,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("power"); id(music_card_bar).execute("power");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
@@ -629,13 +626,13 @@ script:
then: then:
- lambda: |- - lambda: |-
switch (id(actual_page)){ switch (id(actual_page)){
case 0: case 1:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(red));
break; break;
case 1: case 2:
id(music_card_bar).execute("playpause"); id(music_card_bar).execute("playpause");
break; break;
case 2: case 3:
id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue)); id(bar_display).image(80, 0, id(lightbulb), ImageAlign::TOP_CENTER, id(blue));
break; break;
} }
+32 -13
View File
@@ -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. __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! > 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://) [English support topic on Home Assistant Community:](https://)
TODO 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/ * Display Items: https://esphome.io/components/display/
* Fonts: https://esphome.io/components/font#display-fonts * Fonts: https://esphome.io/components/font#display-fonts
* Icon's and images: https://esphome.io/components/image#display-image * 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 ## 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: ## 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 - [ ] Documentation
- [x] initial firmware load
- [ ] links to the card documentation
- [ ] More examples - [ ] More examples
+1
View File
@@ -133,6 +133,7 @@ display:
invert_colors: false invert_colors: false
color_order: rgb color_order: rgb
update_interval: 30s update_interval: 30s
color_palette: 8BIT
dc_pin: dc_pin:
number: GPIO37 number: GPIO37
allow_other_uses: true allow_other_uses: true
-3
View File
@@ -61,8 +61,5 @@ script:
- id: update_all - id: update_all
then: then:
- component.update: main_display - component.update: main_display
- delay: 0.1s
- script.execute: update_bar1_left - script.execute: update_bar1_left
- delay: 0.1s
- script.execute: update_bar1_right - script.execute: update_bar1_right
- delay: 0.1s
+1
View File
@@ -205,6 +205,7 @@ display:
invert_colors: false invert_colors: false
color_order: rgb color_order: rgb
update_interval: 30s update_interval: 30s
color_palette: 8BIT
dc_pin: dc_pin:
number: GPIO37 number: GPIO37
allow_other_uses: true allow_other_uses: true
-5
View File
@@ -103,12 +103,7 @@ script:
- id: update_all - id: update_all
then: then:
- component.update: main_display - component.update: main_display
- delay: 0.1s
- script.execute: update_bar1_left - script.execute: update_bar1_left
- delay: 0.1s
- script.execute: update_bar1_right - script.execute: update_bar1_right
- delay: 0.1s
- script.execute: update_bar2_left - script.execute: update_bar2_left
- delay: 0.1s
- script.execute: update_bar2_right - script.execute: update_bar2_right
- delay: 0.1s
+1
View File
@@ -277,6 +277,7 @@ display:
invert_colors: false invert_colors: false
color_order: rgb color_order: rgb
update_interval: 30s update_interval: 30s
color_palette: 8BIT
dc_pin: dc_pin:
number: GPIO37 number: GPIO37
allow_other_uses: true allow_other_uses: true
+6 -6
View File
@@ -154,15 +154,15 @@ script:
- id: update_all - id: update_all
then: then:
- component.update: main_display - component.update: main_display
- delay: 0.1s - delay: 5ms
- script.execute: update_bar1_left - script.execute: update_bar1_left
- delay: 0.1s - delay: 5ms
- script.execute: update_bar1_right - script.execute: update_bar1_right
- delay: 0.1s - delay: 5ms
- script.execute: update_bar2_left - script.execute: update_bar2_left
- delay: 0.1s - delay: 5ms
- script.execute: update_bar2_right - script.execute: update_bar2_right
- delay: 0.1s - delay: 5ms
- script.execute: update_bar3_left - script.execute: update_bar3_left
- delay: 0.1s - delay: 5ms
- script.execute: update_bar3_right - script.execute: update_bar3_right
+23 -36
View File
@@ -13,7 +13,7 @@ esp32:
interval: interval:
- interval: 1min - interval: 1min
then: then:
- logger.log: "ESPHome for Button+ v0.1.1" - logger.log: "ESPHome for Button+ v0.2.0_dev"
i2c: i2c:
- id: temperature_sensor - id: temperature_sensor
@@ -29,12 +29,15 @@ spi:
mosi_pin: GPIO35 mosi_pin: GPIO35
globals: globals:
- id: nr_of_pages
type: int
initial_value: '1'
- id: actual_page - id: actual_page
type: int 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: output:
- platform: ledc - platform: ledc
@@ -93,25 +96,22 @@ time:
id: datetime id: datetime
number: number:
## Creates a number entity in Home Assistant # Creates a number entity in Home Assistant
# It sets the menu of the Button Plus # It sets the menu of the Button Plus
- platform: template - platform: template
name: "Menu Selector" name: "Menu Selector"
id: menuselector id: menu_selector
optimistic: true optimistic: true
min_value: 0 # keep at 0 min_value: 1
max_value: 10 # TODO replace page numbers with substitution max_value: ${nr_of_pages}
step: 1 step: 1
on_value: on_value:
then: then:
- lambda: |- - globals.set:
if(id(menuselector).state >= id(nr_of_pages)) { id: actual_page
id(actual_page) = id(nr_of_pages)-1; value: !lambda 'return x;'
} else { - script.execute: update_page_naming
id(actual_page) = id(menuselector).state; - script.execute: update_all
}
# # Refresh the screen
# - script.execute: update_page <<< this ends in an loop...
script: script:
###################### ######################
@@ -119,32 +119,19 @@ script:
###################### ######################
- id: next_page - id: next_page
then: then:
- lambda: |- - number.increment:
id(actual_page) = id(actual_page) + 1; id: menu_selector
if(id(actual_page) >= id(nr_of_pages)) {
id(actual_page) = 0;
}
- script.execute: update_page
- id: prev_page - id: prev_page
then: then:
- lambda: |- - number.decrement:
id(actual_page) = id(actual_page) - 1; id: menu_selector
if(id(actual_page) < 0) { - id: update_page_naming
id(actual_page) = id(nr_of_pages) - 1;
}
- script.execute: update_page
- id: update_page
then: then:
- lambda: |- - 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: - sensor.template.publish:
id: active_page_id_ha id: active_page_id_ha
state: !lambda 'return id(actual_page);' state: !lambda 'return id(actual_page);'
- text_sensor.template.publish: - text_sensor.template.publish:
id: active_page_name_ha id: active_page_name_ha
state: !lambda 'return id(active_page_name);' state: !lambda 'return id(active_page_name);'
- number.set:
id: menuselector
value: !lambda 'return id(actual_page);'
- script.execute: update_all
+38
View File
@@ -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
```
+210
View File
@@ -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());
}
+1 -1
View File
@@ -2,7 +2,7 @@
## Usage ## 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: substitutions:
music_card_enity_id: 'media_player.media_keuken_2' music_card_enity_id: 'media_player.media_keuken_2'
+20 -8
View File
@@ -14,70 +14,82 @@
## ##
## display: ## display:
## - id: !extend main_display ## - id: !extend main_display
## pages: ## lambda: |-
## - id: player_page ## id(music_card).execute(20, 125);
## lambda: |-
## id(all_pages).execute();
## // insert music card:
## // >> id(music_card).execute(x, y);
## id(music_card).execute(20, 125);
## - id: !extend bar1_left
## ##
##################################################### #####################################################
image: image:
- file: mdi:music-box-outline - file: mdi:music-box-outline
type: binary
id: icon_music_album id: icon_music_album
resize: 20x20 resize: 20x20
- file: mdi:account-music - file: mdi:account-music
type: binary
id: icon_music_artist id: icon_music_artist
resize: 20x20 resize: 20x20
- file: mdi:music-note - file: mdi:music-note
type: binary
id: icon_music_songtitle id: icon_music_songtitle
resize: 20x20 resize: 20x20
- file: mdi:power-off - file: mdi:power-off
type: binary
id: icon_music_off id: icon_music_off
resize: 75x75 resize: 75x75
- file: mdi:power-on - file: mdi:power-on
type: binary
id: icon_music_on id: icon_music_on
resize: 75x75 resize: 75x75
- file: mdi:power - file: mdi:power
type: binary
id: icon_music_power id: icon_music_power
resize: 75x75 resize: 75x75
- file: mdi:timer-sand-empty - file: mdi:timer-sand-empty
type: binary
id: icon_music_idle id: icon_music_idle
resize: 75x75 resize: 75x75
- file: mdi:play-pause - file: mdi:play-pause
type: binary
id: icon_music_playpause id: icon_music_playpause
resize: 75x75 resize: 75x75
- file: mdi:play-box-outline - file: mdi:play-box-outline
type: binary
id: icon_music_play_box id: icon_music_play_box
resize: 75x75 resize: 75x75
- file: mdi:pause-box-outline - file: mdi:pause-box-outline
type: binary
id: icon_music_pause_box id: icon_music_pause_box
resize: 75x75 resize: 75x75
- file: mdi:power - file: mdi:power
type: binary
id: icon_music_standby id: icon_music_standby
resize: 75x75 resize: 75x75
- file: mdi:download-box-outline - file: mdi:download-box-outline
type: binary
id: icon_music_buffering id: icon_music_buffering
resize: 75x75 resize: 75x75
- file: mdi:volume-plus - file: mdi:volume-plus
type: binary
id: icon_music_vol_up id: icon_music_vol_up
resize: 75x75 resize: 75x75
- file: mdi:volume-minus - file: mdi:volume-minus
type: binary
id: icon_music_vol_down id: icon_music_vol_down
resize: 75x75 resize: 75x75
- file: mdi:skip-forward - file: mdi:skip-forward
type: binary
id: icon_music_next id: icon_music_next
resize: 75x75 resize: 75x75
- file: mdi:skip-backward - file: mdi:skip-backward
type: binary
id: icon_music_prev id: icon_music_prev
resize: 75x75 resize: 75x75
- file: mdi:play - file: mdi:play
type: binary
id: icon_music_play id: icon_music_play
resize: 75x75 resize: 75x75
- file: mdi:pause - file: mdi:pause
type: binary
id: icon_music_pause id: icon_music_pause
resize: 75x75 resize: 75x75