Example Configurations
Note
Some examples below may generate errors during Home Assistant startup. Log messages like Error while processing template
or Template variable error: 'None' has no attribute 'last_changed'
etc. can be caused by the fact that openHASP component loads faster than the other integrations you have set up, from where you want to pull data. Because the data required by openHASP component is not yet available, an error is generated. But as soon as Home Assistant finishes loading everything, and all the data you've configured is available, things will be normal. Nevertheless the log should be checked regularly to find repetitive problems.
Display clock and temperature~
The easiest example is to display the state of a clock and a temperature sensor from Home Assistant, using label objects in openHASP.
Create a label object to display the temperature value, a separate label object to display the unit and a third label object for the clock:
1 2 3 |
|
In component configuration all you need for the objects is:
1 2 3 4 5 6 7 |
|
Note:~
You can of course omit the second label object with the unit and use the same for both value and unit:
1 2 |
|
In component configuration you will add the unit to the value using the template:
1 2 3 4 |
|
All these being on page 0 means that they will appear on all the pages.
Some basic controls~
Jsonl and Home Assistant configuration:
Toggle a light (or any switchable entity with on/off states)~
1 |
|
1 2 3 4 5 6 7 8 |
|
Dropdown (self-populating from an input_select)~
1 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Color coded icons~
Color code a WiFi icon according to RSSI reported by the plate
openHASP config: (screen size 240x320)
1 |
|
relevant openHASP-custom-component config:
1 2 3 |
|
Color code a temperature icon according to sensor values
openHASP config: (screen size 240x320)
1 |
|
relevant openHASP-custom-component config:
1 2 3 |
|
Light brightness and color~
Have a light in Home Assistant controlled by openHASP. In our example we use Lanbon L8's moodlight which has both brightness and color - we use a slider object for the brightness, and a cpicker object for color.
relevant openHASP config:
1 2 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
brightness
attribute of light.plate_moodlight
, while it's on. If it's off, that attribute is removed by Home Assistant, in that case we set it to 0
.
The color
property gets updated from the rgb_color
attriburte of the light. The R, G and B decimal color values are converted to hexadecimal html color code using a template whenever the color of the light changes in Home Assistant.
When somebody changes the color of the picker object on the page, the light in Home Assistant gets updated with rgb_color
values received in the MQTT message from the plate.
Cover with state feedback~
The icon on the up and down buttons change color when covers move and set opacity when reached to limit. UI theme set to Hasp Light
in plate's web interface.
relevant openHASP config: (screen size 240x320)
1 2 3 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Cover with button matrix~
A simpler cover control with only basic feedback. UI theme set to Hasp Light
in plate's web interface.
relevant openHASP config: (screen size 240x320)
1 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Covers like in Lovelace~
The icon behaves like in Lovelace. UI theme set to Hasp Light
in plate's web interface.
Check out the Lovelace-like entities for similar placement.
relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light)
1 2 3 4 5 6 7 8 9 10 11 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Media player~
The labels with artist and title are scrolling, the progressbar fills if the media player provides duration and playback position. The dropdown lists containing the available sources and sound modes of the player get populated automatically by the values existing on the player in Home Assistant, and also the actually selected source is in sync with it.
Player availability is shown by the opacity of the buttons. Player state (play/pause) is shown by the middle button, short pressing means pause, long-press means stop. Power state shown by color, repeat, shuffle and muted state shown by appropriate icons on the buttons.
UI theme set to Hasp Light
in plate's web interface.
relevant openHASP config: (screen size 240x320)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
|
val
value of the slider is multiplied and divided by 100 when read and set, because LVGL only suppports integers for object values. By multiplying and dividing by 100, it becomes possible to set volume between 0 and 1 as required by Home Assistant.
Generic thermostat/climate~
This example is a bit more complex in the aspect that it uses several objects put on top of each other, and grouped toghether using the parentid
parameter. Special attention goes to an invisible tabview (exteding over the label dispaying the target temperarture) which allows for swiping between an on/off switch and dropdowns for setting the hvac and fan modes.
The target temperature can be set by dragging the arc handle, more precise +/- setting possible by short/long pressing the middle circle containing the current temperature (increasing/decreasing the value by the temperature step defined by the climate entity). Note that the min
, max
and val
values of the arc and gauge are multiplied and divided by 10 when set and read, because LVGL only suppports integers for object values. By multiplying and dividing by 10, it becomes possible to set decimal values for climate temperature.
The number of the ticks on the gauge is determined from the min
, max
attributes of the configured climate, likewise the hvac_modes
and fan_modes
dropdowns. You can localise these using the if-else
statements of the template in the configuration of the custom component.
The active area of the arc changes color based on the current hvac mode of the entity.
UI theme set to Hasp Light
in plate's web interface.
Note that the tab swiping dots (p3b26) are also handled by the custom component. Don't forget update the service call in the configuration with your plate's MQTT node name, and the command parameters if you change the page of the objects.
relevant openHASP config: (screen size 240x320)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
|
Current weather and forecasts~
This example implements two weather forecast screens which located on the same page, can be swiped left and right. On the top area the current weather is shown, on the bottom area the user can choose by swiping between next hours and next days forecast. This is achieved by a tabview object with invisible tabs.
Since there's no weather integration in Home Assistant which can offer so much information at once, this can be achieved by installing multiple weather components. In our example we use two:
- Met.no (the one coming by default pre-installed) for next days forecast.
- OpenWeatherMap (available as standard integration to be activated) for next hours forecast. You need to set the forecast mode to onecall_hourly to get forecasts for the day's next hours.
The openHASP component grabs information from both weather sources and updates them on every change.
The various strings containing day names, day periods, weather conditions can be localized easily to any language within the configuration.
Weather condition icons are displayed from the internal flash space of the plate. For this, you need to upload the desired icon pack to the plate:
To unzip them on the plate, connect via Telnet and run the command unzip /openhasp-weathericons-day.zip
to unzip the light theme above (alternatively you can unzip them on your computer and upload them one by one). The configuration example only shows how to use the light theme icons.
This example implements Home Assistant's standard weather conditions only (as in 2021.06), so any weather integration component can be used. Some integrations know extra conditions in addition to the standard ones, those (with their corresponding icons) can be easily added to the component configuration below.
Note that the tab swiping dots (p5b10) are also handled by the custom component. Don't forget update the service call in the configuration with your plate's MQTT node name, and the command parameters if you change the page of the objects.
Warning
For this example to work, you need an ESP32 board having PSRam memory installed, otherwise openHASP will crash.
relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
relevant openHASP-custom-component config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
|
Attribution
Icons are copyright from manifestinteractive and merlinthered.
Fan and scent diffuser~
This example shows how a transparent PNG image can be combined with a moving spinner object, to create the impression of a spinning fan.
In Home Assistant this fan appears as a select
component with the available presets as Low
,Mid
,High
,Turbo
,OFF
selectable options. The scent diffuser appears as a standard fan
component where the intensity can be set by percentage.
To control the fan we use a button matrix object which has exactly the same buttons as the options of the select component. To control the scent diffuser we use a slider object.
The fan and the perfume PNG icons are available below. Upload them to the flash storage of your plate.
Warning
For this example to work, you need an ESP32 board having PSRam memory installed, otherwise openHASP will likely crash.
relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light)
{"page":4,"id":1,"obj":"btn","x":0,"y":0,"w":240,"h":30,"text":"AIR TREATMENT","text_font":16,"bg_color":"#2C3E50","text_color":"#FFFFFF","radius":0,"border_side":0,"click":0}
{"page":4,"id":10,"obj":"obj","x":5,"y":35,"w":230,"h":250,"click":0}
{"page":4,"id":2,"obj":"label","x":10,"y":40,"w":105,"h":20,"text":"Fresh air flow","align":"center","border_width":0}
{"page":4,"id":3,"obj":"label","x":125,"y":40,"w":105,"h":20,"text":"Scent intensity","align":"center","border_width":0}
{"page":4,"id":12,"obj":"spinner","x":36,"y":84,"w":56,"h":56,"bg_opa":0,"border_width":0,"line_width":0,"line_width1":19,"line_color1":"#34eb77","type":2,"angle":160,"speed":3000}
{"page":4,"id":13,"obj":"img","x":14,"y":75,"src":"L:/g64.png","auto_size":1,"w":100,"h":74}
{"page":4,"id":14,"obj":"img","x":130,"y":78,"src":"L:/perfume3.png","auto_size":1,"w":60,"h":68}
{"page":4,"id":40,"obj":"btnmatrix","x":5,"y":130,"w":110,"h":113,"parentid":10,"options":["Low","Mid","\n","High","Turbo","\n","OFF"],"toggle":1,"one_check":1,"bg_opa":0,"pad_inner":5,"border_width":0,"pad_top":0,"pad_bottom":0,"pad_left":0,"pad_right":0}
{"page":4,"id":51,"obj":"slider","x":200,"y":60,"w":25,"h":220,"min":0,"max":60,"val":15}
{"page":4,"id":52,"obj":"obj","x":130,"y":130,"w":50,"h":30,"parentid":10,"click":0,"radius":5}
{"page":4,"id":53,"obj":"label","x":130,"y":130,"w":50,"h":30,"parentid":10,"text":"15","text_font":24,"align":"center"}
{"page":4,"id":54,"obj":"btn","x":130,"y":168,"w":50,"h":76,"parentid":10,"toggle":true,"text":"\uE425","text_font":32,"align":1,"bg_color":"#A0A0A0","bg_grad_color":"#606060","border_color":"#404040"}
relevant openHASP-custom-component config:
- obj: "p4b40" # Buttin Matrix with the fan presets
properties:
"click": "{{ 0 if (is_state('input_select.fan_presets','unavailable') or is_state('input_select.fan_presets','unknown')) else 1 }}"
"opacity": "{{ 100 if (is_state('input_select.fan_presets','unavailable') or is_state('input_select.fan_presets','unknown')) else 255 }}"
"options": '["Low","Mid","\n","High","Turbo","\n","OFF"]'
"toggle": '{{ 1 if (not states("input_select.fan_presets") in state_attr("input_select.fan_presets","options")) or (is_state("input_select.fan_presets","unavailable")) -}}'
"val": >
{% if not (is_state('input_select.fan_presets','unavailable')) -%}
{% if not states('input_select.fan_presets') in state_attr('input_select.fan_presets','options') -%}-1{% else -%}
{% for source in state_attr('input_select.fan_presets','options') -%}
{{loop.index - 1 if source == states('input_select.fan_presets') }}
{%-endfor%}
{%- endif %}
{%- endif %}
event:
- service: input_select.input_select_option
data:
option: '{{ text }}'
target:
entity_id: input_select.fan_presets
- obj: "p4b12" # Spinner behind the PNG icon
properties:
"opacity": "{{ 0 if (is_state('input_select.fan_presets','unavailable') or is_state('input_select.fan_presets','unknown') or is_state('input_select.fan_presets','OFF')) else 255 }}"
"speed": >
{% if is_state('number.plate_test_page_number', '4') %}
{% if is_state('input_select.fan_presets', 'Low') %}
{{ "7000" }}
{%-elif is_state('input_select.fan_presets', 'Mid') %}
{{ "1700" }}
{%-elif is_state('input_select.fan_presets', 'High') %}
{{ "800" }}
{%-elif is_state('input_select.fan_presets', 'Turbo') %}
{{ "250" }}
{%-else %}
{{ "0" }}
{% endif %}
{% else -%}{{ "0" }}{% endif %}
"line_color1": >
{% if is_state('input_select.fan_presets', 'Low') %}
{{ "#31de70" }}
{%-elif is_state('input_select.fan_presets', 'Mid') %}
{{ "#dede1f" }}
{%-elif is_state('input_select.fan_presets', 'High') %}
{{ "#d6a11a" }}
{%-elif is_state('input_select.fan_presets', 'Turbo') %}
{{ "#ff4a4a" }}
{%-else %}
{{ "#9f96b0" }}
{% endif %}
- obj: "p4b54" # Scent Diffuser ON/OFF button
properties:
"val": '{{ 1 if is_state("fan.scent_diffuser_intensity", "on") else 0 }}'
"enabled": "{{ 'false' if (is_state('fan.scent_diffuser_intensity','unavailable') or is_state('fan.scent_diffuser_intensity','unknown')) else 'true' }}"
event:
"down":
- service: fan.toggle
target:
entity_id: fan.scent_diffuser_intensity
- obj: "p4b51" # Scent Diffuser intensity slider
properties:
"val": "{{ state_attr('fan.scent_diffuser_intensity','percentage') }}"
"enabled": "{{ 'false' if (is_state('fan.scent_diffuser_intensity','unavailable') or is_state('fan.scent_diffuser_intensity','unknown')) else 'true' }}"
event:
"up":
- service: fan.set_percentage
target:
entity_id: fan.scent_diffuser_intensity
data:
percentage: '{{ val }}'
- obj: "p4b53" # Scent Diffuser intensity number label
properties:
"text": "{{ '--' if (is_state('fan.scent_diffuser_intensity','unavailable') or is_state('fan.scent_diffuser_intensity','unknown')) else state_attr('fan.scent_diffuser_intensity','percentage') }}"
"opacity": "{{ 255 if is_state('fan.scent_diffuser_intensity', 'on') else 95 }}"
Note the condition in the Spinner configuration of the component:
{% if is_state('openhasp.plate_test', '4') %}
- this is useful to only animate the spinner when the page containing it is actually shown. Since the spinner is being overlapped by a transparent PNG image, CPU usage is higher as it has to be completely redrawn every frame. CPU resources can be freed up this way - only animate when it can be seen.
Attribution
Icons are copyright from SVG Repo.