-
-
- nodename
+
+ hostname
@@ -2758,10 +2758,10 @@ ssid
Set the optional password for the access point to connect to.
MQTT
-nodename
-Set the nodename of the device and mqtt topic for the node to hasp/<nodename>/
+hostname
+Set the hostname of the device and mqtt topic for the node to hasp/<nodename>/
mqtthost
-Set the IP address or nodename of the mqtt broker.
+Set the IP address or hostname of the mqtt broker.
mqttport
Set the port of the mqtt broker.
mqttuser
diff --git a/0.7.0/commands/index.html b/0.7.0/commands/index.html
index 8ecdff4d2..83b857126 100644
--- a/0.7.0/commands/index.html
+++ b/0.7.0/commands/index.html
@@ -3064,10 +3064,10 @@ ssid
Set the optional password for the access point to connect to.
MQTT
-nodename
-Set the nodename of the device and mqtt topic for the node to hasp/<nodename>/
+hostname
+Set the hostname of the device and mqtt topic for the node to hasp/<nodename>/
mqtthost
-Set the IP address or nodename of the mqtt broker.
+Set the IP address or hostname of the mqtt broker.
mqttport
Set the port of the mqtt broker.
mqttuser
diff --git a/0.7.0/search/search_index.json b/0.7.0/search/search_index.json
index 78b04da2c..8384af355 100644
--- a/0.7.0/search/search_index.json
+++ b/0.7.0/search/search_index.json
@@ -1 +1 @@
-{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"openHASP Control your home-automation devices from a customizable touchscreen UI connected via MQTT. openHASP is a re-implementation of the popular HASwitchPlate sketch created by aderusha. The HASPone project uses a Wemos D1 mini and requires a Nextion/TJC HMI display. This project is a complete rewrite and implements the Light and Versatile Graphics Library on the MCU to drive a commodity display. openHASP uses an ESP32 to take advantage of the additional hardware capabilities. Demo Screens ~ Click on the demo screen to show the example configuration: Quotes ~ kazimir Hey man, openHASP is amazing. Currently running 12 pieces of Lanbon L8 plates in my house with your firmware. danielo Oh man, integrating this with Home Assistant was super easy. Lucky you can't see me getting hyped about turning on/off my office lights from a tinny screen (and doing it like 3 or 4 times on a row...) Support ~ For support using openHASP you can find us on Github, Discord or Home Assistant: Github Discussions Discord Chat Home Assistant Forum Donate ~ The firmware is opensource and free to use! If you like this project you can show your appreciation by making a small donation. This will help with ofssetting the cost of the different hardware devices we support.","title":"Overview"},{"location":"#demo-screens","text":"Click on the demo screen to show the example configuration:","title":"Demo Screens"},{"location":"#quotes","text":"kazimir Hey man, openHASP is amazing. Currently running 12 pieces of Lanbon L8 plates in my house with your firmware. danielo Oh man, integrating this with Home Assistant was super easy. Lucky you can't see me getting hyped about turning on/off my office lights from a tinny screen (and doing it like 3 or 4 times on a row...)","title":"Quotes"},{"location":"#support","text":"For support using openHASP you can find us on Github, Discord or Home Assistant: Github Discussions Discord Chat Home Assistant Forum","title":"Support"},{"location":"#donate","text":"The firmware is opensource and free to use! If you like this project you can show your appreciation by making a small donation. This will help with ofssetting the cost of the different hardware devices we support.","title":"Donate"},{"location":"commands/","text":"Commands are not related to an object on the screen but can get or set global properties or invoke system commands on the device. MQTT Topics ~ hasp/plate01/command/ is for sending commands to the screen hasp/plate01/state/ is for receiving updates from the screen So the topic depends on the direction of the data flow. Sending a message to topic hasp/plate01/command/p1b2.val with payload 25 would be a valid command. You can send a test MQTT message with a standalone program like MQTT Explorer or mosuito_pub. Issuing commands ~ Commands can be issued via the Serial commandline, telnet commandline or MQTT. For MQTT, you can use either: hasp//command topic with payload = hasp//command/ topic with payload Leave the payload empty to get the current state without changing it. Batch processing ~ Commands can be processed in batch one after another from .cmd script files located in the flash storage of the plate. General rules when creating .cmd batch scripts: can contain any command empty lines are ignored # or // can be used for comments space or tab in front of a command is ignored lines starting with { are processed as jsonl payloads lines starting with [ are processed as json payloads other lines are processed as CR , LF or CRLF line endings allowed UTF8 encoding is required for special characters To start a batch script, use run command. System scripts ~ If any of the following scripts is present on the filesystem, it will be run automatically according to the rules below: L:/boot.cmd is executed when the plate has finished (re)booting L:/online.cmd will be executed after connection to the network was successfull L:/offline.cmd will be executed after connection to the WiFi is lost This makes it possible to disable or hide buttons, load a special offline page, etc. See example . Global commands ~ run ~ accepted parameters: name of a .cmd or .jsonl file present on the flash filesystem of the plate. Filename must be preceeded by the / character Run a batch script or load a jsonl page. Example run /script.cmd run /pages_party_mode.jsonl jsonl ~ accepted parameters: one or more json formatted lines Create new objects or update the properties of an existing object. When updating an existing object the obj property is not required and will be ignored. Each line in the jsonl payload defines one object and has to be in the json format. If the payload exceeds the MQTT buffer of 2 kB it will be cut off to fit, don't send too many lines in a single payload, you can always sends multiple jsonl commands. Example 1 jso nl { \"obj\" : \"btn\" , \"id\" : 14 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"Test\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } For more details see Pages and Objects . json ~ accepted parameters: json array of strings Use the json command to send multiple commands as an array of strings in one payload. Example 1 jso n [ 'page 3 ' , 'backligh t { \"state\" : \"ON\" , \"brightness\" : 100 } ' , 'idle o ff ' ] This command will change to page 3, turn the backlight on at ~40% brightness and reset the idle timer. page ~ accepted parameters: [1-12] , prev , next or back Switches the display to show the objects from a different page and return the page number in state/page . Calling the page command without a parameter will return the value of the current page in state/page . clearpage ~ accepted parameters: [0-12] or all Deletes all objects on a given page. If no page number is specified, it clears the current page. Use clearpage all to clear all objects on all pages. To delete individual objects, you can issue the pXbY.delete command. backlight ~ accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 Example backlight {\"state\":\"on\",\"brightness\":128} sets the display to half the brightness. Instead of a json payload, you can use a simple payload. To change the state, use either on / off , true / false , 0 , yes / no . A simple integer payload of 1..255 will adjust the brightness. Example backlight off backlight 200 sets the display brightness to ~80%. moodlight ~ accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 color or r, g, b: 0..255 An RGB moodlight can be controlled by configuring 3 GPIO pins as type Mood Red , Mood Green and Mood blue . These leds can then be controlled together using the moodlight command. Example 1 2 3 4 moodligh t { \"state\" : \"off\" , \"color\" : \"green\" } moodligh t { \"state\" : true , \"color\" : \"#ff00e7\" } moodligh t { \"color\" : 12345 } moodligh t { \"state\" : \"on\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 255 } The state key accepts boolean values to turn the moodlight on or off The brightness key can be set between 1 and 255 to dim the moodlight The color key accepts color values to set the RGB channels at once Individual r , g and b keys can also be used to set each channel separately Calling the moodlight command without parameters (or sending an empty payload to the hasp//command/moodlight topic) returns the current state: Example 1 \"state/moodlight\" { \"state\" : \"ON\" , \"brightness\" : 255 , \"color\" : \"#ff0000\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 0 } The color is returned as a hexadecimal value and as individual RGB channels. idle ~ accepted parameters: off , short or long Sets the idle state of the device and publishes the new state via a state/idle status message. off resets the idle counter as if a touch event occurred on the device. This is helpful e.g. when you want to wake up the display when an external event has occurred, like a PIR motion sensor. short or long sets the idle timer to the number of seconds configured in the Display Settings . You can use this to force an idle state, for example at night or when leaving the house. Calling the idle command without a parameter will also return the current idle state short , long or off in the state/idle topic. output[x] ~ where [x] is number of the gpio pin (0-39) accepted json keys: state: on / off , true / false , 0 / 1 , yes / no val: 0..255 Changes the state GPIO pin to on or off . If the pin is configured as a LED or Serial Dimmer then the val key will control the brightness. Note If the GPIO is assigned to a group then objects and other GPIOs that share the same groupid will change state accordingly. input[x] ~ where [x] is number of the gpio pin (0-39) read-only Returns a JSON object containing the current state of the input, either on or off Example 1 i n pu t 4 => { \"state\" : \"on\" } System Commands ~ antiburn ~ accepted parameters: on / off , true / false , 0 / 1 , yes / no Start LCD anti burn-in protection. This cycles the display to a full black, red, green, blue and white color each second to relief the tension put on each individual pixel. The cycle stops when either: 30 seconds have passed antiburn=off is received The screen is touched If you're using Home Assistant, check out the automation example to make it run on a regular basis. calibrate ~ Start on-screen touch calibration. You need to issue a soft reboot command to save the new calibration settings. If you do a hard reset of the device, the calibration settings will be lost. discovery ~ Trigger the sending of the discovery payload. sensors ~ Trigger the sending of the sensor data. factoryreset ~ Clear the filesystem and EEPROM and reboot the device in its initial state. Warning There is no confirmation prompt nor an undo function! reboot or restart ~ Saves any changes in the configuration file and reboots the device. screenshot ~ Saves a picture of the current screen to the flash filesystem. You can retrieve it via http:///screenshot.bmp. This can be handy for bug reporting or documentation. The previous screenshot is overwritten. service ~ Start or stop some of the processes running on the plate. Currently supported parameters: start stop Currently supported services: http (web interface) telnet (remote console) console (serial console) Example To stop the web interface of the plate, send to topic hasp//command/service the string stop http . To start the web interface of the plate, send to topic hasp//command/service the string start http . Tip Once these services are stopped, connection is lost/not possible to the plate through them. They can be started at any time by sending service start commands in through MQTT. It's possible to create self-built firmware binaries which have services stopped by default at boot, using customization . statusupdate ~ Reports the status of the MCU. The response will be posted to the state topic. Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \"hasp//state/statusupdate\" => { \"node\" : \"plate01\" , \"idle\" : \"long\" , \"version\" : \"0.6.3\" , \"uptime\" : 11027 , \"ssid\" : \"my_network\" , \"rssi\" : -60 , \"ip\" : \"192.168.0.133\" , \"mac\" : \"7C:87:CE:E3:55:55\" , \"heapFree\" : 58756 , \"heapFrag\" : 7 , \"core\" : \"v4.4.1\" , \"canUpdate\" : \"false\" , \"page\" : 1 , \"numPages\" : 12 , \"tftDriver\" : \"ILI9488\" , \"tftWidth\" : 480 , \"tftHeight\" : 320 } unzip ~ Unzip a file-packgage on the plate. You can upload uncompressed ZIP files to the flash space of your plate and unzip them locally. This is useful for cases when you need a lot of small files to be uploaded - putting them in an uncompressed zip allows to upload them in one go, and then extract them with a single command: Example unzip /openhasp-weathericons-day.zip update ~ accepted parameters: [url] Update the firmware from the url provided. Reboots when update was successful. Configuration Settings ~ Wi-FI ~ ssid ~ Set network name of the access point to connect to. pass ~ Set the optional password for the access point to connect to. MQTT ~ nodename ~ Set the nodename of the device and mqtt topic for the node to hasp// mqtthost ~ Set the IP address or nodename of the mqtt broker. mqttport ~ Set the port of the mqtt broker. mqttuser ~ Set the optional username for the mqtt broker. mqttpass ~ Set the optional password for the mqtt broker. config/submodule ~ You can get or set the configuration of an openHASP submodule in json format. To get the configuration, use the command config/ : config/wifi config/mqtt config/http config/mdns config/hasp config/gui config/debug config/gpio The result will be published to hasp//state/config . Passwords will be omitted from the result. To update the configuration simply issue the same command config/ with updated json payload. Example config/gui {\"idle2\":0} disable long idle (don't turn off the screen completely) config/debug {\"tele\":300} set the telemetry period to 300 seconds config/hasp {\"startdim\":255} to set the startup brightness to 255","title":"Commands"},{"location":"commands/#mqtt-topics","text":"hasp/plate01/command/ is for sending commands to the screen hasp/plate01/state/ is for receiving updates from the screen So the topic depends on the direction of the data flow. Sending a message to topic hasp/plate01/command/p1b2.val with payload 25 would be a valid command. You can send a test MQTT message with a standalone program like MQTT Explorer or mosuito_pub.","title":"MQTT Topics"},{"location":"commands/#issuing-commands","text":"Commands can be issued via the Serial commandline, telnet commandline or MQTT. For MQTT, you can use either: hasp//command topic with payload = hasp//command/ topic with payload Leave the payload empty to get the current state without changing it.","title":"Issuing commands"},{"location":"commands/#batch-processing","text":"Commands can be processed in batch one after another from .cmd script files located in the flash storage of the plate. General rules when creating .cmd batch scripts: can contain any command empty lines are ignored # or // can be used for comments space or tab in front of a command is ignored lines starting with { are processed as jsonl payloads lines starting with [ are processed as json payloads other lines are processed as CR , LF or CRLF line endings allowed UTF8 encoding is required for special characters To start a batch script, use run command.","title":"Batch processing"},{"location":"commands/#system-scripts","text":"If any of the following scripts is present on the filesystem, it will be run automatically according to the rules below: L:/boot.cmd is executed when the plate has finished (re)booting L:/online.cmd will be executed after connection to the network was successfull L:/offline.cmd will be executed after connection to the WiFi is lost This makes it possible to disable or hide buttons, load a special offline page, etc. See example .","title":"System scripts"},{"location":"commands/#global-commands","text":"","title":"Global commands"},{"location":"commands/#run","text":"accepted parameters: name of a .cmd or .jsonl file present on the flash filesystem of the plate. Filename must be preceeded by the / character Run a batch script or load a jsonl page. Example run /script.cmd run /pages_party_mode.jsonl","title":"run"},{"location":"commands/#jsonl","text":"accepted parameters: one or more json formatted lines Create new objects or update the properties of an existing object. When updating an existing object the obj property is not required and will be ignored. Each line in the jsonl payload defines one object and has to be in the json format. If the payload exceeds the MQTT buffer of 2 kB it will be cut off to fit, don't send too many lines in a single payload, you can always sends multiple jsonl commands. Example 1 jso nl { \"obj\" : \"btn\" , \"id\" : 14 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"Test\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } For more details see Pages and Objects .","title":"jsonl"},{"location":"commands/#json","text":"accepted parameters: json array of strings Use the json command to send multiple commands as an array of strings in one payload. Example 1 jso n [ 'page 3 ' , 'backligh t { \"state\" : \"ON\" , \"brightness\" : 100 } ' , 'idle o ff ' ] This command will change to page 3, turn the backlight on at ~40% brightness and reset the idle timer.","title":"json"},{"location":"commands/#page","text":"accepted parameters: [1-12] , prev , next or back Switches the display to show the objects from a different page and return the page number in state/page . Calling the page command without a parameter will return the value of the current page in state/page .","title":"page"},{"location":"commands/#clearpage","text":"accepted parameters: [0-12] or all Deletes all objects on a given page. If no page number is specified, it clears the current page. Use clearpage all to clear all objects on all pages. To delete individual objects, you can issue the pXbY.delete command.","title":"clearpage"},{"location":"commands/#backlight","text":"accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 Example backlight {\"state\":\"on\",\"brightness\":128} sets the display to half the brightness. Instead of a json payload, you can use a simple payload. To change the state, use either on / off , true / false , 0 , yes / no . A simple integer payload of 1..255 will adjust the brightness. Example backlight off backlight 200 sets the display brightness to ~80%.","title":"backlight"},{"location":"commands/#moodlight","text":"accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 color or r, g, b: 0..255 An RGB moodlight can be controlled by configuring 3 GPIO pins as type Mood Red , Mood Green and Mood blue . These leds can then be controlled together using the moodlight command. Example 1 2 3 4 moodligh t { \"state\" : \"off\" , \"color\" : \"green\" } moodligh t { \"state\" : true , \"color\" : \"#ff00e7\" } moodligh t { \"color\" : 12345 } moodligh t { \"state\" : \"on\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 255 } The state key accepts boolean values to turn the moodlight on or off The brightness key can be set between 1 and 255 to dim the moodlight The color key accepts color values to set the RGB channels at once Individual r , g and b keys can also be used to set each channel separately Calling the moodlight command without parameters (or sending an empty payload to the hasp//command/moodlight topic) returns the current state: Example 1 \"state/moodlight\" { \"state\" : \"ON\" , \"brightness\" : 255 , \"color\" : \"#ff0000\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 0 } The color is returned as a hexadecimal value and as individual RGB channels.","title":"moodlight"},{"location":"commands/#idle","text":"accepted parameters: off , short or long Sets the idle state of the device and publishes the new state via a state/idle status message. off resets the idle counter as if a touch event occurred on the device. This is helpful e.g. when you want to wake up the display when an external event has occurred, like a PIR motion sensor. short or long sets the idle timer to the number of seconds configured in the Display Settings . You can use this to force an idle state, for example at night or when leaving the house. Calling the idle command without a parameter will also return the current idle state short , long or off in the state/idle topic.","title":"idle"},{"location":"commands/#outputx","text":"where [x] is number of the gpio pin (0-39) accepted json keys: state: on / off , true / false , 0 / 1 , yes / no val: 0..255 Changes the state GPIO pin to on or off . If the pin is configured as a LED or Serial Dimmer then the val key will control the brightness. Note If the GPIO is assigned to a group then objects and other GPIOs that share the same groupid will change state accordingly.","title":"output[x]"},{"location":"commands/#inputx","text":"where [x] is number of the gpio pin (0-39) read-only Returns a JSON object containing the current state of the input, either on or off Example 1 i n pu t 4 => { \"state\" : \"on\" }","title":"input[x]"},{"location":"commands/#system-commands","text":"","title":"System Commands"},{"location":"commands/#antiburn","text":"accepted parameters: on / off , true / false , 0 / 1 , yes / no Start LCD anti burn-in protection. This cycles the display to a full black, red, green, blue and white color each second to relief the tension put on each individual pixel. The cycle stops when either: 30 seconds have passed antiburn=off is received The screen is touched If you're using Home Assistant, check out the automation example to make it run on a regular basis.","title":"antiburn"},{"location":"commands/#calibrate","text":"Start on-screen touch calibration. You need to issue a soft reboot command to save the new calibration settings. If you do a hard reset of the device, the calibration settings will be lost.","title":"calibrate"},{"location":"commands/#discovery","text":"Trigger the sending of the discovery payload.","title":"discovery"},{"location":"commands/#sensors","text":"Trigger the sending of the sensor data.","title":"sensors "},{"location":"commands/#factoryreset","text":"Clear the filesystem and EEPROM and reboot the device in its initial state. Warning There is no confirmation prompt nor an undo function!","title":"factoryreset"},{"location":"commands/#reboot-or-restart","text":"Saves any changes in the configuration file and reboots the device.","title":"reboot or restart"},{"location":"commands/#screenshot","text":"Saves a picture of the current screen to the flash filesystem. You can retrieve it via http:///screenshot.bmp. This can be handy for bug reporting or documentation. The previous screenshot is overwritten.","title":"screenshot"},{"location":"commands/#service","text":"Start or stop some of the processes running on the plate. Currently supported parameters: start stop Currently supported services: http (web interface) telnet (remote console) console (serial console) Example To stop the web interface of the plate, send to topic hasp//command/service the string stop http . To start the web interface of the plate, send to topic hasp//command/service the string start http . Tip Once these services are stopped, connection is lost/not possible to the plate through them. They can be started at any time by sending service start commands in through MQTT. It's possible to create self-built firmware binaries which have services stopped by default at boot, using customization .","title":"service"},{"location":"commands/#statusupdate","text":"Reports the status of the MCU. The response will be posted to the state topic. Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \"hasp//state/statusupdate\" => { \"node\" : \"plate01\" , \"idle\" : \"long\" , \"version\" : \"0.6.3\" , \"uptime\" : 11027 , \"ssid\" : \"my_network\" , \"rssi\" : -60 , \"ip\" : \"192.168.0.133\" , \"mac\" : \"7C:87:CE:E3:55:55\" , \"heapFree\" : 58756 , \"heapFrag\" : 7 , \"core\" : \"v4.4.1\" , \"canUpdate\" : \"false\" , \"page\" : 1 , \"numPages\" : 12 , \"tftDriver\" : \"ILI9488\" , \"tftWidth\" : 480 , \"tftHeight\" : 320 }","title":"statusupdate"},{"location":"commands/#unzip","text":"Unzip a file-packgage on the plate. You can upload uncompressed ZIP files to the flash space of your plate and unzip them locally. This is useful for cases when you need a lot of small files to be uploaded - putting them in an uncompressed zip allows to upload them in one go, and then extract them with a single command: Example unzip /openhasp-weathericons-day.zip","title":"unzip"},{"location":"commands/#update","text":"accepted parameters: [url] Update the firmware from the url provided. Reboots when update was successful.","title":"update"},{"location":"commands/#configuration-settings","text":"","title":"Configuration Settings"},{"location":"commands/#wi-fi","text":"","title":"Wi-FI"},{"location":"commands/#mqtt","text":"","title":"MQTT"},{"location":"commands/#configsubmodule","text":"You can get or set the configuration of an openHASP submodule in json format. To get the configuration, use the command config/ : config/wifi config/mqtt config/http config/mdns config/hasp config/gui config/debug config/gpio The result will be published to hasp//state/config . Passwords will be omitted from the result. To update the configuration simply issue the same command config/ with updated json payload. Example config/gui {\"idle2\":0} disable long idle (don't turn off the screen completely) config/debug {\"tele\":300} set the telemetry period to 300 seconds config/hasp {\"startdim\":255} to set the startup brightness to 255","title":"config/submodule"},{"location":"gallery/","text":"","title":"Gallery"},{"location":"assets/buy/waveshare-tft-touch-shield/","text":" GND 5V <--> 5V RX <--> RX (not reversed!) TX <--> TX (not reversed!) Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Once the connections are made, flash the GS-T3E ESP32 binary like on any other device. GPIO Settings ~ 3-gang EU version GS-T3E ~ Pin Mode GS-T3E Group Default 45 Output Relay L1 1 Low (Normal) 46 Output Relay L2 2 Low (Normal) 44 Output Relay L3 3 Low (Normal) Tip To configure the GPIOs as light switches at once for GS-T3E send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 655918 , 656172 , 655661 , 0 , 0 , 0 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721454 , 721708 , 721197 , 0 , 0 , 0 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 } Wiring Diagram ~ The switch supports this wiring configuration: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring. Product Video ~ Your browser does not support the video tag. Gallery ~","title":"Golden Security"},{"location":"hardware/golden-security/gs-t3e/#gs-t3e","text":"","title":"GS-T3E "},{"location":"hardware/golden-security/gs-t3e/#models","text":"EU model: 3 gang relay switch CN model: 4 gang relay switch Only the PCB revision v2.3 (20221205) is supported by openHASP. Specify that you want the new device with PCB revision v2.3 when ordering from known vendor Golden Security on Alibaba. Warning Do NOT buy PCB revision v1.23 (20220817) because the internal antenna connector is NOT soldered onto the board. Those devices will have no WiFi reception on the ESP32! This version is now discontinued, but some sellers might have old stock.","title":"Models"},{"location":"hardware/golden-security/gs-t3e/#packaging","text":"","title":"Packaging"},{"location":"hardware/golden-security/gs-t3e/#flashing","text":"Disclaimer Never connect high-voltage when the panel is not properly secured in place. Device can be flashed by either using the USB port or the flash header pins and a FTDI serial programmer device. Steps to flash via USB: Disengage the panel from high-voltage power Detach the panel from the PSU power supply Connect a Micro USB cable Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Steps to flash via UART: Disengage the panel from high-voltage power Detach the panel from the PSU power supply Connect jumper wires: GND <--> GND 5V <--> 5V RX <--> RX (not reversed!) TX <--> TX (not reversed!) Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Once the connections are made, flash the GS-T3E ESP32 binary like on any other device.","title":"Flashing"},{"location":"hardware/golden-security/gs-t3e/#gpio-settings","text":"","title":"GPIO Settings"},{"location":"hardware/golden-security/gs-t3e/#3-gang-eu-version-gs-t3e","text":"Pin Mode GS-T3E Group Default 45 Output Relay L1 1 Low (Normal) 46 Output Relay L2 2 Low (Normal) 44 Output Relay L3 3 Low (Normal) Tip To configure the GPIOs as light switches at once for GS-T3E send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 655918 , 656172 , 655661 , 0 , 0 , 0 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721454 , 721708 , 721197 , 0 , 0 , 0 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 }","title":"3-gang EU version GS-T3E"},{"location":"hardware/golden-security/gs-t3e/#wiring-diagram","text":"The switch supports this wiring configuration: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring.","title":"Wiring Diagram"},{"location":"hardware/golden-security/gs-t3e/#product-video","text":"Your browser does not support the video tag.","title":"Product Video"},{"location":"hardware/golden-security/gs-t3e/#gallery","text":"","title":"Gallery"},{"location":"hardware/lanbon/lanbon-l8/","text":"Lanbon L8 ~ Models ~ L8-HS: 3 Relays - load up to 200W/gang L8-HD: 1 Dimmer - load up to 200W/gang L8-HB: Boiler switch - load up to 16A L8-HT: Thermostat switch - not tested! Warning Choose a model that works with Apple HomeKit because those are WiFi versions with the internal antenna connected to the ESP32. Do NOT buy a version that is powered by Tuya Smart Life because the internal antenna is connected to the Tuya chip. Those devices will have very bad WiFi reception of the ESP32! Form factor ~ EU model: 86mm x 86mm US model: 120mm x 74mm All models are rated at AC 100-250V ~50-60Hz, the form factor can be a design choice regardless of the continental area. The models have the same recessed housing sliding into the wall, sized 50x50mm, with rounded corners creating a diameter of about 59mm. This makes them suitable for both EU and US wall fixtures. The EU model fits in a properly deployed, standard 60mm round wall box and can be fixed with two side screws (use the screws which belong to the box instead of the ones shipped with the device), the US model fits in the standard rectangular box and can be fixed through the oval holes located 3 1/4\" apart. The depth of the wall box has to be at least 35-40mm because some room is needed for the wires coming out straight of the device. Bezel Color ~ Black White Features: ~ Input voltage 110-250V ~ 50-60Hz AC ESP32-WROVER-B Capacitive touch screen Energy counter Pros Cons 8 MB flash Mood LEDS not uniform 8 MB PSram Capactitive touch Built-in PSU Energy monitor Standard wallmount form factor both EU and US Buy Note 1 An earlier revision V1.14 (20191203) of the PCB had an analog temperature sensor onboard. It was removed from V1.15 (20200521) of the PCB. You are likely not to get it when buying a recent switch. Note 2 There is a new V1.17 of the PCB with Tuya support. openHASP does not support the proprietary Tuya chip, but you can still flash the firmware and use the other Lanbon L8 features just fine. Contents ~ Flashing ~ Disclaimer Never connect high-voltage when the panel is not properly secured in place. You can follow this flashing guide on blakadder.com or this discussion post with instructions and photos to flash the firmware without having to open the device. Steps: Disengage the high-voltage power Detach the panel from the PSU power supply Connect RX , TX , IO0 , GND and 5V pins to the female pinheader Because there is no RESET pin, you need to powercycle the board while IO0 is connected to GND to activate flash mode Make sure you have a USB to serial adapter than can provide sufficient power on the 5V pin . Once the serial connections are made, flash the Lanbon-L8 ESP32 binary like on any other device. GPIO Settings ~ 3-gang version L8-HS ~ Pin Mode L8-HS Group Default 12 Output Relay (K3) 1 Low (Normal) 14 Output Relay 2 Low (Normal) 26 Output Mood Red 4 Low (Normal) 27 Output Relay 3 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs as light switches at once for L8-HS send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 197658 , 263456 , 329249 , 655628 , 655886 , 656155 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721164 , 721422 , 197658 , 721691 , 263456 , 329249 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 } Dimmer version L8-HD ~ Pin Mode L8-HD Group Default 12 Output Dimmer TX (K3) 1 Low (Normal) 26 Output Mood Red 4 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Warning There are two versions of the dimmer configuration: EU and AU . The protocol used to command the dimmer module differs between the two! Make sure that you have the correct type configured under your GPIO Output settings for pin 12 . Use the AU configuration for any 120V/US compatible dimmer modules. Tip To configure the GPIOs at once for L8-HD send to topic hasp//config/gpio a message with payload: EU version: 1 { \"config\" :[ 3211532 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} AU/US version: 1 { \"config\" :[ 3277068 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} Boiler version L8-HB ~ Pin Mode L8-HB Group Default 26 Output Mood Red 4 Low (Normal) 27 Output Relay 16A (K1) 1 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs at once for L8-HB send to topic hasp//config a message with payload: 1 { \"gpio\" :{ \"config\" :[ 197658 , 263456 , 329249 , 721179 , 14 , 27 , 0 , 0 ]}} Developer Note You can build your own firmware with GPIOs and many other parameters pre-configured in user_config_override.h as factory defaults for Lanbon L8. Wiring Diagrams ~ The switch supports several wiring configurations: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring. Product Video ~ Your browser does not support the video tag. Gallery ~ LCD Configuration ~ The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 st7789v = -D ST7789_DRIVER = 1 ;-D CGRAM_OFFSET=1 ; Library will add offsets required -D TFT_SDA_READ ; Read from display, it only provides an SDA pin -D TFT_WIDTH = 240 -D TFT_HEIGHT = 320 -D TFT_ROTATION = 2 ; see TFT_ROTATION values ; -D TFT_INVERSION_OFF ; for normal colors ; -D TFT_RGB_ORDER=TFT_RGB ; Colour order Red-Green-Blue -D TFT_RGB_ORDER = TFT_BGR ; Colour order Blue-Green-Red -D SPI_FREQUENCY = 80000000 -D SPI_READ_FREQUENCY = 6000000 -D USER_SETUP_LOADED = 1 -D SUPPORT_TRANSACTIONS HASP build_flags ~ Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 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 build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.ps_ram} ;region -- TFT_eSPI build options ------------------------ ${lcd.st7789v} -D LANBONL8 -D TFT_RST = 18 ; FCP pin2 RESET -D TFT_SCLK = 19 ; FCP pin3 SCL -D TFT_DC = 21 ; FCP pin4 D/C -D TFT_CS = 22 ; FCP pin5 CS -D TFT_MOSI = 23 ; FCP pin6 SDA -D TFT_MISO = 25 ; FCP pin7 SDO -D TFT_BCKL = 5 -D TOUCH_DRIVER = 6336 -D TOUCH_SDA = 4 -D TOUCH_SCL = 0 -D TOUCH_IRQ = -1 ; not connected -D TOUCH_RST = -1 ; not used, connected to 3.3V on FCP pin10 -D TOUCH_FREQUENCY = 400000 -D LED_RED = 26 -D LED_GREEN = 32 -D LED_BLUE = 33 -D RELAY_1 = 12 -D RELAY_2 = 24 -D RELAY_3 = 37 ;endregion","title":"Lanbon"},{"location":"hardware/lanbon/lanbon-l8/#lanbon-l8","text":"","title":"Lanbon L8"},{"location":"hardware/lanbon/lanbon-l8/#models","text":"L8-HS: 3 Relays - load up to 200W/gang L8-HD: 1 Dimmer - load up to 200W/gang L8-HB: Boiler switch - load up to 16A L8-HT: Thermostat switch - not tested! Warning Choose a model that works with Apple HomeKit because those are WiFi versions with the internal antenna connected to the ESP32. Do NOT buy a version that is powered by Tuya Smart Life because the internal antenna is connected to the Tuya chip. Those devices will have very bad WiFi reception of the ESP32!","title":"Models"},{"location":"hardware/lanbon/lanbon-l8/#contents","text":"","title":"Contents"},{"location":"hardware/lanbon/lanbon-l8/#flashing","text":"Disclaimer Never connect high-voltage when the panel is not properly secured in place. You can follow this flashing guide on blakadder.com or this discussion post with instructions and photos to flash the firmware without having to open the device. Steps: Disengage the high-voltage power Detach the panel from the PSU power supply Connect RX , TX , IO0 , GND and 5V pins to the female pinheader Because there is no RESET pin, you need to powercycle the board while IO0 is connected to GND to activate flash mode Make sure you have a USB to serial adapter than can provide sufficient power on the 5V pin . Once the serial connections are made, flash the Lanbon-L8 ESP32 binary like on any other device.","title":"Flashing"},{"location":"hardware/lanbon/lanbon-l8/#gpio-settings","text":"","title":"GPIO Settings"},{"location":"hardware/lanbon/lanbon-l8/#3-gang-version-l8-hs","text":"Pin Mode L8-HS Group Default 12 Output Relay (K3) 1 Low (Normal) 14 Output Relay 2 Low (Normal) 26 Output Mood Red 4 Low (Normal) 27 Output Relay 3 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs as light switches at once for L8-HS send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 197658 , 263456 , 329249 , 655628 , 655886 , 656155 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721164 , 721422 , 197658 , 721691 , 263456 , 329249 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 }","title":"3-gang version L8-HS"},{"location":"hardware/lanbon/lanbon-l8/#dimmer-version-l8-hd","text":"Pin Mode L8-HD Group Default 12 Output Dimmer TX (K3) 1 Low (Normal) 26 Output Mood Red 4 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Warning There are two versions of the dimmer configuration: EU and AU . The protocol used to command the dimmer module differs between the two! Make sure that you have the correct type configured under your GPIO Output settings for pin 12 . Use the AU configuration for any 120V/US compatible dimmer modules. Tip To configure the GPIOs at once for L8-HD send to topic hasp//config/gpio a message with payload: EU version: 1 { \"config\" :[ 3211532 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} AU/US version: 1 { \"config\" :[ 3277068 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]}","title":"Dimmer version L8-HD"},{"location":"hardware/lanbon/lanbon-l8/#boiler-version-l8-hb","text":"Pin Mode L8-HB Group Default 26 Output Mood Red 4 Low (Normal) 27 Output Relay 16A (K1) 1 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs at once for L8-HB send to topic hasp//config a message with payload: 1 { \"gpio\" :{ \"config\" :[ 197658 , 263456 , 329249 , 721179 , 14 , 27 , 0 , 0 ]}} Developer Note You can build your own firmware with GPIOs and many other parameters pre-configured in user_config_override.h as factory defaults for Lanbon L8.","title":"Boiler version L8-HB"},{"location":"hardware/lanbon/lanbon-l8/#wiring-diagrams","text":"The switch supports several wiring configurations: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring.","title":"Wiring Diagrams"},{"location":"hardware/lanbon/lanbon-l8/#product-video","text":"Your browser does not support the video tag.","title":"Product Video"},{"location":"hardware/lanbon/lanbon-l8/#gallery","text":"","title":"Gallery"},{"location":"hardware/lanbon/lanbon-l8/#lcd-configuration","text":"The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 st7789v = -D ST7789_DRIVER = 1 ;-D CGRAM_OFFSET=1 ; Library will add offsets required -D TFT_SDA_READ ; Read from display, it only provides an SDA pin -D TFT_WIDTH = 240 -D TFT_HEIGHT = 320 -D TFT_ROTATION = 2 ; see TFT_ROTATION values ; -D TFT_INVERSION_OFF ; for normal colors ; -D TFT_RGB_ORDER=TFT_RGB ; Colour order Red-Green-Blue -D TFT_RGB_ORDER = TFT_BGR ; Colour order Blue-Green-Red -D SPI_FREQUENCY = 80000000 -D SPI_READ_FREQUENCY = 6000000 -D USER_SETUP_LOADED = 1 -D SUPPORT_TRANSACTIONS","title":"LCD Configuration"},{"location":"hardware/lanbon/lanbon-l8/#hasp-build_flags","text":"Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 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 build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.ps_ram} ;region -- TFT_eSPI build options ------------------------ ${lcd.st7789v} -D LANBONL8 -D TFT_RST = 18 ; FCP pin2 RESET -D TFT_SCLK = 19 ; FCP pin3 SCL -D TFT_DC = 21 ; FCP pin4 D/C -D TFT_CS = 22 ; FCP pin5 CS -D TFT_MOSI = 23 ; FCP pin6 SDA -D TFT_MISO = 25 ; FCP pin7 SDO -D TFT_BCKL = 5 -D TOUCH_DRIVER = 6336 -D TOUCH_SDA = 4 -D TOUCH_SCL = 0 -D TOUCH_IRQ = -1 ; not connected -D TOUCH_RST = -1 ; not used, connected to 3.3V on FCP pin10 -D TOUCH_FREQUENCY = 400000 -D LED_RED = 26 -D LED_GREEN = 32 -D LED_BLUE = 33 -D RELAY_1 = 12 -D RELAY_2 = 24 -D RELAY_3 = 37 ;endregion","title":"HASP build_flags"},{"location":"hardware/lilygo/lilygo-lily-pi/","text":"LilyGO\u00ae Lily Pi ~ Features ~ ESP32-WROVER ILI9481 or ST7796 3.5\" (480*320) TFT screen in 4-wire SPI mode FT6X36 or GT911 Capacitive Touch Controller CP2104 USB-to-UART IC USB-C connector DC 5-12V barrel jack (5.5x2.1mm) Relay HFD3 5V 2A microSD card holder Real Time Clock PCF8563 Battery voltage divider connected to GPIO35 GPIO output via USB-A type connectors The Lily Pi is designed to resemble the Raspberry Pi appearance. The PCB layout and ports also mimmicks the Rasberry Pi. There is even the familiar 2x20 expansion port inside that match the Raspberry Pi GPIO pinout. Some Rpi expansion boards could work on this PCB too depending on the pins used. Pros Cons 480x320 display Non-standard USB-A connectors as GPIO 16 MB flash 8 MB PSram Capacitive Touchscreen The RTC and SD card are not supported by openHASP 0.7.0-rc9. Models ~ Model TN ST7796 FT6236 IPS ILI9481 GT911 SKU K113 K113-01 Resolution 480x320 480x320 TFT controller ST7796 ILI9481 Interface SPI SPI Touchscreen Capacitive Capacitive Touch controller FT6236 GT911 Screen dimming yes yes Buy AliExpress Tindie Buy AliExpress Tindie Video ~ Backlight Control ~ The GPIO that controls the backlight is GPIO12 . Documentation ~ The Lily Pi comes with the following information cards describing all the GPIOs used: Flashing ~ The LilyGO Lily Pi can easily be flashed over USB like any ESP32 development board. Dimensions ~ Size: 99.7 x 62.5 x 31.2mm","title":"Lily Pi"},{"location":"hardware/lilygo/lilygo-lily-pi/#lilygo-lily-pi","text":"","title":"LilyGO\u00ae Lily Pi"},{"location":"hardware/lilygo/lilygo-lily-pi/#features","text":"ESP32-WROVER ILI9481 or ST7796 3.5\" (480*320) TFT screen in 4-wire SPI mode FT6X36 or GT911 Capacitive Touch Controller CP2104 USB-to-UART IC USB-C connector DC 5-12V barrel jack (5.5x2.1mm) Relay HFD3 5V 2A microSD card holder Real Time Clock PCF8563 Battery voltage divider connected to GPIO35 GPIO output via USB-A type connectors The Lily Pi is designed to resemble the Raspberry Pi appearance. The PCB layout and ports also mimmicks the Rasberry Pi. There is even the familiar 2x20 expansion port inside that match the Raspberry Pi GPIO pinout. Some Rpi expansion boards could work on this PCB too depending on the pins used. Pros Cons 480x320 display Non-standard USB-A connectors as GPIO 16 MB flash 8 MB PSram Capacitive Touchscreen The RTC and SD card are not supported by openHASP 0.7.0-rc9.","title":"Features"},{"location":"hardware/lilygo/lilygo-lily-pi/#models","text":"Model TN ST7796 FT6236 IPS ILI9481 GT911 SKU K113 K113-01 Resolution 480x320 480x320 TFT controller ST7796 ILI9481 Interface SPI SPI Touchscreen Capacitive Capacitive Touch controller FT6236 GT911 Screen dimming yes yes Buy AliExpress Tindie Buy AliExpress Tindie","title":"Models"},{"location":"hardware/lilygo/lilygo-lily-pi/#video","text":"","title":"Video"},{"location":"hardware/lilygo/lilygo-lily-pi/#backlight-control","text":"The GPIO that controls the backlight is GPIO12 .","title":"Backlight Control"},{"location":"hardware/lilygo/lilygo-lily-pi/#documentation","text":"The Lily Pi comes with the following information cards describing all the GPIOs used:","title":"Documentation"},{"location":"hardware/lilygo/lilygo-lily-pi/#flashing","text":"The LilyGO Lily Pi can easily be flashed over USB like any ESP32 development board.","title":"Flashing"},{"location":"hardware/lilygo/lilygo-lily-pi/#dimensions","text":"Size: 99.7 x 62.5 x 31.2mm","title":"Dimensions"},{"location":"hardware/lilygo/lilygo-t-display-s3/","text":"LilyGO\u00ae T-Display-S3 ~ Warning The configuration for this board is under development and not finilized yet. LILYGO\u00ae T-Display-S3 ESP32-S3 1.9\" ST7789 LCD Display Development Board WIFI Bluetooth5.0 Wireless Module 170*320 Resolution T-Display-S3 is a development board whose main control chip is ESP32-S3. It is equipped with a 1.9\" LCD color screen and two programmable buttons. Communication using the I8080 interface Retains the same layout design as T-Display. You can directly use ESP32S3 for USB communication or programming. Specifications ~ Pros Cons MCU ESP32-S3R8 Dual-core LX7 microprocessor Wireless Connectivity Wi-Fi 802.11, BLE 5 + BT mesh Flash 16MB PSRAM 8MB Bat voltage detection IO04 Onboard functions Boot + Reset + IO14 Button LCD 1.9\" diagonal, Full-color TFT Display Drive Chip ST7789V Resolution 170(H)RGB x320(V) 8-Bit Parallel Interface Connectors JST-GH 1.25mm 2PIN STEMMA QT / Qwiic JST-SH 1.0mm 4-PIN Touch Edition ~ ESP32-S3 1.9\" ST7789 LCD Display with Touch Screen Development Board. Basic Edition ~ The Basic Edition of the LilyGO\u00ae T-Display-S3 does not have a touchscreen. It can only be used to display information. You can not interact with objects on the screen. However, you can connect GPIOs and/or use the push buttons to integrate the device into your Home Automation system. Documentation ~ Documentation ~ Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"T-Display-S3"},{"location":"hardware/lilygo/lilygo-t-display-s3/#lilygo-t-display-s3","text":"Warning The configuration for this board is under development and not finilized yet. LILYGO\u00ae T-Display-S3 ESP32-S3 1.9\" ST7789 LCD Display Development Board WIFI Bluetooth5.0 Wireless Module 170*320 Resolution T-Display-S3 is a development board whose main control chip is ESP32-S3. It is equipped with a 1.9\" LCD color screen and two programmable buttons. Communication using the I8080 interface Retains the same layout design as T-Display. You can directly use ESP32S3 for USB communication or programming.","title":"LilyGO\u00ae T-Display-S3"},{"location":"hardware/lilygo/lilygo-t-display-s3/#specifications","text":"Pros Cons MCU ESP32-S3R8 Dual-core LX7 microprocessor Wireless Connectivity Wi-Fi 802.11, BLE 5 + BT mesh Flash 16MB PSRAM 8MB Bat voltage detection IO04 Onboard functions Boot + Reset + IO14 Button LCD 1.9\" diagonal, Full-color TFT Display Drive Chip ST7789V Resolution 170(H)RGB x320(V) 8-Bit Parallel Interface Connectors JST-GH 1.25mm 2PIN STEMMA QT / Qwiic JST-SH 1.0mm 4-PIN","title":"Specifications"},{"location":"hardware/lilygo/lilygo-t-display-s3/#touch-edition","text":"ESP32-S3 1.9\" ST7789 LCD Display with Touch Screen Development Board.","title":"Touch Edition"},{"location":"hardware/lilygo/lilygo-t-display-s3/#basic-edition","text":"The Basic Edition of the LilyGO\u00ae T-Display-S3 does not have a touchscreen. It can only be used to display information. You can not interact with objects on the screen. However, you can connect GPIOs and/or use the push buttons to integrate the device into your Home Automation system.","title":"Basic Edition"},{"location":"hardware/lilygo/lilygo-t-display-s3/#documentation","text":"","title":"Documentation"},{"location":"hardware/lilygo/lilygo-t-display-s3/#documentation_1","text":"Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"Documentation"},{"location":"hardware/lilygo/lilygo-t-hmi/","text":"LILYGO\u00ae T-HMI ESP32-S3 ~ Warning The configuration for this board is currently being tested. T-HMI is currently LILYGO's largest touch display screen equipped with ESP32-S3 chip. The screen uses a 2.8-inch ST7789 LCD and is equipped with a resistive screen stylus/pen. It has 16 MB onboard Flash and 8MB PSram. It can be powered via the USB-C interface, 5V DC seat or battery connector. Pros Cons 16 MB flash Resistive Touchscreen 8 MB PSram 3 Groove ports The SD card is not supported by openHASP 0.7.0-rc9. AliExpress Tindie","title":"T-HMI ESP32-S3"},{"location":"hardware/lilygo/lilygo-t-hmi/#lilygo-t-hmi-esp32-s3","text":"Warning The configuration for this board is currently being tested. T-HMI is currently LILYGO's largest touch display screen equipped with ESP32-S3 chip. The screen uses a 2.8-inch ST7789 LCD and is equipped with a resistive screen stylus/pen. It has 16 MB onboard Flash and 8MB PSram. It can be powered via the USB-C interface, 5V DC seat or battery connector. Pros Cons 16 MB flash Resistive Touchscreen 8 MB PSram 3 Groove ports The SD card is not supported by openHASP 0.7.0-rc9. AliExpress Tindie","title":"LILYGO\u00ae T-HMI ESP32-S3 "},{"location":"hardware/lilygo/lilygo-t-rgb-s3/","text":"LilyGO\u00ae T-RGB ESP32-S3 ~ Warning The configuration for this board is under development and not finilized yet. Oval Edition ~ Round Edition ~ There is an Oval and a Round Edition of the LilyGO\u00ae T-RGB ESP32-S3. Both have a capacitive touchscreen.","title":"T-RGB-S3 2.1\""},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#lilygo-t-rgb-esp32-s3","text":"Warning The configuration for this board is under development and not finilized yet.","title":"LilyGO\u00ae T-RGB ESP32-S3"},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#oval-edition","text":"","title":"Oval Edition"},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#round-edition","text":"There is an Oval and a Round Edition of the LilyGO\u00ae T-RGB ESP32-S3. Both have a capacitive touchscreen.","title":"Round Edition"},{"location":"hardware/lilygo/ttgo-t7-s3/","text":"Warning The configuration for this board is under development and not finilized yet. LilyGO\u00ae T7 S3 ESP32-S3 ~ T7 S3 is an ESP32 module based on the ESP32-S3-WROOM-1, with 16 MB built-in Flash and 8MB PSram. AliExpress Tindie","title":"T7-S3 v1.1"},{"location":"hardware/lilygo/ttgo-t7-s3/#lilygo-t7-s3-esp32-s3","text":"T7 S3 is an ESP32 module based on the ESP32-S3-WROOM-1, with 16 MB built-in Flash and 8MB PSram. AliExpress Tindie","title":"LilyGO\u00ae T7 S3 ESP32-S3"},{"location":"hardware/lolin/lolin-tft-shield/","text":"Lolin TFT 2.4\" Touch Shield ~ Features ~ This Lolin TFT has a 2.4\" touchscreen with XPT2046 resistive touch controller. There are 3 ways to connect an ESP32: Plug a compatible ESP32 onto the female headers on the back Attach a LOLIN D32 Pro V2.0 using the 10-pin TFT connector and cable Solder headers onto the bottom pinholes for pluging into a breadboard or jumper cables for any other ESP32 Pros Cons Plug-and-play Resistive touchscreen Limited soldering required Availability Choice of several ESP32 MCUs Price Buy Compatible ESP32 dev boards ~ The Lolin TFT 2.4\" headers are plug-and-play compatible with these development boards, no need to use any jumper cables: Model Minimal Better Best SKU D1 Mini ESP32 TTGO T7 V1.5 Mini32 Lolin D32 Pro V2.0 MCU ESP32-WROOM ESP32-WROVER ESP32-WROVER Flash 4 MB 4 or 16 MB 4 or 16 MB PSram No 8 MB 8 MB Connection Two 1x8 Pinheaders\u00b2 Two 1x8 Pinheaders\u00b2 10-pin TFT cable (optional) SD Card no no yes Battery charging no yes yes USB Chip CH9102F CH340C Screen dimming yes yes yes Buy Buy Buy Warning The D1 Mini ESP32 board may suffer from brown-out reboots if not powered adequately. Note (\u00b2) Because the board is developed for the D1-mini, you must only solder a row of 1x8 male pins to pads TXD-5V and RST-3V3 each. Product Video ~ Backlight Control ~ To use PWM dimming on the Lolin TFT 2.4\" you must bridge the center TFT-LED pin to the D1 solder pad next to it. This pin is configured by default in the firmware. Warning Do not use D3 for backlight control because it is already in use for touch! Do not use D4 for backlight control because it is already in use for PSram on the ESP32-WROVER. The D1-mini has D4 connected to the on-board LED and boot fails if pulled LOW. Documentation ~ Wemos Wiki Schematics Dimensions ~","title":"Lolin"},{"location":"hardware/lolin/lolin-tft-shield/#lolin-tft-24-touch-shield","text":"","title":"Lolin TFT 2.4\" Touch Shield"},{"location":"hardware/lolin/lolin-tft-shield/#features","text":"This Lolin TFT has a 2.4\" touchscreen with XPT2046 resistive touch controller. There are 3 ways to connect an ESP32: Plug a compatible ESP32 onto the female headers on the back Attach a LOLIN D32 Pro V2.0 using the 10-pin TFT connector and cable Solder headers onto the bottom pinholes for pluging into a breadboard or jumper cables for any other ESP32 Pros Cons Plug-and-play Resistive touchscreen Limited soldering required Availability Choice of several ESP32 MCUs Price Buy","title":"Features"},{"location":"hardware/lolin/lolin-tft-shield/#compatible-esp32-dev-boards","text":"The Lolin TFT 2.4\" headers are plug-and-play compatible with these development boards, no need to use any jumper cables: Model Minimal Better Best SKU D1 Mini ESP32 TTGO T7 V1.5 Mini32 Lolin D32 Pro V2.0 MCU ESP32-WROOM ESP32-WROVER ESP32-WROVER Flash 4 MB 4 or 16 MB 4 or 16 MB PSram No 8 MB 8 MB Connection Two 1x8 Pinheaders\u00b2 Two 1x8 Pinheaders\u00b2 10-pin TFT cable (optional) SD Card no no yes Battery charging no yes yes USB Chip CH9102F CH340C Screen dimming yes yes yes Buy Buy Buy Warning The D1 Mini ESP32 board may suffer from brown-out reboots if not powered adequately. Note (\u00b2) Because the board is developed for the D1-mini, you must only solder a row of 1x8 male pins to pads TXD-5V and RST-3V3 each.","title":"Compatible ESP32 dev boards"},{"location":"hardware/lolin/lolin-tft-shield/#product-video","text":"","title":"Product Video"},{"location":"hardware/lolin/lolin-tft-shield/#backlight-control","text":"To use PWM dimming on the Lolin TFT 2.4\" you must bridge the center TFT-LED pin to the D1 solder pad next to it. This pin is configured by default in the firmware. Warning Do not use D3 for backlight control because it is already in use for touch! Do not use D4 for backlight control because it is already in use for PSram on the ESP32-WROVER. The D1-mini has D4 connected to the on-board LED and boot fails if pulled LOW.","title":"Backlight Control"},{"location":"hardware/lolin/lolin-tft-shield/#documentation","text":"Wemos Wiki Schematics","title":"Documentation"},{"location":"hardware/lolin/lolin-tft-shield/#dimensions","text":"","title":"Dimensions"},{"location":"hardware/m5stack/core2/","text":"M5Stack core2 ~ M5Stack core2 is the second generation core device in the M5Stack development kit series. The core2 features a 2\" capacitive touchscreen, unlike its predecessor, making it very suitable to run openHASP. The device is packed with a beefy ESP32 model D0WDQ6-V3 and lots of sensors. Features ~ 1W Speaker SPM1423 Microphone Vibration Motor 3.7V / 390 mAh battery with power management chip SD card slot (16 GB maximum size) IMU (3-axis gyroscope & 3-axis accelerometer) Dimensions: 54 x 54 x 16mm Pros Cons 16 MB flash Small display 8 MB PSram Internal Battery Capacitive Touchscreen Available from: M5stack Mouser Digikey Amazon Product Video ~ Schematic ~ Schematics M5Stack Library ~ The M5Stack series comes with an opensource library to give you a jump start in deveopment for this device, including a Getting Started guide, examples and API reference. Visit the M5Stack Github repo.","title":"M5stack"},{"location":"hardware/m5stack/core2/#m5stack-core2","text":"M5Stack core2 is the second generation core device in the M5Stack development kit series. The core2 features a 2\" capacitive touchscreen, unlike its predecessor, making it very suitable to run openHASP. The device is packed with a beefy ESP32 model D0WDQ6-V3 and lots of sensors.","title":"M5Stack core2"},{"location":"hardware/m5stack/core2/#features","text":"1W Speaker SPM1423 Microphone Vibration Motor 3.7V / 390 mAh battery with power management chip SD card slot (16 GB maximum size) IMU (3-axis gyroscope & 3-axis accelerometer) Dimensions: 54 x 54 x 16mm Pros Cons 16 MB flash Small display 8 MB PSram Internal Battery Capacitive Touchscreen Available from: M5stack Mouser Digikey Amazon","title":"Features"},{"location":"hardware/m5stack/core2/#product-video","text":"","title":"Product Video"},{"location":"hardware/m5stack/core2/#schematic","text":"Schematics","title":"Schematic"},{"location":"hardware/m5stack/core2/#m5stack-library","text":"The M5Stack series comes with an opensource library to give you a jump start in deveopment for this device, including a Getting Started guide, examples and API reference. Visit the M5Stack Github repo.","title":"M5Stack Library"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/","text":"ESP32-S3 Parallel TFT with Touch ~ Warning The configuration for this board is under development and not finilized yet. more images... Features ~ The Makerfabs ESP32-S3 Parallel TFT Touch development board incorporates a 3.5\u201d, 4.0\u201d or 4.3\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and PSram. There is also an SD-card slot, USB-C connectors and two expansion ports. Models ~ Model 3.5\" Parallel 4.0\" Parallel 4.3\" Parallel SKU ESP32S335D E32S3RGB40 E32S3RGB43 Flash 16 MB 16 MB 16 MB PSram 2 MB 8 MB 8 MB Display 3.5\" 480x320 4.0\" IPS 4.3\" IPS Resolution 480x320 480x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Real Time Clock no no yes Screen dimming GPIO45 GPIO2 GPIO2 Buy Buy Buy Also available on Tindie The real-time clock and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ The backlight of the 3.5\" model can be controlled by PWM on pin GPIO45 . The backlight on the 4.0\" model is always on and can not be controlled. The backlight of the 4.3\" model can be controlled by PWM on pin GPIO02 if the PCB is v1.3 only. With PCB v2.0 the backlight can not be adjusted and the screen is always on. Video ~ ESP32-S3 Parallel TFT with Touch 3.5'' ILI9488 ~ ESP32-S3 Parallel TFT with Touch 4.0\" ~ ESP32-S3 Parallel TFT with Touch 4.3\" ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"ESP32-S3 Parallel TFT"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch","text":"Warning The configuration for this board is under development and not finilized yet. more images...","title":"ESP32-S3 Parallel TFT with Touch"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#features","text":"The Makerfabs ESP32-S3 Parallel TFT Touch development board incorporates a 3.5\u201d, 4.0\u201d or 4.3\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and PSram. There is also an SD-card slot, USB-C connectors and two expansion ports.","title":"Features"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#models","text":"Model 3.5\" Parallel 4.0\" Parallel 4.3\" Parallel SKU ESP32S335D E32S3RGB40 E32S3RGB43 Flash 16 MB 16 MB 16 MB PSram 2 MB 8 MB 8 MB Display 3.5\" 480x320 4.0\" IPS 4.3\" IPS Resolution 480x320 480x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Real Time Clock no no yes Screen dimming GPIO45 GPIO2 GPIO2 Buy Buy Buy Also available on Tindie The real-time clock and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#backlight-control","text":"The backlight of the 3.5\" model can be controlled by PWM on pin GPIO45 . The backlight on the 4.0\" model is always on and can not be controlled. The backlight of the 4.3\" model can be controlled by PWM on pin GPIO02 if the PCB is v1.3 only. With PCB v2.0 the backlight can not be adjusted and the screen is always on.","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-35-ili9488","text":"","title":"ESP32-S3 Parallel TFT with Touch 3.5'' ILI9488"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-40","text":"","title":"ESP32-S3 Parallel TFT with Touch 4.0\""},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-43","text":"","title":"ESP32-S3 Parallel TFT with Touch 4.3\""},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/","text":"ESP32-S3 SPI TFT with Touch ~ more images... Features ~ The ESP32-S3 SPI TFT with Touch development board incorporates a 3.5\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and 2MB of PSram. There is also an SD-card slot, USB-C connectors and expansion port with 14 GPIOs. Models ~ Model 3.5\" SPI SKU ESP32S3SPI35 Flash 16 MB PSram 2 MB Resolution 3.5\" 480x320 Touch Screen Capacitive SD Card yes Screen dimming yes Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ The backlight can be controlled by PWM on GPIO48 . Video ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"ESP32-S3 SPI TFT"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#esp32-s3-spi-tft-with-touch","text":"more images...","title":"ESP32-S3 SPI TFT with Touch"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#features","text":"The ESP32-S3 SPI TFT with Touch development board incorporates a 3.5\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and 2MB of PSram. There is also an SD-card slot, USB-C connectors and expansion port with 14 GPIOs.","title":"Features"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#models","text":"Model 3.5\" SPI SKU ESP32S3SPI35 Flash 16 MB PSram 2 MB Resolution 3.5\" 480x320 Touch Screen Capacitive SD Card yes Screen dimming yes Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#backlight-control","text":"The backlight can be controlled by PWM on GPIO48 .","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"hardware/makerfabs/esp32-tft-touch/","text":"ESP32 TFT Touch with Camera ~ more images... Features ~ The Makerfabs ESP32 TFT Touch development board incorporates a 3.2\u201d or 3.5\u201d touch display, with a built-in 2M pixel OV2640 camera, which makes it a very suitable platform for any ESP32 project. There is a version with capacitive and resistive touch. At the back sits an ESP32-WROVER module with 16MB of flash and 8MB of PSram. There is also an SD-card slot, USB-C connector and expansion port with 14 GPIOs. Models ~ Model 3.2\" Resistive 3.5\" Resistive 3.5\" Capacitive SKU ESPTFT32CA ESPTFT35RE ESPTFT35CA Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Resolution 3.2\" 320x240 3.5\" 480x320 3.5\" 480x320 Touch Screen Resistive Resistive Capacitive OV2640 Camera 2M pixel 2M pixel 2M pixel SD Card yes yes yes Screen dimming no no no Buy Buy Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ Unfortunately, there is no support for backlight control. The display is always-on. Video ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Acrylic Case ~ All 3 models have the option to add a protective acrylic case for only $2.90 extra:","title":"ESP32 SPI TFT with Camera"},{"location":"hardware/makerfabs/esp32-tft-touch/#esp32-tft-touch-with-camera","text":"more images...","title":"ESP32 TFT Touch with Camera"},{"location":"hardware/makerfabs/esp32-tft-touch/#features","text":"The Makerfabs ESP32 TFT Touch development board incorporates a 3.2\u201d or 3.5\u201d touch display, with a built-in 2M pixel OV2640 camera, which makes it a very suitable platform for any ESP32 project. There is a version with capacitive and resistive touch. At the back sits an ESP32-WROVER module with 16MB of flash and 8MB of PSram. There is also an SD-card slot, USB-C connector and expansion port with 14 GPIOs.","title":"Features"},{"location":"hardware/makerfabs/esp32-tft-touch/#models","text":"Model 3.2\" Resistive 3.5\" Resistive 3.5\" Capacitive SKU ESPTFT32CA ESPTFT35RE ESPTFT35CA Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Resolution 3.2\" 320x240 3.5\" 480x320 3.5\" 480x320 Touch Screen Resistive Resistive Capacitive OV2640 Camera 2M pixel 2M pixel 2M pixel SD Card yes yes yes Screen dimming no no no Buy Buy Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-tft-touch/#backlight-control","text":"Unfortunately, there is no support for backlight control. The display is always-on.","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-tft-touch/#acrylic-case","text":"All 3 models have the option to add a protective acrylic case for only $2.90 extra:","title":"Acrylic Case"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/","text":"SenseCAP Indicator D1 ~ more images... SenseCAP Indicator D1 is a 4-inch touch screen driven by an ESP32-S3 and RP2040 dual-MCU and supports Wi-Fi/BLE communication. The ESP32-S3 has 8 MB flash and 8 MB PSRAM. It is a powerful, fully open-source IoT development platform. It can be powered via USB-C 2.0 on the bottom or the backside of the device. It is suitable for mounting on the wall or placement on a desk using the kickback stand. Models ~ The SenseCAP Indicator series offers four different versions: D1, D1S, D1L, and D1Pro. Each version is designed to meet different application needs without any extra cost from unnecessary hardware. Here are the differences between the versions: Attention openHASP does not support the D1S sensors or D1L Lora communications. Buy Mouser Kiwi Electronics Seeed Studio Documentation Product Video ~ Introduction to the SenseCAP Indicator D1: Gallery ~","title":"Seeed Studio"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#sensecap-indicator-d1","text":"more images... SenseCAP Indicator D1 is a 4-inch touch screen driven by an ESP32-S3 and RP2040 dual-MCU and supports Wi-Fi/BLE communication. The ESP32-S3 has 8 MB flash and 8 MB PSRAM. It is a powerful, fully open-source IoT development platform. It can be powered via USB-C 2.0 on the bottom or the backside of the device. It is suitable for mounting on the wall or placement on a desk using the kickback stand.","title":"SenseCAP Indicator D1"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#models","text":"The SenseCAP Indicator series offers four different versions: D1, D1S, D1L, and D1Pro. Each version is designed to meet different application needs without any extra cost from unnecessary hardware. Here are the differences between the versions: Attention openHASP does not support the D1S sensors or D1L Lora communications. Buy Mouser Kiwi Electronics Seeed Studio Documentation","title":"Models"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#product-video","text":"Introduction to the SenseCAP Indicator D1:","title":"Product Video"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#gallery","text":"","title":"Gallery"},{"location":"hardware/sunton/esp32-1732s019/","text":"Sunton ESP32-1732S019 ~ Warning The configuration for this board is under development and not finilized yet. These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress. Versions ~ There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: ESP32-3248S035 ~ Sunton ESP32 3.5inch Display Case Stand from Printables.com ESP32-4827S043 ~ Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-1732S019"},{"location":"hardware/sunton/esp32-1732s019/#sunton-esp32-1732s019","text":"Warning The configuration for this board is under development and not finilized yet. These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress.","title":"Sunton ESP32-1732S019 "},{"location":"hardware/sunton/esp32-1732s019/#versions","text":"There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Versions"},{"location":"hardware/sunton/esp32-1732s019/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-1732s019/#cases","text":"If you have a 3D printer, cases are becoming available:","title":"Cases"},{"location":"hardware/sunton/esp32-1732s019/#esp32-3248s035","text":"Sunton ESP32 3.5inch Display Case Stand from Printables.com","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-1732s019/#esp32-4827s043","text":"Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-1732s019/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-1732s019/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-1732s019/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-2432s028/","text":"Sunton ESP32-2432S028 ~ These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress. Versions ~ There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: ESP32-3248S035 ~ Sunton ESP32 3.5inch Display Case Stand from Printables.com ESP32-4827S043 ~ Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-2432S028"},{"location":"hardware/sunton/esp32-2432s028/#sunton-esp32-2432s028","text":"These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress.","title":"Sunton ESP32-2432S028 "},{"location":"hardware/sunton/esp32-2432s028/#versions","text":"There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Versions"},{"location":"hardware/sunton/esp32-2432s028/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-2432s028/#cases","text":"If you have a 3D printer, cases are becoming available:","title":"Cases"},{"location":"hardware/sunton/esp32-2432s028/#esp32-3248s035","text":"Sunton ESP32 3.5inch Display Case Stand from Printables.com","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-2432s028/#esp32-4827s043","text":"Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-2432s028/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-2432s028/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-2432s028/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-3248s035/","text":"Sunton ESP32-3248S035 ~ The ESP32-3248S035 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles. Models ~ Model Resistive Touch Capacitive Touch SKU ESP32-3248S035R ESP32-3248S035C MCU ESP32-D0WDQ6 ESP32-D0WDQ6 Flash 4 MB 4 MB PSram No No Display Panel 3.5\" TN 3.5' TN Resolution 480x320 480x320 Touch Screen Resistive Capacitive SD Card yes yes Screen dimming yes yes Buy Buy The SD card is not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32 Modules have no PSram and are less suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-3248s035/#sunton-esp32-3248s035","text":"The ESP32-3248S035 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles.","title":"Sunton ESP32-3248S035 "},{"location":"hardware/sunton/esp32-3248s035/#models","text":"Model Resistive Touch Capacitive Touch SKU ESP32-3248S035R ESP32-3248S035C MCU ESP32-D0WDQ6 ESP32-D0WDQ6 Flash 4 MB 4 MB PSram No No Display Panel 3.5\" TN 3.5' TN Resolution 480x320 480x320 Touch Screen Resistive Capacitive SD Card yes yes Screen dimming yes yes Buy Buy The SD card is not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32 Modules have no PSram and are less suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-3248s035/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-3248s035/#cases","text":"If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-3248s035/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-3248s035/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-3248s035/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-4827s043/","text":"Sunton ESP32-4827S043 ~ The ESP32-4827s043 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles. Models ~ Model TN Without Touch TN Resistive Touch TN Capacitive Touch SKU ESP32-4827S043 ESP32-4827S043R ESP32-4827S043C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" TN 4.3\" TN 4.3\" TN Resolution 480x272 480x272 480x272 Touch Screen None Resistive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-4827s043/#sunton-esp32-4827s043","text":"The ESP32-4827s043 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles.","title":"Sunton ESP32-4827S043 "},{"location":"hardware/sunton/esp32-4827s043/#models","text":"Model TN Without Touch TN Resistive Touch TN Capacitive Touch SKU ESP32-4827S043 ESP32-4827S043R ESP32-4827S043C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" TN 4.3\" TN 4.3\" TN Resolution 480x272 480x272 480x272 Touch Screen None Resistive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-4827s043/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-4827s043/#cases","text":"If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-4827s043/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-4827s043/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-4827s043/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-8048s0xx/","text":"Sunton ESP32-8048S0xx ~ These are great \"all-in-one\" device that have integrated ESP32-S3 chips with 16 MB of flash and 8MB PSram. There are 3 sizes available with an 800x480 resolution ranging from 4.3\", 5\" to 7\" display and built in capacitive touch panel. The 4.3\" and 5\" model have an IPS panel so the viewing angles are great. The 7\" version uses a TN panel with acceptable viewing angles but a larger display area. Models ~ Model 4.3\" IPS Capacitive 5.0\" IPS Capacitive 7.0\" TN Capacitive SKU ESP32-8048S043C ESP32-8048S050C ESP32-8048S070C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" IPS 5.0\" IPS 7.0\" TN Resolution 800x480 800x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: SUNON ESP32-2432S028 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/esp32-2432s028-display-box SUNON ESP32-3248S035 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-3248s035-matsekberg SUNON ESP32-8048S050 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-8048s050-display-box Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-8048S0xx"},{"location":"hardware/sunton/esp32-8048s0xx/#sunton-esp32-8048s0xx","text":"These are great \"all-in-one\" device that have integrated ESP32-S3 chips with 16 MB of flash and 8MB PSram. There are 3 sizes available with an 800x480 resolution ranging from 4.3\", 5\" to 7\" display and built in capacitive touch panel. The 4.3\" and 5\" model have an IPS panel so the viewing angles are great. The 7\" version uses a TN panel with acceptable viewing angles but a larger display area.","title":"Sunton ESP32-8048S0xx "},{"location":"hardware/sunton/esp32-8048s0xx/#models","text":"Model 4.3\" IPS Capacitive 5.0\" IPS Capacitive 7.0\" TN Capacitive SKU ESP32-8048S043C ESP32-8048S050C ESP32-8048S070C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" IPS 5.0\" IPS 7.0\" TN Resolution 800x480 800x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-8048s0xx/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-8048s0xx/#cases","text":"If you have a 3D printer, cases are becoming available: SUNON ESP32-2432S028 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/esp32-2432s028-display-box SUNON ESP32-3248S035 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-3248s035-matsekberg SUNON ESP32-8048S050 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-8048s050-display-box Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-8048s0xx/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-8048s0xx/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-8048s0xx/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/waveshare/waveshare-rpi-lcd/","text":"Waveshare RPi LCD (Rev C) ~ Models ~ The Waveshare RPi LCD (Rev C) display comes in 3.5\" and 4.0\" sizes: Model 3.5inch (Rev C) 4.0inch (Rev C) SKU 15811 16099 Resolution 480x320 480x320 TFT controller ILI9486 ST7796 Interface SPI SPI Touchscreen Resistive Resistive Touch controller XPT2046 XPT2046 Screen dimming yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy AliExpress Waveshare.com Backlight Control ~ By default the display is always on. To enable backlight dimming, you can connect the pads marked by the red arrow using a 0R resistor or a direct solder connection: Attention (*) The WaveShare 3.5\" RPi LCD Revision C (SKU 15811) and WaveShare 4.0\" RPi LCD Revision C (SKU 16099) have the solder jumper on the back to enable PWM backlight dimming. Most revisions of this board do not have this feature! Development Boards ~ ESP32 One ~ The Waveshare ESP32 One development board has the same form factor as the Raspberry Pi Zero, inluding a 40 pin GPIO header. The ESP32 One is plug-and-play compatible with the Waveshare RPi LCD (Rev C) 3.5\" and 4\". This board has 4 MB flash and 8 MB PSRAM. Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Schematics Gallery ~ Pin Configuration ~ LCD Pin Function ESP32 Pin Config Name Display Pin 1 Module Power 3.3V 3.3V 3.3V 2 Module Power 5v 5V 5V 3 Not connected N/C 4 5V 5-10 Not connected N/C 11 Touch Interrupt N/C TOUCH_IRQ TP_IRQ 12 (*) LED Backlight PWM GPIO26 TFT_BCKL LCD_LED 13 Not connected N/C 14 Module Ground GND GND 15-16 Not connected N/C 17 Module Power 3.3V 3.3V 18 Data Command control pin GPIO4 TFT_DC LCD_RS 19 SPI Master Out Slave In GPIO13 TFT_MOSI LCD/SI/TP_SI 20 Not connected N/C 21 Touch Panel Slave Out GPIO12 TFT_MISO TP_SO 22 LCD Reset pin GPIO32 TFT_RST RST 23 SPI Clock GPIO14 TFT_SCLK LCD_SCK/TP_SCK 24 Chip select control pin GPIO5 TFT_CS LCD_CS 25 Module Ground GND GND 26 Touch Chip Select GPIO22 TOUCH_CS TP_CS SPI MISO, MOSI and SCLK are shared between the touch controller and the LCD controller. You can also use jumper wires to connect the display to any ESP32 development board: 6 GPIOs are required to drive the SPI display. One additional GPIO is needed for the XPT2046 touch sensor and one extra GPIO for backlight dimming. Including the VCC and GND pins, a total of 13 connections need to be made to the MCU. LCD Configuration ~ The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 raspberrypi = -D RPI_DISPLAY_TYPE = 1 -D ST7796_DRIVER = 1 -D TFT_WIDTH = 320 -D TFT_HEIGHT = 480 -D TFT_ROTATION = 0 ; 0=0, 1=90, 2=180 or 3=270 degree -D SPI_FREQUENCY = 80000000 -D SPI_TOUCH_FREQUENCY = 2500000 -D USER_SETUP_LOADED = 1 -D TOUCH_DRIVER = 2046 ; XPT2046 Resistive touch panel driver -D SUPPORT_TRANSACTIONS HASP build_flags ~ Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 build_flags = ${env.build_flags} ${esp32.build_flags} -DBOARD_HAS_PSRAM ; uses 78kB ; -- TFT_eSPI build options ------------------------ ${lcd.raspberrypi} ${esp32.hspi} ; Use HSPI hardware SPI bus -D TFT_CS = 5 -D TFT_DC = 4 -D TFT_RST = 32 -D TFT_BCKL = 26 ; Default, configurable via web UI -D TOUCH_CS = 22 -D SD_CS = 15 ; Currently not supported","title":"Waveshare RPi LCD"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#waveshare-rpi-lcd-rev-c","text":"","title":"Waveshare RPi LCD (Rev C)"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#models","text":"The Waveshare RPi LCD (Rev C) display comes in 3.5\" and 4.0\" sizes: Model 3.5inch (Rev C) 4.0inch (Rev C) SKU 15811 16099 Resolution 480x320 480x320 TFT controller ILI9486 ST7796 Interface SPI SPI Touchscreen Resistive Resistive Touch controller XPT2046 XPT2046 Screen dimming yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy AliExpress Waveshare.com","title":"Models"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#backlight-control","text":"By default the display is always on. To enable backlight dimming, you can connect the pads marked by the red arrow using a 0R resistor or a direct solder connection: Attention (*) The WaveShare 3.5\" RPi LCD Revision C (SKU 15811) and WaveShare 4.0\" RPi LCD Revision C (SKU 16099) have the solder jumper on the back to enable PWM backlight dimming. Most revisions of this board do not have this feature!","title":"Backlight Control"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#development-boards","text":"","title":"Development Boards"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#esp32-one","text":"The Waveshare ESP32 One development board has the same form factor as the Raspberry Pi Zero, inluding a 40 pin GPIO header. The ESP32 One is plug-and-play compatible with the Waveshare RPi LCD (Rev C) 3.5\" and 4\". This board has 4 MB flash and 8 MB PSRAM. Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Schematics","title":"ESP32 One"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#gallery","text":"","title":"Gallery"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#pin-configuration","text":"LCD Pin Function ESP32 Pin Config Name Display Pin 1 Module Power 3.3V 3.3V 3.3V 2 Module Power 5v 5V 5V 3 Not connected N/C 4 5V 5-10 Not connected N/C 11 Touch Interrupt N/C TOUCH_IRQ TP_IRQ 12 (*) LED Backlight PWM GPIO26 TFT_BCKL LCD_LED 13 Not connected N/C 14 Module Ground GND GND 15-16 Not connected N/C 17 Module Power 3.3V 3.3V 18 Data Command control pin GPIO4 TFT_DC LCD_RS 19 SPI Master Out Slave In GPIO13 TFT_MOSI LCD/SI/TP_SI 20 Not connected N/C 21 Touch Panel Slave Out GPIO12 TFT_MISO TP_SO 22 LCD Reset pin GPIO32 TFT_RST RST 23 SPI Clock GPIO14 TFT_SCLK LCD_SCK/TP_SCK 24 Chip select control pin GPIO5 TFT_CS LCD_CS 25 Module Ground GND GND 26 Touch Chip Select GPIO22 TOUCH_CS TP_CS SPI MISO, MOSI and SCLK are shared between the touch controller and the LCD controller. You can also use jumper wires to connect the display to any ESP32 development board: 6 GPIOs are required to drive the SPI display. One additional GPIO is needed for the XPT2046 touch sensor and one extra GPIO for backlight dimming. Including the VCC and GND pins, a total of 13 connections need to be made to the MCU.","title":"Pin Configuration"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#lcd-configuration","text":"The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 raspberrypi = -D RPI_DISPLAY_TYPE = 1 -D ST7796_DRIVER = 1 -D TFT_WIDTH = 320 -D TFT_HEIGHT = 480 -D TFT_ROTATION = 0 ; 0=0, 1=90, 2=180 or 3=270 degree -D SPI_FREQUENCY = 80000000 -D SPI_TOUCH_FREQUENCY = 2500000 -D USER_SETUP_LOADED = 1 -D TOUCH_DRIVER = 2046 ; XPT2046 Resistive touch panel driver -D SUPPORT_TRANSACTIONS","title":"LCD Configuration"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#hasp-build_flags","text":"Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 build_flags = ${env.build_flags} ${esp32.build_flags} -DBOARD_HAS_PSRAM ; uses 78kB ; -- TFT_eSPI build options ------------------------ ${lcd.raspberrypi} ${esp32.hspi} ; Use HSPI hardware SPI bus -D TFT_CS = 5 -D TFT_DC = 4 -D TFT_RST = 32 -D TFT_BCKL = 26 ; Default, configurable via web UI -D TOUCH_CS = 22 -D SD_CS = 15 ; Currently not supported","title":"HASP build_flags"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/","text":"Waveshare TFT Touch Shield ~ more images... Waveshare has a line of TFT Touch Shields for Arduino which are also plug-and-play compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 board. Unlike many other common Arduino UNO shields the Waveshare displays have an SPI interface with resistive touch controller and backlight control . Be sure to check if the LCD_BL , LCD_CS and TP_CS pins are present. If these pins are missing, the screen won't work with the pre-compiled builds. Models ~ There are 3 models of this TFT shield: Model 2.8\" Rev 2.1 3.5inch 4.0inch SKU 10684 13506 13587 Resolution 320x240 480x320 480x320 TFT controller ST7789 (Rev 2.1 only) ILI9486 ILI9486 Interface SPI SPI SPI Touchscreen Resistive Resistive Resistive Touch controller XPT2046 XPT2046 XPT2046 SD Card yes yes yes Screen dimming yes yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Backlight Control ~ All three models come with an LCD_BL pin that allows for backlight control. It is connected to GPIO13 on the D1 R32 development board. Documentation ~ Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\" Configuration ~ Note By default the DIP switches on the display are set in the ICSP position instead of the SPI position. If your board does not include an ICSP header, you need to switch the display over to use the SPI pins. To use the MISO , MOSI and SCLK SPI pins you first need to peel of the orange tape that sticks on top of the dip switches. Then move all 3 DIP switches to the ON position with a tiny screwdriver. The 2.8\" model has 3 solder jumpers SB1 , SB2 and SB3 that need to be bridged instead! Development Boards ~ D1 R32 ~ The Waveshare TFT Touch Shields are compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 development board. It contains an ESP32-WROOM module with 4MB flash. Warning The D1 R32 ESP32 board may suffer from brown-out reboots if not powered adequately. Arducam IoTai ESP32 ~ Onboard 4MB PSRAM, 4MByte Flash To be tested Adafruit Metro ESP32-S2 ~ With 4 MByte of Flash and 2 MByte of PSRAM Note This board has not been tested yet!","title":"Waveshare TFT Touch Shield"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#waveshare-tft-touch-shield","text":"more images... Waveshare has a line of TFT Touch Shields for Arduino which are also plug-and-play compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 board. Unlike many other common Arduino UNO shields the Waveshare displays have an SPI interface with resistive touch controller and backlight control . Be sure to check if the LCD_BL , LCD_CS and TP_CS pins are present. If these pins are missing, the screen won't work with the pre-compiled builds.","title":"Waveshare TFT Touch Shield"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#models","text":"There are 3 models of this TFT shield: Model 2.8\" Rev 2.1 3.5inch 4.0inch SKU 10684 13506 13587 Resolution 320x240 480x320 480x320 TFT controller ST7789 (Rev 2.1 only) ILI9486 ILI9486 Interface SPI SPI SPI Touchscreen Resistive Resistive Resistive Touch controller XPT2046 XPT2046 XPT2046 SD Card yes yes yes Screen dimming yes yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com","title":"Models"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#backlight-control","text":"All three models come with an LCD_BL pin that allows for backlight control. It is connected to GPIO13 on the D1 R32 development board.","title":"Backlight Control"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#documentation","text":"Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"Documentation"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#configuration","text":"Note By default the DIP switches on the display are set in the ICSP position instead of the SPI position. If your board does not include an ICSP header, you need to switch the display over to use the SPI pins. To use the MISO , MOSI and SCLK SPI pins you first need to peel of the orange tape that sticks on top of the dip switches. Then move all 3 DIP switches to the ON position with a tiny screwdriver. The 2.8\" model has 3 solder jumpers SB1 , SB2 and SB3 that need to be bridged instead!","title":"Configuration"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#development-boards","text":"","title":"Development Boards"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#d1-r32","text":"The Waveshare TFT Touch Shields are compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 development board. It contains an ESP32-WROOM module with 4MB flash. Warning The D1 R32 ESP32 board may suffer from brown-out reboots if not powered adequately.","title":"D1 R32"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#arducam-iotai-esp32","text":"Onboard 4MB PSRAM, 4MByte Flash To be tested","title":"Arducam IoTai ESP32"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#adafruit-metro-esp32-s2","text":"With 4 MByte of Flash and 2 MByte of PSRAM Note This board has not been tested yet!","title":"Adafruit Metro ESP32-S2"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/","text":"WT-86-32-3ZW1 ~ Warning This product with ESP32-S2 is not sold anymore and will soon become obsolete. Please get the ESP32-S3 model instead. The Wireless-Tag WT-86-32-3ZW1 is a 86x86mm touchscreen with 4 relays that can be mounted in a standard 86x86mm wall-box. It is currently only available from Alibaba for around US $40 excluding shipping. Features ~ Pros Cons 16 MB flash Display ghosting 8 MB PSram 320 kB SRAM (ESP32-S2) Price Can't fit in EU workbox Capacitive Touchscreen Issues ~ One issue we've noticed is temporary ghosting on the display reported by multiple users. When showing a UI with white, cyan or bright colors on a dark background, a dim ghost image of these bright colors can linger on the screen for some time after changing pages. If you notice this issue on your device, please report back in this Github discussion thread . Dimensions ~ Note The size of the PSU unit does not fit a regular EU wall-box and mounting it in a US wall-box needs testing. Flashing ~ All pins are conveniently broken out on the 2mm pitch female header. Make sure the USB port can deliver enough power. It is best to use a powered USB hub since most PC ports can not power the whole device. esptool.py --port COM6 erase_flash esptool.py --port COM6 write_flash 0x0 wt-86-32-3zw1_full_16MB_v0.6.3-dev_88a478d.bin --verify Gallery ~","title":"WT-86-32-3ZW1"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#wt-86-32-3zw1","text":"Warning This product with ESP32-S2 is not sold anymore and will soon become obsolete. Please get the ESP32-S3 model instead. The Wireless-Tag WT-86-32-3ZW1 is a 86x86mm touchscreen with 4 relays that can be mounted in a standard 86x86mm wall-box. It is currently only available from Alibaba for around US $40 excluding shipping.","title":"WT-86-32-3ZW1"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#features","text":"Pros Cons 16 MB flash Display ghosting 8 MB PSram 320 kB SRAM (ESP32-S2) Price Can't fit in EU workbox Capacitive Touchscreen","title":"Features"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#issues","text":"One issue we've noticed is temporary ghosting on the display reported by multiple users. When showing a UI with white, cyan or bright colors on a dark background, a dim ghost image of these bright colors can linger on the screen for some time after changing pages. If you notice this issue on your device, please report back in this Github discussion thread .","title":"Issues"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#dimensions","text":"Note The size of the PSU unit does not fit a regular EU wall-box and mounting it in a US wall-box needs testing.","title":"Dimensions"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#flashing","text":"All pins are conveniently broken out on the 2mm pitch female header. Make sure the USB port can deliver enough power. It is best to use a powered USB hub since most PC ports can not power the whole device. esptool.py --port COM6 erase_flash esptool.py --port COM6 write_flash 0x0 wt-86-32-3zw1_full_16MB_v0.6.3-dev_88a478d.bin --verify","title":"Flashing"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#gallery","text":"","title":"Gallery"},{"location":"hardware/wireless-tag/wt32-sc01-plus/","text":"WT32-SC01 Plus ~ Features ~ The SC01 Plus uses an ESP32-S3-WROVER module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there are some ports with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 8-bit Display Flashing the initial bootloader 2 MB PSram Serial Flashing tool recommended Capacitive Touchscreen JST 1.25mm Expansion headers IPS Viewing angles Sleek design The development board is powered via USB Type-C. Video ~ Cases ~ A 3D-printable case can be found on: https://www.printables.com/model/381026-wt32-sc01-plus-desk-case#preview","title":"WT32-SC01 Plus"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#wt32-sc01-plus","text":"","title":"WT32-SC01 Plus "},{"location":"hardware/wireless-tag/wt32-sc01-plus/#features","text":"The SC01 Plus uses an ESP32-S3-WROVER module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there are some ports with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 8-bit Display Flashing the initial bootloader 2 MB PSram Serial Flashing tool recommended Capacitive Touchscreen JST 1.25mm Expansion headers IPS Viewing angles Sleek design The development board is powered via USB Type-C.","title":"Features"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#video","text":"","title":"Video"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#cases","text":"A 3D-printable case can be found on: https://www.printables.com/model/381026-wt32-sc01-plus-desk-case#preview","title":"Cases"},{"location":"hardware/wireless-tag/wt32-sc01/","text":"WT32-SC01 ~ Features ~ The WT32-SC01 incorporates an ESP32-WROVER-B module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 Display 4 MB flash on basic model 8 MB PSram Viewing angle in landscape mode Capacitive Touchscreen Mounting holes placement The development board is powered via USB Type-C. The basic version comes with only 4MB SPI Flash but there is a better WT32-SC01(16MB) SKU with a larger flash chip. Both models have 8MB of PSRAM. With 4MB flash available from: LCSC Seeed studio With 16MB flash available from: Alibaba Tip Please consider getting the model with 16MB flash size as it is more suitable for the large screen. Note The expansion connector has a 2.0mm pitch female header instead of the more common 2.54mm pitch. Datasheet Gallery ~ 3D Printed Case ~ Wt32-sc01 Case by mbenten on Sketchfab","title":"WT32-SC01"},{"location":"hardware/wireless-tag/wt32-sc01/#wt32-sc01","text":"","title":"WT32-SC01"},{"location":"hardware/wireless-tag/wt32-sc01/#features","text":"The WT32-SC01 incorporates an ESP32-WROVER-B module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 Display 4 MB flash on basic model 8 MB PSram Viewing angle in landscape mode Capacitive Touchscreen Mounting holes placement The development board is powered via USB Type-C. The basic version comes with only 4MB SPI Flash but there is a better WT32-SC01(16MB) SKU with a larger flash chip. Both models have 8MB of PSRAM. With 4MB flash available from: LCSC Seeed studio With 16MB flash available from: Alibaba Tip Please consider getting the model with 16MB flash size as it is more suitable for the large screen. Note The expansion connector has a 2.0mm pitch female header instead of the more common 2.54mm pitch. Datasheet","title":"Features"},{"location":"hardware/wireless-tag/wt32-sc01/#gallery","text":"","title":"Gallery"},{"location":"hardware/wireless-tag/wt32-sc01/#3d-printed-case","text":"Wt32-sc01 Case by mbenten on Sketchfab","title":"3D Printed Case"},{"location":"hardware/yeacreate/nscreen32/","text":"YeaCreate Nscreen32 ~ Features ~ The Nscreen32 uses an ESP32-WROVER-IE module with a large 4-inch capacitive touch display. The display is connected via an 8-bit parallel bus resulting in a fast performance. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with 6 GPIOs (4 input only, RX & TX) so you add inputs if needed. The development board can be powered via micro USB or the 5V-in JST connector. Pros Cons 8-bit parallel display No backlight control 16 MB flash + 8 MB PSram Bright white power LED Capacitive Touchscreen Viewing angles External antenna YeaCreate Store Backlight Control ~ Unfortunately, there is no support for backlight control . The display is always-on. With a small hack it is possible to control the backlight using a PNP transistor connected to GPIO0 , R8 and 3.3V . Documentation ~ Some example projects and the schematics for the Nscreen32 can be found on the Yeacreate Github repository. Github Repo Schematics Product Video ~ Nscreen32 is the first device to receive the LVGL Certified Board label: Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Yeacreate"},{"location":"hardware/yeacreate/nscreen32/#yeacreate-nscreen32","text":"","title":"YeaCreate Nscreen32"},{"location":"hardware/yeacreate/nscreen32/#features","text":"The Nscreen32 uses an ESP32-WROVER-IE module with a large 4-inch capacitive touch display. The display is connected via an 8-bit parallel bus resulting in a fast performance. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with 6 GPIOs (4 input only, RX & TX) so you add inputs if needed. The development board can be powered via micro USB or the 5V-in JST connector. Pros Cons 8-bit parallel display No backlight control 16 MB flash + 8 MB PSram Bright white power LED Capacitive Touchscreen Viewing angles External antenna YeaCreate Store","title":"Features"},{"location":"hardware/yeacreate/nscreen32/#backlight-control","text":"Unfortunately, there is no support for backlight control . The display is always-on. With a small hack it is possible to control the backlight using a PNP transistor connected to GPIO0 , R8 and 3.3V .","title":"Backlight Control"},{"location":"hardware/yeacreate/nscreen32/#documentation","text":"Some example projects and the schematics for the Nscreen32 can be found on the Yeacreate Github repository. Github Repo Schematics","title":"Documentation"},{"location":"hardware/yeacreate/nscreen32/#product-video","text":"Nscreen32 is the first device to receive the LVGL Certified Board label:","title":"Product Video"},{"location":"hardware/yeacreate/nscreen32/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"integrations/home-assistant/howto/","text":"Home Assistant ~ The openHASP Custom Component simplifies synchronization of objects on one or more openHASP plates with Home Assistant entities. You can map any service supported by any entity in Home Assistant to any object event in openHASP. Moreover, you can set any property of any object in openHASP to any value from Home Assistant. This powerful concept gives you full freedom to create a completely customized, hardware-based control user interface for your home automation. We call plate any device running openHASP in your system. Note Before going forward make sure you have installed the MQTT add-on in Home Assistant and the option Enable Discovery is indeed enabled in the MQTT integration service. A working MQTT add-on with discovery enabled is a prerequisite for using the openHASP custom component. Installation ~ You have the option to install the custom component using HACS or via manual download: Using HACS Manual Install Install using HACS in one-click. This is the preferred and recommended method, as HACS provides a very effective way to keep the component updated and/or choose between various versions. Goto Home Assistant > HACS > Integrations . Click the Explore & Add Repositories button. Search for openHASP and click on the openHasp logo. Click Install this repository in HACS . Note: To install the current unstable development version select the Main . Click Install Reboot Home-Assistant Alternatively, you can also install it manually: Download ZIP Using the tool of choice open the directory (folder) for your HA configuration (where you find configuration.yaml ). If you do not have a custom_components directory there, you need to create it. In the custom_components directory create a new folder called openhasp . Download all the files from the custom_components/openhasp/ directory in this repository. Place the files you downloaded in the new directory you created. Edit your configuration.yaml file add an entry similar to the example below. Restart Home Assistant Note The download {target= blank} link points to the actual _development code in the master branch. Warning You have to use component version consistently with the firmware version on your plates. For example, if your plates are at firmware version 0.7.x , you also need to use component version 0.7.y to ensure interoperability. Only the first two digits matter, i.e. 0.7 , the last one can be different. Home Assistant will show a warning if it finds a version mismatch. Note that you can only have one version of the component installed at a time so a mix of plate firmware versions is not supported. Configuration ~ First prepare your plates to be integrated with Home Assistant (follow steps in order): Connect your plates to the network . Static DHCP or fixed IP is not needed as communication only happens through MQTT. Set the GPIO configuration corresponding to your hardware (important for them to be detected as entities), save and reboot. Restart Home Assistant. Set the MQTT server settings and make sure each plate has a unique node name, save and reboot. The component will automatically discover the plates and you will see them appearing in Lovelace UI's Configuration > Devices & Services > openHASP . When Home Assistant detects your plate, you will have to give it a name. In the examples below both name and node name is plate35 . You will be presented with options to set the backlight brightness level when the plate is idle and optionally you can set a path to a centrally located pages.jsonl file containing design for this plate - the component can send the contents of the file when the plate connects. From v0.6.3 of the component this file can also be a file with a .json extension. See the JSON Files section below. Note If you opt to store the pages.jsonl file on Home Assistant server, it will only be loaded on start of Home Assistant and reloaded on plate availability (becoming online). Optionally you should also check how to handle the offline state of the plate. Currently you will get a warning that you need to add manual configuration for the objects in your configuration.yaml , that's no problem, read ahead. Example ~ To add an openHASP plate to your installation with a sample configuration, upload a pages.jsonl file with the following content to your plate first: 1 2 3 4 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"openHASP\" , \"value_font\" : 22 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"mode\" : \"break\" , \"align\" : 1 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 10 , \"y\" : 140 , \"w\" : 170 , \"h\" : 30 , \"options\" : \"Apples\\nBananas\\nOranges\\nMelon\" } { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" } Assuming your plate's configured MQTT node name is plate35 , add the following to your configuration.yaml file (Home Assistant will deliberately ask for it when finished autodetection procedure): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 openhasp : plate35 : objects : - obj : \"p0b1\" # temperature label on all pages properties : \"text\" : '{{ states(\"sensor.my_room_temperature\") }}\u00b0C' - obj : \"p1b2\" # light-switch toggle button properties : \"val\" : '{{ 1 if states(\"light.my_room\") == \"on\" else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_room\", \"on\") else \"\\uE335\" | e }}' event : \"up\" : - service : homeassistant.toggle entity_id : \"light.my_room\" - obj : \"p1b3\" # dropdown event : \"changed\" : - service : persistent_notification.create data : message : I like {{ text }} Note The Home Assistant Custom Component is not limited to setting val and text properties on UI objects! There is nothing stopping you from using the full suite of template functions like state_attr in your templates to drive more sophisticated behaviors. See the Example Automations for more. Variable definitions ~ openhasp: (Required) The platform identifier. Required once in the configuration. plate35: (Required) Your plate identifier slug. For each plate in your system, such an entry is required, has to be unique. It is generated automatically from the plate name you gave during discovery, which by default equals to the HASP Node Name set in the plate's configuration . objects: (Optional) Definition of the objects reacting to changes in Home Assistant, or generating events for Home Assistant. obj: (string) (Required) The object identifier which we want to integrate with Home Assistant. Its name has the form pXbY where X represents the page where the object is located, and Y represents the id of the object on that page. properties: (Optional) List containing the properties of the object which we want to modify based on changes occurring in Home Assistant. In the example above text property gets updated whenever sensor.my_room_temperature changes. event: (Optional) List containing the events generated by the object when touched on the screen. These are object-specific and can be observed accurately with an MQTT client. Each event defines a list of services which will be processed in order (like actions list in an automation). In the example above, when object p1b2 (which is a toggle button) generates the on event, light.my_room will be turned on by the service call light.turn_on as specified in the event config. And similarly when off event comes through MQTT, the light will be turned off by the corresponding service call. Note Any variable coming from the MQTT message can be used between curly brackets and passed to the service call. In the example above when object p1b3 (which is a dropdown selector) generates the changed event, a persistent notification will appear in Home Assistant's Lovelace interface containing the selected text from the object, which was passed over from the MQTT message. See object events for more types of generated events. Reloading the configuration ~ After you make changes to the configuration of the plate you can apply them by either restarting Home Assistant or by reloading the integration from Lovelace user interface with option found in Configuration > Devices & Services > openHASP > (your plate >) 3dots menu > Reload . Note that this has to be done individually for each configured plate. You can achieve the same by with a service too: 1 2 3 service : homeassistant.reload_config_entry data : entry_id : 95f7d6fe3fa5f4e242797e9ae4a5dd1d With the entry_id found in .storage/core.config_entries file from your main Home Assistant configuration directory (do NOT edit this file!). Configuration tips ~ Multiple plates ~ If you have multiple plates you can add them all using different plate identifiers. Their configured topics have to be unique too: 1 2 3 4 5 6 7 8 9 10 openhasp : plate_my_room_1 : objects : # ... plate_my_room_2 : objects : # ... plate_my_room_3 : objects : # ... Split configuration ~ You can use Home Assistant's split configuration to help better organizing your config files. Instead of keeping the configuration of all openHASP plates in Home Assistant's main config file, you can keep openHASP config separately, by adding only this to configuration.yaml : openhasp: !include openhasp.yaml After this, you can move your openHASP configuration starting with plate_my_room: level to your separate openhasp.yaml file and restart Home Assistant. Moreover, if you have multiple plates, you can keep each one in a separate config file, to achieve this, make it like: openhasp: !include_dir_merge_named openhasp_configs/ Create a directory openhasp_configs right near configuration.yaml , and put in it all your plates configuration (only with plate_my_room: level) in separate yaml files and restart Home Assistant. Services ~ This component implements some specific services to make interactions with the plate even more comfortable. openhasp.wakeup Wakes up the display when an external event has occurred, like a presence or a PIR motion sensor. openhasp.next_page Changes plate to the next page. openhasp.prev_page Changes plate to the previous page. openhasp.change_page Changes plate directly to the specified page number. openhasp.clear_page Clears the contents of the specified page number. If page number not specified, clears all the pages. openhasp.load_pages Loads new design from pages.jsonl file from full path on Home Assistant server. The file must be located in an authorized location defined by allowlist_external_dirs (in case of hassio /config/ is the directory where Home Assistant's configuration.yaml resides, so in case of a subdirectory called openhasp the full path would be e.g. /config/openhasp/pages.jsonl , and you need to add /config/openhasp/ to your allowlist_external_dirs ). Note The contents of the file are loaded line by line thus \"page\":X has to be defined for each object. Unless you clear the page first, the objects will be updated. For example, to allow read-access to the folder, add these lines to your configuration.yaml : 1 2 3 homeassistant : allowlist_external_dirs : - \"/config/openhasp\" openhasp.command Wraps up any command so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! openhasp.config Wraps up any raw submodule config so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! Check out the example configurations and automations to learn how to use these services within Home Assistant. JSON Files ~ From v0.6.3 pages file supplied in the plate config within home assistant can be a .json , files with this extension will be parsed differently and expect a JSON array containing objects or strings. Objects must be valid JSONL lines and strings can be used for comments. As this file is valid JSON whitespace will be ignored when parsing and removed before sending the JSONL data to the plate. If you are storing your plate config along with your HA config, this allows you to have more readable config which will be formatted in your editor of choice. Example: 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 [ { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : false , \"text\" : \"Normal Button\" , \"mode\" : \"break\" , \"align\" : \"center\" }, \"Comment string will be removed when parsing\" , { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"#FFD700 Toggle# Button\" , \"mode\" : \"break\" , \"align\" : \"center\" } ] Debugging ~ Add these lines to your main configuration.yaml configuration and restart Home Assistant: 1 2 3 4 logger : default : warning logs : custom_components.openhasp : debug Look for the debug messages in the home-assistant.log file.","title":"How-To"},{"location":"integrations/home-assistant/howto/#home-assistant","text":"The openHASP Custom Component simplifies synchronization of objects on one or more openHASP plates with Home Assistant entities. You can map any service supported by any entity in Home Assistant to any object event in openHASP. Moreover, you can set any property of any object in openHASP to any value from Home Assistant. This powerful concept gives you full freedom to create a completely customized, hardware-based control user interface for your home automation. We call plate any device running openHASP in your system. Note Before going forward make sure you have installed the MQTT add-on in Home Assistant and the option Enable Discovery is indeed enabled in the MQTT integration service. A working MQTT add-on with discovery enabled is a prerequisite for using the openHASP custom component.","title":"Home Assistant"},{"location":"integrations/home-assistant/howto/#installation","text":"You have the option to install the custom component using HACS or via manual download: Using HACS Manual Install Install using HACS in one-click. This is the preferred and recommended method, as HACS provides a very effective way to keep the component updated and/or choose between various versions. Goto Home Assistant > HACS > Integrations . Click the Explore & Add Repositories button. Search for openHASP and click on the openHasp logo. Click Install this repository in HACS . Note: To install the current unstable development version select the Main . Click Install Reboot Home-Assistant Alternatively, you can also install it manually: Download ZIP Using the tool of choice open the directory (folder) for your HA configuration (where you find configuration.yaml ). If you do not have a custom_components directory there, you need to create it. In the custom_components directory create a new folder called openhasp . Download all the files from the custom_components/openhasp/ directory in this repository. Place the files you downloaded in the new directory you created. Edit your configuration.yaml file add an entry similar to the example below. Restart Home Assistant Note The download {target= blank} link points to the actual _development code in the master branch. Warning You have to use component version consistently with the firmware version on your plates. For example, if your plates are at firmware version 0.7.x , you also need to use component version 0.7.y to ensure interoperability. Only the first two digits matter, i.e. 0.7 , the last one can be different. Home Assistant will show a warning if it finds a version mismatch. Note that you can only have one version of the component installed at a time so a mix of plate firmware versions is not supported.","title":"Installation"},{"location":"integrations/home-assistant/howto/#configuration","text":"First prepare your plates to be integrated with Home Assistant (follow steps in order): Connect your plates to the network . Static DHCP or fixed IP is not needed as communication only happens through MQTT. Set the GPIO configuration corresponding to your hardware (important for them to be detected as entities), save and reboot. Restart Home Assistant. Set the MQTT server settings and make sure each plate has a unique node name, save and reboot. The component will automatically discover the plates and you will see them appearing in Lovelace UI's Configuration > Devices & Services > openHASP . When Home Assistant detects your plate, you will have to give it a name. In the examples below both name and node name is plate35 . You will be presented with options to set the backlight brightness level when the plate is idle and optionally you can set a path to a centrally located pages.jsonl file containing design for this plate - the component can send the contents of the file when the plate connects. From v0.6.3 of the component this file can also be a file with a .json extension. See the JSON Files section below. Note If you opt to store the pages.jsonl file on Home Assistant server, it will only be loaded on start of Home Assistant and reloaded on plate availability (becoming online). Optionally you should also check how to handle the offline state of the plate. Currently you will get a warning that you need to add manual configuration for the objects in your configuration.yaml , that's no problem, read ahead.","title":"Configuration"},{"location":"integrations/home-assistant/howto/#example","text":"To add an openHASP plate to your installation with a sample configuration, upload a pages.jsonl file with the following content to your plate first: 1 2 3 4 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"openHASP\" , \"value_font\" : 22 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"mode\" : \"break\" , \"align\" : 1 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 10 , \"y\" : 140 , \"w\" : 170 , \"h\" : 30 , \"options\" : \"Apples\\nBananas\\nOranges\\nMelon\" } { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" } Assuming your plate's configured MQTT node name is plate35 , add the following to your configuration.yaml file (Home Assistant will deliberately ask for it when finished autodetection procedure): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 openhasp : plate35 : objects : - obj : \"p0b1\" # temperature label on all pages properties : \"text\" : '{{ states(\"sensor.my_room_temperature\") }}\u00b0C' - obj : \"p1b2\" # light-switch toggle button properties : \"val\" : '{{ 1 if states(\"light.my_room\") == \"on\" else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_room\", \"on\") else \"\\uE335\" | e }}' event : \"up\" : - service : homeassistant.toggle entity_id : \"light.my_room\" - obj : \"p1b3\" # dropdown event : \"changed\" : - service : persistent_notification.create data : message : I like {{ text }} Note The Home Assistant Custom Component is not limited to setting val and text properties on UI objects! There is nothing stopping you from using the full suite of template functions like state_attr in your templates to drive more sophisticated behaviors. See the Example Automations for more.","title":"Example"},{"location":"integrations/home-assistant/howto/#variable-definitions","text":"openhasp: (Required) The platform identifier. Required once in the configuration. plate35: (Required) Your plate identifier slug. For each plate in your system, such an entry is required, has to be unique. It is generated automatically from the plate name you gave during discovery, which by default equals to the HASP Node Name set in the plate's configuration . objects: (Optional) Definition of the objects reacting to changes in Home Assistant, or generating events for Home Assistant. obj: (string) (Required) The object identifier which we want to integrate with Home Assistant. Its name has the form pXbY where X represents the page where the object is located, and Y represents the id of the object on that page. properties: (Optional) List containing the properties of the object which we want to modify based on changes occurring in Home Assistant. In the example above text property gets updated whenever sensor.my_room_temperature changes. event: (Optional) List containing the events generated by the object when touched on the screen. These are object-specific and can be observed accurately with an MQTT client. Each event defines a list of services which will be processed in order (like actions list in an automation). In the example above, when object p1b2 (which is a toggle button) generates the on event, light.my_room will be turned on by the service call light.turn_on as specified in the event config. And similarly when off event comes through MQTT, the light will be turned off by the corresponding service call. Note Any variable coming from the MQTT message can be used between curly brackets and passed to the service call. In the example above when object p1b3 (which is a dropdown selector) generates the changed event, a persistent notification will appear in Home Assistant's Lovelace interface containing the selected text from the object, which was passed over from the MQTT message. See object events for more types of generated events.","title":"Variable definitions"},{"location":"integrations/home-assistant/howto/#reloading-the-configuration","text":"After you make changes to the configuration of the plate you can apply them by either restarting Home Assistant or by reloading the integration from Lovelace user interface with option found in Configuration > Devices & Services > openHASP > (your plate >) 3dots menu > Reload . Note that this has to be done individually for each configured plate. You can achieve the same by with a service too: 1 2 3 service : homeassistant.reload_config_entry data : entry_id : 95f7d6fe3fa5f4e242797e9ae4a5dd1d With the entry_id found in .storage/core.config_entries file from your main Home Assistant configuration directory (do NOT edit this file!).","title":"Reloading the configuration"},{"location":"integrations/home-assistant/howto/#configuration-tips","text":"","title":"Configuration tips"},{"location":"integrations/home-assistant/howto/#services","text":"This component implements some specific services to make interactions with the plate even more comfortable. openhasp.wakeup Wakes up the display when an external event has occurred, like a presence or a PIR motion sensor. openhasp.next_page Changes plate to the next page. openhasp.prev_page Changes plate to the previous page. openhasp.change_page Changes plate directly to the specified page number. openhasp.clear_page Clears the contents of the specified page number. If page number not specified, clears all the pages. openhasp.load_pages Loads new design from pages.jsonl file from full path on Home Assistant server. The file must be located in an authorized location defined by allowlist_external_dirs (in case of hassio /config/ is the directory where Home Assistant's configuration.yaml resides, so in case of a subdirectory called openhasp the full path would be e.g. /config/openhasp/pages.jsonl , and you need to add /config/openhasp/ to your allowlist_external_dirs ). Note The contents of the file are loaded line by line thus \"page\":X has to be defined for each object. Unless you clear the page first, the objects will be updated. For example, to allow read-access to the folder, add these lines to your configuration.yaml : 1 2 3 homeassistant : allowlist_external_dirs : - \"/config/openhasp\" openhasp.command Wraps up any command so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! openhasp.config Wraps up any raw submodule config so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! Check out the example configurations and automations to learn how to use these services within Home Assistant.","title":"Services"},{"location":"integrations/home-assistant/howto/#json-files","text":"From v0.6.3 pages file supplied in the plate config within home assistant can be a .json , files with this extension will be parsed differently and expect a JSON array containing objects or strings. Objects must be valid JSONL lines and strings can be used for comments. As this file is valid JSON whitespace will be ignored when parsing and removed before sending the JSONL data to the plate. If you are storing your plate config along with your HA config, this allows you to have more readable config which will be formatted in your editor of choice. Example: 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 [ { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : false , \"text\" : \"Normal Button\" , \"mode\" : \"break\" , \"align\" : \"center\" }, \"Comment string will be removed when parsing\" , { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"#FFD700 Toggle# Button\" , \"mode\" : \"break\" , \"align\" : \"center\" } ]","title":"JSON Files"},{"location":"integrations/home-assistant/howto/#debugging","text":"Add these lines to your main configuration.yaml configuration and restart Home Assistant: 1 2 3 4 logger : default : warning logs : custom_components.openhasp : debug Look for the debug messages in the home-assistant.log file.","title":"Debugging"},{"location":"integrations/home-assistant/sampl_autom/","text":"Display of the current album cover of a media player ~ Combined with a media player entity which supports entity_picture attribute, you can automate display of that using the push_image service of the Custom Component. On the plate (named plate_livingroom in this example) you'd have two objects, first a rectangular object with rounded corners, secod an image object placed inside of it. It's hidden by default so you could place this on top of your existing media player controls, and have it pop up only when there's a cover present. To look nice together use the clip_corner property: { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"obj\" , \"x\" : 3 , \"y\" : 48 , \"w\" : 200 , \"h\" : 200 , \"radius\" : 6 , \"clip_corner\" : 1 , \"hidden\" : 1 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"img\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 200 , \"h\" : 200 , \"parentid\" : 15 , \"src\" : \"\" , \"auto_size\" : 1 } The automation below takes care of unhiding them when a cover appears on the sound_livingroom media player, updating the picture when it changes and hiding them again when the player drops the entity_picture attribute (it's stopped or the played media doesn't have a corresponding picture): 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 - id : openhasp-sound_livingroom-detect-mediaplayer-coverart alias : openhasp-sound_livingroom-detect-mediaplayer-coverart trigger : - platform : state entity_id : media_player.sound_livingroom condition : - condition : template value_template : > {{ trigger.from_state.attributes.entity_picture != trigger.to_state.attributes.entity_picture }} action : - choose : - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') != None }}\" sequence : - service : openhasp.push_image target : entity_id : openhasp.plate_livingroom data : image : http://ip.of.your.ha:8123{{ state_attr('media_player.sound_livingroom','entity_picture') }} obj : p6b16 width : 200 height : 200 - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '0' - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') == None }}\" sequence : - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '1' Backlight ON (dimmed) if there's any light in the room, OFF otherwise ~ The night mode activates when all the lights are off and shutters are down below 25% (assuming it's dark enough for the backlight to be disturbing in such situation), the day mode activates otherwise. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. This will act directly on the plate in a certain room, as it is triggered by entities located in that room. If you have multiple plates in various rooms, you can create separate automations for each. 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 - id : openhasp-plate_myroom-day alias : \"openHASP Night mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":0}' - id : openhasp-plate_myroom-night alias : \"openHASP Day mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ not ( state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" ) }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":60}' Note the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes). Backlight ON (dimmed) during the day, OFF during the night for all the plates ~ The night mode activates when sun goes down, and the day mode activates when the sun comes up. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. Assuming your plate's configured MQTT group name is plates , this will affect all the plates in your system at once: 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 - id : openhasp-night alias : \"openHASP Night mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation below : -1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":120}' - id : openhasp-day alias : \"openHASP Day mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation above : 1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":0}' Note here too the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes). Turn ON moodlight when backlight goes OFF (and back) ~ If your plate has moodlights, it is useful in dark situations, when you don't want to have the screen backlit on all the time as above, but have the mood light on instead. During the day mood light doesn't light. Put your light.plate_my_room_moodlight to a Lovelace card entity row and select a nice color for moodlight. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - id : openhasp-moodlight-on alias : \"openHASP Moodlight ON when Backlight OFF\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'on' to : 'off' action : - service : light.turn_on target : entity_id : light.plate_my_room_moodlight - id : openhasp-moodlight-off alias : \"openHASP Moodlight OFF when Backlight ON\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'off' to : 'on' action : - service : light.turn_off target : entity_id : light.plate_my_room_moodlight Return to home page after some idle time ~ Apart from the idle times controlling backlight levels, one may want to return to page 1 after a while. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - id : openhasp-back-to-page-1 alias : \"openHASP back to page 1\" trigger : - platform : template value_template : \"{{ state_attr('openhasp.plate_my_room','idle') != 'off' }}\" for : \"00:05:00\" condition : - condition : template value_template : \"{{ states('openhasp.plate_my_room') != '1' and states('openhasp.plate_my_room') != 'unavailable' }}\" action : - service : openhasp.change_page target : entity_id : openhasp.plate_my_room data : page : 1 Prevent burn-in of the LCD screen ~ You can use this to protect and prolonge the lifetime of the LCD screens, thus being more green and generating less hazardous waste. Wall mounted LCD screens' main problem is that they display the same picture 99.999% of the time. Even if somebody turns off backlight during the night or dark periods, the LCD screen keeps showing the same picture, seen by nobody. There are high chances that this will lead to screen picture burn-in after a few years of operation. Pixel training One way to reduce this is to \"train\" the pixels periodically with completely different other content. Assuming your group name is configured as plates in your screens running openHASP, here is a possible solution to extend their life (all at once). The cycle runs for 30 seconds each time, can be stopped by touching. The trigger runs this 6 times each night. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - id : openhasp_antiburn_start_at_night alias : openHASP anti-burn-in start at night initial_state : 'on' trigger : - platform : time at : '00:20:00' - platform : time at : '01:20:00' - platform : time at : '02:20:00' - platform : time at : '03:20:00' - platform : time at : '04:20:00' - platform : time at : '05:20:00' action : - service : mqtt.publish data : topic : hasp/plates/command/antiburn payload : '1' Clear pixels when backlight off Another way to reduce the chance of burn-in is to clear the contents of the screen while the backlight is turned off, as nobody sees the pixels anyway. Just add these actions to the first automation example which draw an overlay with a black base object on page 0 when display is off, and deletes it when comes back on: for automation openhasp-moodlight-on , add to actions: 1 2 3 4 - service : mqtt.publish data : topic : hasp/plates/command/jsonl payload : '{\"page\":0,\"id\":99,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"hidden\":0,\"bg_grad_dir\":0,\"bg_color\":\"black\"}' for automation openhasp-moodlight-off , add to actions: 1 2 3 4 5 6 7 8 - service : mqtt.publish data : topic : hasp/plates/command/p0b99.hidden payload : '1' - service : mqtt.publish data : topic : hasp/plates/command/p0b99.delete payload : '' Don't forget to adjust the size of the object to your screen if it's not 240x320. Dynamically set UI element dimensions ~ Note This technique relies on small changes in the openHasp device firmware that should be present in all builds of 0.7 after 2021-01. openHasp devices report several device properties to the Custom Component... including tftWidth and tftHeight . These properties are exposed in home assistant as device attributes and can be used in template automations. Here is a modified version of the Display clock and temperature example configuration that will use a \"generic\" jsonl file that has no hard-coded layout attributes: x , y , w , h and will appear the same on devices with different resolutions and screen orientations. Tell the openHasp device to create three text labels. As we are not specifying x/y coordinates, when the device first powers on, all three labels will be drawn in the upper left corner with their default size/values. When plate00 comes online and connects to the MQTT broker, the openHasp Custom Component will be invoked and the yaml below will be executed. The templates will be executed and the computed x , y , w , h values for each UI component will be sent to the plate. 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 { \"page\" : 0 , \"comment\" : \"Default to page0 as the header and page/layout\" } { \"id\" : 1 , \"comment\" : \"Time in the top left\" , \"obj\" : \"label\" , \"text\" : \"00:00\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 2 , \"comment\" : \"Temp in the middle\" , \"obj\" : \"label\" , \"text\" : \"00.0\u00b0C\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 3 , \"comment\" : \"Humidity in the top right\" , \"obj\" : \"label\" , \"text\" : \"00.0%\" , \"bg_color\" : \"#2C3E50\" } Assuming that the above jsonl was deployed to a openHasp device named plate00 , configure the Home Assistant Custom Component with yaml like this: 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 # The top left corner is 0,0, X grows positive to the right and Y grows positive down plate00 : objects : # Header: Time - obj : \"p0b1\" properties : \"align\" : \"left\" \"text\" : \"{{ states('sensor.time') }}\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Temp - obj : \"p0b2\" properties : \"align\" : \"center\" \"text\" : \"{{ states('sensor.room_temperature') }}\u00b0C\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+hdrLblWd}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Humidity - obj : \"p0b3\" properties : \"align\" : \"right\" \"text\" : \"{{ states('sensor.room_humidity') }}%\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+(2*hdrLblWd)}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} You should be able to shift the screen orientation for plate00 by 90 degrees and restart the device to apply your change. When the device boots back up and connects to MQTT, openHasp should report a different value for it's tftHeight and tftWidth which will cause Home Assistant to re-evaluate the templates. A few seconds after connecting to MQTT, plate00 should have an updated layout that reflects it's new screen orientation.","title":"Example Automations"},{"location":"integrations/home-assistant/sampl_autom/#display-of-the-current-album-cover-of-a-media-player","text":"Combined with a media player entity which supports entity_picture attribute, you can automate display of that using the push_image service of the Custom Component. On the plate (named plate_livingroom in this example) you'd have two objects, first a rectangular object with rounded corners, secod an image object placed inside of it. It's hidden by default so you could place this on top of your existing media player controls, and have it pop up only when there's a cover present. To look nice together use the clip_corner property: { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"obj\" , \"x\" : 3 , \"y\" : 48 , \"w\" : 200 , \"h\" : 200 , \"radius\" : 6 , \"clip_corner\" : 1 , \"hidden\" : 1 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"img\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 200 , \"h\" : 200 , \"parentid\" : 15 , \"src\" : \"\" , \"auto_size\" : 1 } The automation below takes care of unhiding them when a cover appears on the sound_livingroom media player, updating the picture when it changes and hiding them again when the player drops the entity_picture attribute (it's stopped or the played media doesn't have a corresponding picture): 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 - id : openhasp-sound_livingroom-detect-mediaplayer-coverart alias : openhasp-sound_livingroom-detect-mediaplayer-coverart trigger : - platform : state entity_id : media_player.sound_livingroom condition : - condition : template value_template : > {{ trigger.from_state.attributes.entity_picture != trigger.to_state.attributes.entity_picture }} action : - choose : - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') != None }}\" sequence : - service : openhasp.push_image target : entity_id : openhasp.plate_livingroom data : image : http://ip.of.your.ha:8123{{ state_attr('media_player.sound_livingroom','entity_picture') }} obj : p6b16 width : 200 height : 200 - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '0' - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') == None }}\" sequence : - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '1'","title":"Display of the current album cover of a media player"},{"location":"integrations/home-assistant/sampl_autom/#backlight-on-dimmed-if-theres-any-light-in-the-room-off-otherwise","text":"The night mode activates when all the lights are off and shutters are down below 25% (assuming it's dark enough for the backlight to be disturbing in such situation), the day mode activates otherwise. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. This will act directly on the plate in a certain room, as it is triggered by entities located in that room. If you have multiple plates in various rooms, you can create separate automations for each. 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 - id : openhasp-plate_myroom-day alias : \"openHASP Night mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":0}' - id : openhasp-plate_myroom-night alias : \"openHASP Day mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ not ( state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" ) }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":60}' Note the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes).","title":"Backlight ON (dimmed) if there's any light in the room, OFF otherwise"},{"location":"integrations/home-assistant/sampl_autom/#backlight-on-dimmed-during-the-day-off-during-the-night-for-all-the-plates","text":"The night mode activates when sun goes down, and the day mode activates when the sun comes up. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. Assuming your plate's configured MQTT group name is plates , this will affect all the plates in your system at once: 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 - id : openhasp-night alias : \"openHASP Night mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation below : -1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":120}' - id : openhasp-day alias : \"openHASP Day mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation above : 1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":0}' Note here too the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes).","title":"Backlight ON (dimmed) during the day, OFF during the night for all the plates"},{"location":"integrations/home-assistant/sampl_autom/#turn-on-moodlight-when-backlight-goes-off-and-back","text":"If your plate has moodlights, it is useful in dark situations, when you don't want to have the screen backlit on all the time as above, but have the mood light on instead. During the day mood light doesn't light. Put your light.plate_my_room_moodlight to a Lovelace card entity row and select a nice color for moodlight. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - id : openhasp-moodlight-on alias : \"openHASP Moodlight ON when Backlight OFF\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'on' to : 'off' action : - service : light.turn_on target : entity_id : light.plate_my_room_moodlight - id : openhasp-moodlight-off alias : \"openHASP Moodlight OFF when Backlight ON\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'off' to : 'on' action : - service : light.turn_off target : entity_id : light.plate_my_room_moodlight","title":"Turn ON moodlight when backlight goes OFF (and back)"},{"location":"integrations/home-assistant/sampl_autom/#return-to-home-page-after-some-idle-time","text":"Apart from the idle times controlling backlight levels, one may want to return to page 1 after a while. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - id : openhasp-back-to-page-1 alias : \"openHASP back to page 1\" trigger : - platform : template value_template : \"{{ state_attr('openhasp.plate_my_room','idle') != 'off' }}\" for : \"00:05:00\" condition : - condition : template value_template : \"{{ states('openhasp.plate_my_room') != '1' and states('openhasp.plate_my_room') != 'unavailable' }}\" action : - service : openhasp.change_page target : entity_id : openhasp.plate_my_room data : page : 1","title":"Return to home page after some idle time"},{"location":"integrations/home-assistant/sampl_autom/#prevent-burn-in-of-the-lcd-screen","text":"You can use this to protect and prolonge the lifetime of the LCD screens, thus being more green and generating less hazardous waste. Wall mounted LCD screens' main problem is that they display the same picture 99.999% of the time. Even if somebody turns off backlight during the night or dark periods, the LCD screen keeps showing the same picture, seen by nobody. There are high chances that this will lead to screen picture burn-in after a few years of operation.","title":"Prevent burn-in of the LCD screen"},{"location":"integrations/home-assistant/sampl_autom/#dynamically-set-ui-element-dimensions","text":"Note This technique relies on small changes in the openHasp device firmware that should be present in all builds of 0.7 after 2021-01. openHasp devices report several device properties to the Custom Component... including tftWidth and tftHeight . These properties are exposed in home assistant as device attributes and can be used in template automations. Here is a modified version of the Display clock and temperature example configuration that will use a \"generic\" jsonl file that has no hard-coded layout attributes: x , y , w , h and will appear the same on devices with different resolutions and screen orientations. Tell the openHasp device to create three text labels. As we are not specifying x/y coordinates, when the device first powers on, all three labels will be drawn in the upper left corner with their default size/values. When plate00 comes online and connects to the MQTT broker, the openHasp Custom Component will be invoked and the yaml below will be executed. The templates will be executed and the computed x , y , w , h values for each UI component will be sent to the plate. 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 { \"page\" : 0 , \"comment\" : \"Default to page0 as the header and page/layout\" } { \"id\" : 1 , \"comment\" : \"Time in the top left\" , \"obj\" : \"label\" , \"text\" : \"00:00\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 2 , \"comment\" : \"Temp in the middle\" , \"obj\" : \"label\" , \"text\" : \"00.0\u00b0C\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 3 , \"comment\" : \"Humidity in the top right\" , \"obj\" : \"label\" , \"text\" : \"00.0%\" , \"bg_color\" : \"#2C3E50\" } Assuming that the above jsonl was deployed to a openHasp device named plate00 , configure the Home Assistant Custom Component with yaml like this: 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 # The top left corner is 0,0, X grows positive to the right and Y grows positive down plate00 : objects : # Header: Time - obj : \"p0b1\" properties : \"align\" : \"left\" \"text\" : \"{{ states('sensor.time') }}\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Temp - obj : \"p0b2\" properties : \"align\" : \"center\" \"text\" : \"{{ states('sensor.room_temperature') }}\u00b0C\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+hdrLblWd}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Humidity - obj : \"p0b3\" properties : \"align\" : \"right\" \"text\" : \"{{ states('sensor.room_humidity') }}%\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+(2*hdrLblWd)}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} You should be able to shift the screen orientation for plate00 by 90 degrees and restart the device to apply your change. When the device boots back up and connects to MQTT, openHasp should report a different value for it's tftHeight and tftWidth which will cause Home Assistant to re-evaluate the templates. A few seconds after connecting to MQTT, plate00 should have an updated layout that reflects it's new screen orientation.","title":"Dynamically set UI element dimensions"},{"location":"integrations/home-assistant/sampl_conf/","text":"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 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"00.0\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 220 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"\u00b0C\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration all you need for the objects is: 1 2 3 4 5 6 7 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\" - obj : \"p0b6\" properties : \"text\" : \"{{ states('sensor.time') }}\" Note: ~ You can of course omit the second label object with the unit and use the same for both value and unit: 1 2 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration you will add the unit to the value using the template: 1 2 3 4 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\u00b0C\" 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 { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"align\" : 1 } 1 2 3 4 5 6 7 8 - obj : \"p1b2\" # switch, checkbox or btn with toggle true properties : \"val\" : '{{ 1 if is_state(\"light.my_lamp\", \"on\") else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_lamp\", \"on\") else \"\\uE335\" | e }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.my_lamp\" Dropdown (self-populating from an input_select) ~ 1 { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 5 , \"y\" : 40 , \"w\" : 230 , \"h\" : 30 , \"options\" : \"\" } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - obj : \"p1b3\" # dropdown properties : \"options\" : > {% if (state_attr('input_select.my_dropdown_selections','options') != none and states('input_select.my_dropdown_selections') not in ['unavailable', 'unknown']) %}{%for item in state_attr('input_select.my_dropdown_selections','options')%}{{item+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"val\" : > {% if (state_attr('input_select.my_dropdown_selections','options') != none and states('input_select.my_dropdown_selections') not in ['unavailable', 'unknown']) %}{%for item in state_attr('input_select.my_dropdown_selections','options')%} {{loop.index -1 if item == states('input_select.my_dropdown_selections') }} {%-endfor%}{% endif %} event : \"changed\" : - service : input_select.select_option data : option : '{{ text }}' target : entity_id : input_select.my_dropdown_selections - service : persistent_notification.create data : message : Selected {{ text }} Color coded icons ~ Color code a WiFi icon according to RSSI reported by the plate openHASP config: (screen size 240x320) 1 { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"\\uE5A9\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } relevant openHASP-custom-component config: 1 2 3 - obj : \"p0b1\" properties : \"text_color\" : \"{% if -30 <= state_attr('openhasp.openhasp_plate','rssi') |int %}green{% elif -31 > state_attr('openhasp.openhasp_plate','rssi') |int >= -50 %}orange{% elif -51 > state_attr('openhasp.openhasp_plate','rssi') |int >= -80 %}tomato{% else %}red{% endif %}\" Color code a temperature icon according to sensor values openHASP config: (screen size 240x320) 1 { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 165 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"\\uE50F\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } relevant openHASP-custom-component config: 1 2 3 - obj : \"p0b3\" properties : \"text_color\" : \"{% if states('sensor.room_temperature') |int <= 21 %}#4682B4{% elif 21 < states('sensor.room_temperature') |int <= 26 %}green{% else %}red{% endif %}\" Variable sized icons ~ Have a fan icon which changes its size depending on the speed of the fan, and goes off the screen when the fan is off. openHASP config: 1 { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 1 , \"y\" : 1 , \"h\" : 35 , \"w\" : 35 , \"text\" : \"\\uE210\" , \"align\" : \"left\" , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"yellow\" } relevant openHASP-custom-component config: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - obj : \"p0b1\" properties : \"jsonl\" : > {% if is_state('input_select.fan_speed', 'Low') %} {\"text_font\":12,\"x\":6,\"y\":7} {%-elif is_state('input_select.fan_speed', 'Medium') %} {\"text_font\":16,\"x\":5,\"y\":6} {%-elif is_state('input_select.fan_speed', 'Hign') %} {\"text_font\":24,\"x\":1,\"y\":2} {%-elif is_state('input_select.fan_speed', 'Turbo') %} {\"text_font\":32,\"x\":-2,\"y\":-3} {%-elif is_state('input_select.fan_speed', 'OFF') %} {\"text_font\":12,\"x\":-10,\"y\":-10} {% endif %} 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 { \"page\" : 1 , \"id\" : 31 , \"obj\" : \"slider\" , \"x\" : 6 , \"y\" : 15 , \"w\" : 14 , \"h\" : 180 , \"min\" : 1 , \"max\" : 255 } { \"page\" : 1 , \"id\" : 32 , \"obj\" : \"cpicker\" , \"x\" : 30 , \"y\" : 10 , \"w\" : 180 , \"h\" : 180 } 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 - obj : \"p1b31\" # Light brightness properties : \"val\" : \"{{ state_attr('light.plate_moodlight', 'brightness') if state_attr('light.plate_moodlight', 'brightness') != None else 0 }}\" event : \"changed\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" - obj : \"p1b32\" # Light color properties : \"color\" : > {% if is_state('light.plate_moodlight','on') %} {% set rgb = state_attr('light.plate_moodlight','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" The brightness slider value gets updated from the 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 { \"page\" : 1 , \"id\" : 4 , \"obj\" : \"btn\" , \"x\" : 5 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 5 , \"obj\" : \"btn\" , \"x\" : 83 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 6 , \"obj\" : \"btn\" , \"x\" : 161 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } 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 - obj : \"p1b4\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b5\" properties : \"text\" : > {% if is_state('cover.cover_1', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.cover_1', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b6\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.cover_1\" 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 { \"page\" : 4 , \"id\" : 20 , \"obj\" : \"btnmatrix\" , \"x\" : 0 , \"y\" : 20 , \"w\" : 240 , \"h\" : 70 , \"options\" :[ \"\\uE05D\" , \"\\uE4DB\" , \"\\uE045\" ], \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 } 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 - obj : \"p4b20\" properties : \"options\" : > {% if is_state('cover.cover_1', 'closing') %} [\"\\uE05D\",\"\\uE4DB\",\"#FFFF00 \\uE045\"] {%-elif is_state('cover.cover_1', 'opening') %} [\"#FFFF00 \\uE05D\",\"\\uE4DB\",\"\\uE045\"] {%-else %} [\"\\uE05D\",\"\\uE4DB\",\"\\uE045\"] {% endif %} event : \"down\" : - service : > {% if val == 0 %} cover.open_cover {%-elif val == 1 %} cover.stop_cover {%-elif val == 2 %} cover.close_cover {% endif %} target : entity_id : cover.cover_1 Covers like in Lovelace ~ The icon behaves like in Lovelace. UI theme set to Hasp Light in plate's web interface. Your browser does not support the video tag. 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 { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 33 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 43 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 1\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 69 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 79 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 2\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 25 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 26 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } 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 - obj : \"p5b12\" properties : \"text\" : > {% if is_state('cover.my_cover', 'closing') %} {{ \"\\uE6C0\" | e }} {%-elif is_state('cover.my_cover', 'opening') %} {{ \"\\uE6C3\" | e }} {%-elif is_state('cover.my_cover', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.my_cover', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} - obj : \"p5b14\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b15\" event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b16\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.my_cover\" 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 { \"page\" : 6 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 , \"bg_opa\" : 0 , \"shadow_opa\" : 140 , \"shadow_color\" : \"black\" , \"shadow_width\" : 20 , \"shadow_spread\" : 0 } { \"page\" : 6 , \"id\" : 11 , \"obj\" : \"obj\" , \"x\" : 8 , \"y\" : 38 , \"w\" : 200 , \"h\" : 84 , \"click\" : 0 } { \"page\" : 6 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 48 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 83 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 14 , \"obj\" : \"bar\" , \"x\" : 8 , \"y\" : 117 , \"w\" : 200 , \"h\" : 5 , \"min\" : 0 , \"max\" : 100 , \"border_opa\" : 0 , \"pad_top\" : 0 , \"pad_bottom\" : 0 , \"pad_left\" : 0 , \"pad_right\" : 0 } { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"dropdown\" , \"x\" : 8 , \"y\" : 129 , \"w\" : 120 , \"h\" : 30 , \"options\" : \"Source1\\nSource2\\nSource3\" , \"direction\" : 3 , \"max_height\" : 300 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"dropdown\" , \"x\" : 133 , \"y\" : 129 , \"w\" : 75 , \"h\" : 30 , \"options\" : \"Jazz\\nPop\\nRock\" , \"direction\" : 2 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 17 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 166 , \"w\" : 50 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AE\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 18 , \"obj\" : \"btn\" , \"x\" : 66 , \"y\" : 166 , \"w\" : 83 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE40A\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 19 , \"obj\" : \"btn\" , \"x\" : 157 , \"y\" : 166 , \"w\" : 51 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AD\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 20 , \"obj\" : \"slider\" , \"x\" : 212 , \"y\" : 38 , \"w\" : 20 , \"h\" : 244 , \"min\" : 0 , \"max\" : 100 , \"val\" : 85 } { \"page\" : 6 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE425\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 60 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE457\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 111 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE49E\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 163 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE57E\" , \"text_font\" : 32 } 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 - obj : \"p6b12\" # artist label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_artist') if state_attr('media_player.sound_my_room1','media_artist') else '-' }}\" - obj : \"p6b13\" # title label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_title') if state_attr('media_player.sound_my_room1','media_title') else '-' }}\" - obj : \"p6b15\" # sources list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','source_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{\"(no source)\\n\"|e}} {%- for source in state_attr('media_player.sound_my_room1','source_list') -%} {{source+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %} {% if state_attr('media_player.sound_my_room1','source') == None %}0{% else %} {%for source in state_attr('media_player.sound_my_room1','source_list')%} {{loop.index if source == state_attr('media_player.sound_my_room1','source') }} {%-endfor%}{%-endif %}{%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_source data : entity_id : media_player.sound_my_room1 source : \"{{ text }}\" - obj : \"p6b16\" # sound modes list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','sound_mode_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {%-for soundmode in state_attr('media_player.sound_my_room1','sound_mode_list')-%} {{soundmode+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %}{%for source in state_attr('media_player.sound_my_room1','sound_mode_list')%} {{loop.index -1 if source == state_attr('media_player.sound_my_room1','sound_mode') }} {%-endfor%}{% endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_sound_mode data : entity_id : media_player.sound_my_room1 sound_mode : \"{{ text }}\" - obj : \"p6b14\" # progressbar properties : \"max\" : \"{{ state_attr('media_player.sound_my_room1','media_duration') | int }}\" \"val\" : \"{{ state_attr('media_player.sound_my_room1','media_position') | int }}\" - obj : \"p6b18\" # play/pause/stop properties : \"text\" : > {% if is_state('media_player.sound_my_room1', 'playing') %} {{ \"\\uE3E4\" | e }} {%-else %} {{ \"\\uE40A\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_play_pause target : entity_id : media_player.sound_my_room1 \"long\" : - service : media_player.media_stop target : entity_id : media_player.sound_my_room1 - obj : \"p6b17\" # prev properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_previous_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b19\" # next properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_next_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b20\" # volume slider properties : \"val\" : > {% if (state_attr('media_player.sound_my_room1','volume_level') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{ state_attr('media_player.sound_my_room1','volume_level') * 100 | int(default=80) }} {%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" \"up\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" - obj : \"p6b21\" # power properties : \"text_color\" : \"{{ '#B00000' if states('media_player.sound_my_room1') == 'off' else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.toggle data : entity_id : media_player.sound_my_room1 - obj : \"p6b22\" # repeat properties : \"text\" : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} {{ \"\\uE458\" | e }} {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} {{ \"\\uE456\" | e }} {%-else %} {{ \"\\uE457\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.repeat_set data : entity_id : media_player.sound_my_room1 repeat : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} all {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} off {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'off') %} one {%-endif %} - obj : \"p6b23\" # shuffle properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} {{ \"\\uE49D\" | e }} {%-else %} {{ \"\\uE49E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.shuffle_set data : entity_id : media_player.sound_my_room1 shuffle : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} false {% else %} true {%-endif %} - obj : \"p6b24\" # mute properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} {{ \"\\uE75F\" | e }} {%-else %} {{ \"\\uE57E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.volume_mute data : entity_id : media_player.sound_my_room1 is_volume_muted : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} false {% else %} true {%-endif %} Note that the 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. Your browser does not support the video tag. relevant openHASP config: (screen size 240x320) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 20 , \"obj\" : \"arc\" , \"x\" : 5 , \"y\" : 37 , \"w\" : 230 , \"h\" : 230 , \"min\" : 170 , \"max\" : 300 , \"val\" : 250 , \"border_side\" : 0 , \"type\" : 0 , \"rotation\" : 0 , \"start_angle\" : 135 , \"end_angle\" : 45 , \"adjustable\" : \"true\" , \"line_width\" : 21 , \"line_width10\" : 21 , \"line_color10\" : \"#34bdeb\" , \"bg_opa\" : 0 , \"pad_top20\" : 5 , \"pad_bottom20\" : 5 , \"pad_left20\" : 5 , \"pad_right20\" : 5 , \"pad_top\" : 5 , \"pad_bottom\" : 5 , \"pad_left\" : 5 , \"pad_right\" : 5 } { \"page\" : 3 , \"id\" : 21 , \"obj\" : \"gauge\" , \"x\" : 28 , \"y\" : 28 , \"w\" : 175 , \"h\" : 175 , \"parentid\" : 20 , \"min\" : 170 , \"max\" : 300 , \"val\" : 224 , \"format\" : 1 , \"critical_value\" : 301 , \"label_count\" : 14 , \"line_count\" : 27 , \"border_width\" : 0 , \"pad_top\" : 2 , \"pad_bottom\" : 2 , \"pad_left\" : 2 , \"pad_right\" : 2 , \"value_str\" : \"\u00b0C\" , \"value_ofs_y\" : 55 , \"value_font\" : 16 , \"bg_opa\" : 0 , \"line_width10\" : 3 , \"line_rounded10\" : 1 , \"line_color\" : \"#348feb\" , \"line_color60\" : \"#348feb\" , \"scale_grad_color\" : \"#eb4934\" , \"scale_grad_color60\" : \"#eb4934\" , \"scale_end_color60\" : \"#eb4934\" } { \"page\" : 3 , \"id\" : 22 , \"obj\" : \"obj\" , \"x\" : 85 , \"y\" : 85 , \"w\" : 60 , \"h\" : 60 , \"parentid\" : 20 , \"click\" : 0 , \"radius\" : 30 , \"border_width\" : 2 , \"border_opa\" : 200 } { \"page\" : 3 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 80 , \"y\" : 100 , \"w\" : 70 , \"h\" : 30 , \"parentid\" : 20 , \"text\" : \"22.4\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 24 , \"obj\" : \"obj\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"click\" : 0 , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 25 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"25\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 26 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 220 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" , \"border_width\" : 0 } { \"page\" : 3 , \"id\" : 30 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 235 , \"w\" : 240 , \"h\" : 80 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 , \"radius\" : 0 } { \"page\" : 3 , \"id\" : 31 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 32 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 33 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 41 , \"obj\" : \"switch\" , \"x\" : 35 , \"y\" : 10 , \"w\" : 60 , \"h\" : 30 , \"parentid\" : 31 , \"radius\" : 25 , \"radius20\" : 25 } { \"page\" : 3 , \"id\" : 42 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 32 , \"options\" : \"fan_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 43 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 33 , \"options\" : \"hvac_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } 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 - obj : \"p3b20\" # arc slider properties : \"val\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') | int * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"line_color1\" : > {% if is_state('climate.thermostat_1', 'cool') %} {{ \"#346beb\" }} {%-elif is_state('climate.thermostat_1', 'heat_cool') %} {{ \"#34bdeb\" }} {%-elif is_state('climate.thermostat_1', 'heat') %} {{ \"#eb3434\" }} {%-elif is_state('climate.thermostat_1', 'dry') %} {{ \"#ebeb34\" }} {%-elif is_state('climate.thermostat_1', 'fan_only') %} {{ \"#34eb77\" }} {%-else %} {{ \"#9f96b0\" }} {% endif %} event : \"changed\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" - obj : \"p3b21\" # gauge current temp properties : \"val\" : > {% if not (is_state('sensor.ble_atlaghomerseklet','unavailable') or is_state('sensor.ble_atlaghomerseklet','unknown')) %} {{ states('sensor.ble_atlaghomerseklet') | float (default=0) * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"critical_value\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 + 1 }} {%- endif %} \"label_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int + 1 }} {%- endif %} \"line_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ (state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int) * 2 + 1 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b23\" # label current temp (and +/- with short/long touch) properties : \"text\" : > {% if (is_state('sensor.temp_room_1','unavailable') or is_state('sensor.temp_room_1','unknown')) %} {{ \"--.-\" }} {%-else %} {{ states('sensor.temp_room_1') | round(1,default=0) }} {%- endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') + state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" \"long\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') - state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" - obj : \"p3b25\" # label target temp properties : \"text\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b41\" # on/off switch properties : \"val\" : \"{{ 0 if (is_state('climate.thermostat_1', 'off') or is_state('climate.thermostat_1', 'unavailable')) else 1 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"down\" : - service_template : > {% if val == 0 -%} climate.turn_on {% else -%} climate.turn_off {% endif -%} entity_id : \"climate.thermostat_1\" - obj : \"p3b30\" # tab dots event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p3b26.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 2 %} {{ \"#909090 \\u2022# #909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p3b42\" # dropdown with fan_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','fan_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {%- if mode == 'auto' -%} Automatic{{\"\\n\"|e}} {%- elif mode == 'low' -%} Low{{\"\\n\"|e}} {%- elif mode == 'medium' -%} Medium{{\"\\n\"|e}} {%- elif mode == 'high' -%} High{{\"\\n\"|e}} {%- elif mode == 'turbo' -%} Turbo{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {{loop.index -1 if mode == state_attr('climate.thermostat_1','fan_mode') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_fan_mode target : entity_id : climate.thermostat_1 data : fan_mode : > {% if text == \"Automatic\" -%} auto {% elif text == 'Low' -%} low {% elif text == 'Medium' -%} medium {% elif text == 'High' -%} high {% elif text == 'Turbo' -%} turbo {% endif -%} - obj : \"p3b43\" # dropdown with hvac_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','hvac_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {%- if mode == 'off' -%} Off{{\"\\n\"|e}} {%- elif mode == 'heat' -%} Heating{{\"\\n\"|e}} {%- elif mode == 'cool' -%} Cooling{{\"\\n\"|e}} {%- elif mode == 'heat_cool' -%} Heat/Cool{{\"\\n\"|e}} {%- elif mode == 'dry' -%} Drying{{\"\\n\"|e}} {%- elif mode == 'fan_only' -%} Fan only{{\"\\n\"|e}} {%- else -%} On{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {{loop.index -1 if mode == states('climate.thermostat_1') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_hvac_mode target : entity_id : climate.thermostat_1 data : hvac_mode : > {% if text == \"Off\" -%} off {% elif text == 'Heating' -%} heat {% elif text == 'Cooling' -%} cool {% elif text == 'Heat/Cool' -%} heat_cool {% elif text == 'Drying' -%} dry {% elif text == 'Fan only' -%} fan_only {% endif -%} 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 {target= blank} (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: light theme dark theme 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 { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"WEATHER\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"img\" , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 2 , \"auto_size\" : 1 , \"w\" : 128 , \"offset_x\" : -6 , \"offset_y\" : -10 } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"label\" , \"x\" : 100 , \"y\" : 10 , \"w\" : 130 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"date current\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 34 , \"w\" : 95 , \"h\" : 40 , \"align\" : \"center\" , \"text\" : \"00.0\u00b0C\" , \"parentid\" : 2 , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 17 , \"obj\" : \"label\" , \"x\" : 110 , \"y\" : 78 , \"w\" : 120 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"condition\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 19 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 95 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#000000 \\u2022# #909090 \\u2022#\" , \"parentid\" : 2 , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" } { \"page\" : 5 , \"id\" : 10 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 260 , \"parentid\" : 2 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 21 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 123 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+2\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 123 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 31 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 154 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+3\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 32 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 154 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 33 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 41 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 186 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+4\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 42 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 186 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 43 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 51 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 218 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+5\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 52 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 218 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 53 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 61 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 123 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+1\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 62 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 63 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 64 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 71 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 154 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+2\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 72 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 73 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 74 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 81 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 186 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+3\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 82 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 83 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 84 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 91 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 218 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+4\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 92 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 93 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 94 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } 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 - obj : \"p5b14\" # Icon properties : \"src\" : \"{{ 'L:/w-128-' + states('weather.openweathermap') + '.png' if not is_state('weather.openweathermap','unavailable') }}\" - obj : \"p5b15\" # Current date (adjust format to your needs) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set day = (states.weather.openweathermap.last_changed).strftime('%w') %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{- days[ day | int -1 ] }} {{ (states.weather.openweathermap.last_changed).strftime('%m. %d. ') }} {% endif -%} - obj : \"p5b16\" # Current temp (you can use your own outdoor temp sensor if you have one) properties : \"text\" : \"{{ state_attr('weather.openweathermap','temperature') |string + '\u00b0C' if not is_state('weather.openweathermap','unavailable') }}\" # or \"{{ states('sensor.your_own_temp_sensor') if not is_state('sensor.your_own_temp_sensor','unavailable') else '--' }}\u00b0C\" - obj : \"p5b17\" # Current weather condition properties : \"text\" : > {% if is_state('weather.openweathermap','clear-night') -%} Clear night {% elif is_state('weather.openweathermap','cloudy') -%} Cloudy {% elif is_state('weather.openweathermap','fog') -%} Fog {% elif is_state('weather.openweathermap','hail') -%} Hail {% elif is_state('weather.openweathermap','lightning') -%} Lightning {% elif is_state('weather.openweathermap','lightning-rainy') -%} Thunderstorms {% elif is_state('weather.openweathermap','partlycloudy') -%} Partly cloudy {% elif is_state('weather.openweathermap','pouring') -%} Pouring rain {% elif is_state('weather.openweathermap','rainy') -%} Rainy {% elif is_state('weather.openweathermap','snowy') -%} Snowy {% elif is_state('weather.openweathermap','snowy-rainy') -%} Snowy-rainy {% elif is_state('weather.openweathermap','sunny') -%} Sunny {% elif is_state('weather.openweathermap','windy') -%} Windy {% elif is_state('weather.openweathermap','windy-variant') -%} Windy {% elif is_state('weather.openweathermap','exceptional') -%} Exceptional {% elif is_state('weather.openweathermap','unavailable') -%} (not available) {% else -%} {{ states('weather.openweathermap') }} {% endif -%} - obj : \"p5b10\" # tab dots - MAKE SURE YOU UPDATE THIS ONE!! event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p5b19.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p5b21\" # Forecast time +1h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b22\" # Forecast temp +1h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[1]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b23\" # Forecast condition +1h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b31\" # Forecast time +2h (using Dawn/Morn etc instead of Today/Tomorrow) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set hour = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) | timestamp_custom(\"%-H\") | int %} {%- if 4 <= hour < 6 %} Dawning {%- elif 6 <= hour < 9 %} Morning {%- elif 9 <= hour < 12 %} Forenoon {%- elif 12 <= hour < 18 %} Afternoon {%- elif 18 <= hour < 23 %} Evening {%- elif 23 <= hour or hour < 4 %} Night {%- endif %} {{- \" \" + hour |string + \" o'clock\" }} {%- endif %} - obj : \"p5b32\" # Forecast temp +2h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[3]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b33\" # Forecast condition +2h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[3]['condition'] }}.png {%- endif %} - obj : \"p5b41\" # Forecast time +4h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[6]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b42\" # Forecast temp +4h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[6]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b43\" # Forecast condition +4h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[6]['condition'] }}.png {%- endif %} - obj : \"p5b51\" # Forecast time +8h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[12]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b52\" # Forecast temp +8h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[12]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b53\" # Forecast condition +8h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[12]['condition'] }}.png {%- endif %} - obj : \"p5b61\" # Forecast date +1d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[0]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b62\" # Forecast temp min +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b63\" # Forecast temp max +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b64\" # Forecast condition +1d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[0]['condition'] }}.png {%- endif %} - obj : \"p5b71\" # Forecast date +2d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b72\" # Forecast temp min +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b73\" # Forecast temp max +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b74\" # Forecast condition +2d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b81\" # Forecast date +3d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[2]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b82\" # Forecast temp min +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b83\" # Forecast temp max +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b84\" # Forecast condition +3d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[2]['condition'] }}.png {%- endif %} - obj : \"p5b91\" # Forecast date +4d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b92\" # Forecast temp min +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b93\" # Forecast temp max +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b94\" # Forecast condition +4d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[3]['condition'] }}.png {%- endif %} 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. fan perfume 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_width10\" : 19 , \"line_color10\" : \"#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 state_attr(\"input_select.fan_presets\",\"options\") is not none -%} {% 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 states('input_select.fan_presets') in ['unavailable', 'unknown', 'OFF'] else 255 }}\" \"jsonl\" : > {% if is_state('number.plate_test_page_number', '4') %} {% if is_state('input_select.fan_presets', 'Alap') %} {\"speed\":7000,\"line_color10\":\"#31de70\"} {%-elif is_state('input_select.fan_presets', 'K\u00f6z\u00e9p') %} {\"speed\":1700,\"line_color10\":\"#dede1f\"} {%-elif is_state('input_select.fan_presets', 'Magas') %} {\"speed\":800,\"line_color10\":\"#d6a11a\"} {%-elif is_state('input_select.fan_presets', 'Turb\u00f3') %} {\"speed\":250,\"line_color10\":\"#ff4a4a\"} {% endif %} {% else -%} {\"speed\":0} {% endif %} - obj : \"p4b54\" # Scent Diffuser ON/OFF button properties : \"val\" : '{{ 1 if is_state(\"fan.scent_diffuser_intensity\", \"on\") else 0 }}' \"enabled\" : \"{{ 'false' if states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 . Using tags ~ You can avoid too much code repetition when you have multiple similar objects on a page, doing the same thing with different entities, and you'd like to make accessible some advanced options too. Presenting everyting flat will overwhelm your user interface, so it would be better to just show the most used controls, and only display the advanced options in popups related to unique objects. Tag property was made to ease this task. Colored lights panel ~ In the example below we have four coloured lights. Squeezing the ON/OFF button, the color picker and the brightness selector for all four lights on a single page can be challenging - and the result will likely be useless on a small touch screen. Instead, we'll just place the toggle buttons with descriptive labels on the page, and we'll only display the color picker and the brightness selector on demand, in this case when the user touches the descriptive coloured label. While dynamically drawing these objects we're setting the tag property for the color picker and the slider to the entity_id of the light we want to adjust, so that when we're interacting with them, the Custom Component can know which light it has to send the adjustments to. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"COLOURED LIGHTS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"I.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"II.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"III.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"IV.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p5b11\" # toggle button for ON/OFF switching of light I. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_1\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_1\" - obj : \"p5b12\" # toggle button for ON/OFF switching of light II. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_2\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_2\" - obj : \"p5b13\" # toggle button for ON/OFF switching of light III. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_3\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_3\" - obj : \"p5b14\" # toggle button for ON/OFF switching of light IV. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_4\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_4\" - obj : \"p5b2\" # label showing the current color of light I. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_1','on') %} {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_1 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light I. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light I.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_1\",\"color\": {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_1\",\"val\": {{- state_attr('light.dmx_vbar_1', 'brightness') -}} } - obj : \"p5b3\" # label showing the current color of light II. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_2','on') %} {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_2 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light II. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light II.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_2\",\"color\": {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_2\",\"val\": {{- state_attr('light.dmx_vbar_2', 'brightness') -}} } - obj : \"p5b4\" # label showing the current color of light III. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_3','on') %} {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_3 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light III. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light III.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_3\",\"color\": {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_3\",\"val\": {{- state_attr('light.dmx_vbar_3', 'brightness') -}} } - obj : \"p5b5\" # label showing the current color of light IV. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_4','on') %} {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_4 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light IV. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light IV.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_4\",\"color\": {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_4\",\"val\": {{- state_attr('light.dmx_vbar_4', 'brightness') -}} } - obj : \"p5b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b201\" # set the color of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b202\" # set the brightness of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" brightness : \"{{ val }}\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete Without tags, the last 3 object definitions would have to be added for each light, and also it would be needed to be drawn separately for each light, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. Shutter control panel ~ In the second example, we have five windows with motorized shutters. In addition to the usual UP/STOP/DOWN buttons, the inhabitants want to have three shortcut positions for each shutter, and also a slider for free positioning. Useless to say that it's impossible to put all these on a page, and also it would be a pity to use up 5 pages just for these. We'll just put the most used, UP/STOP/DOWN buttons on the page (this already looks a bit much...) and we'll use a long press event on the middle STOP button to show a pop-up with the extra required settings related to the desired shutter. The tag here will be a JSON object referencing both the entity_id and the position specific to the desired shutter, eg. \"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"} , this will be set for the buttons and the slider appearing in the popup. Since the shutters are different sizes and types, the same intermediate physical position may correspond to different numeric values in Home Assistant. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 2 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"MOTORIZED COVERS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 2 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 7 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"I.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 53 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"II.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 99 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"III.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"IV.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 191 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"V.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 31 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 32 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 33 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 41 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 42 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 43 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 51 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 52 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 53 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p2b11\" # shutter I. up button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b13\" # shutter I. down button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b12\" # shutter I. middle stop button properties : \"text\" : > {% if is_state('cover.bigroom_i', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_i', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_i\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - I.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"54\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_i','current_position') -}} } - obj : \"p2b21\" # shutter II. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b23\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b22\" properties : \"text\" : > {% if is_state('cover.bigroom_ii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_ii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_ii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - II.\",\"align\":\"center\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"18\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_ii','current_position') -}} } - obj : \"p2b31\" # shutter III. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b33\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b32\" properties : \"text\" : > {% if is_state('cover.bigroom_iii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - III.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iii','current_position') -}} } - obj : \"p2b41\" # shutter IV. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b43\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b42\" properties : \"text\" : > {% if is_state('cover.bigroom_iv', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iv', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iv\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - IV.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iv','current_position') -}} } - obj : \"p2b51\" # shutter V. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b53\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b52\" properties : \"text\" : > {% if is_state('cover.bigroom_v', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_v', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_v\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - V.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"55\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"19\"},\"val\": {{- state_attr('cover.bigroom_v','current_position') -}} } - obj : \"p2b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b201\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b202\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b203\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b204\" # set the shutter position from the slider for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"up\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ val | int }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete Again - without tags, the last 5 object definitions would have to be added for each shutter, and also it would be needed to be drawn separately for each one, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. 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.","title":"Example Configurations"},{"location":"integrations/home-assistant/sampl_conf/#display-clock-and-temperature","text":"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 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"00.0\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 220 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"\u00b0C\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration all you need for the objects is: 1 2 3 4 5 6 7 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\" - obj : \"p0b6\" properties : \"text\" : \"{{ states('sensor.time') }}\"","title":"Display clock and temperature"},{"location":"integrations/home-assistant/sampl_conf/#some-basic-controls","text":"Jsonl and Home Assistant configuration:","title":"Some basic controls"},{"location":"integrations/home-assistant/sampl_conf/#color-coded-icons","text":"","title":"Color coded icons"},{"location":"integrations/home-assistant/sampl_conf/#variable-sized-icons","text":"Have a fan icon which changes its size depending on the speed of the fan, and goes off the screen when the fan is off. openHASP config: 1 { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 1 , \"y\" : 1 , \"h\" : 35 , \"w\" : 35 , \"text\" : \"\\uE210\" , \"align\" : \"left\" , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"yellow\" } relevant openHASP-custom-component config: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - obj : \"p0b1\" properties : \"jsonl\" : > {% if is_state('input_select.fan_speed', 'Low') %} {\"text_font\":12,\"x\":6,\"y\":7} {%-elif is_state('input_select.fan_speed', 'Medium') %} {\"text_font\":16,\"x\":5,\"y\":6} {%-elif is_state('input_select.fan_speed', 'Hign') %} {\"text_font\":24,\"x\":1,\"y\":2} {%-elif is_state('input_select.fan_speed', 'Turbo') %} {\"text_font\":32,\"x\":-2,\"y\":-3} {%-elif is_state('input_select.fan_speed', 'OFF') %} {\"text_font\":12,\"x\":-10,\"y\":-10} {% endif %}","title":"Variable sized icons"},{"location":"integrations/home-assistant/sampl_conf/#light-brightness-and-color","text":"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 { \"page\" : 1 , \"id\" : 31 , \"obj\" : \"slider\" , \"x\" : 6 , \"y\" : 15 , \"w\" : 14 , \"h\" : 180 , \"min\" : 1 , \"max\" : 255 } { \"page\" : 1 , \"id\" : 32 , \"obj\" : \"cpicker\" , \"x\" : 30 , \"y\" : 10 , \"w\" : 180 , \"h\" : 180 } 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 - obj : \"p1b31\" # Light brightness properties : \"val\" : \"{{ state_attr('light.plate_moodlight', 'brightness') if state_attr('light.plate_moodlight', 'brightness') != None else 0 }}\" event : \"changed\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" - obj : \"p1b32\" # Light color properties : \"color\" : > {% if is_state('light.plate_moodlight','on') %} {% set rgb = state_attr('light.plate_moodlight','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" The brightness slider value gets updated from the 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.","title":"Light brightness and color"},{"location":"integrations/home-assistant/sampl_conf/#cover-with-state-feedback","text":"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 { \"page\" : 1 , \"id\" : 4 , \"obj\" : \"btn\" , \"x\" : 5 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 5 , \"obj\" : \"btn\" , \"x\" : 83 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 6 , \"obj\" : \"btn\" , \"x\" : 161 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } 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 - obj : \"p1b4\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b5\" properties : \"text\" : > {% if is_state('cover.cover_1', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.cover_1', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b6\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.cover_1\"","title":"Cover with state feedback"},{"location":"integrations/home-assistant/sampl_conf/#cover-with-button-matrix","text":"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 { \"page\" : 4 , \"id\" : 20 , \"obj\" : \"btnmatrix\" , \"x\" : 0 , \"y\" : 20 , \"w\" : 240 , \"h\" : 70 , \"options\" :[ \"\\uE05D\" , \"\\uE4DB\" , \"\\uE045\" ], \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 } 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 - obj : \"p4b20\" properties : \"options\" : > {% if is_state('cover.cover_1', 'closing') %} [\"\\uE05D\",\"\\uE4DB\",\"#FFFF00 \\uE045\"] {%-elif is_state('cover.cover_1', 'opening') %} [\"#FFFF00 \\uE05D\",\"\\uE4DB\",\"\\uE045\"] {%-else %} [\"\\uE05D\",\"\\uE4DB\",\"\\uE045\"] {% endif %} event : \"down\" : - service : > {% if val == 0 %} cover.open_cover {%-elif val == 1 %} cover.stop_cover {%-elif val == 2 %} cover.close_cover {% endif %} target : entity_id : cover.cover_1","title":"Cover with button matrix"},{"location":"integrations/home-assistant/sampl_conf/#covers-like-in-lovelace","text":"The icon behaves like in Lovelace. UI theme set to Hasp Light in plate's web interface. Your browser does not support the video tag. 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 { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 33 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 43 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 1\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 69 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 79 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 2\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 25 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 26 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } 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 - obj : \"p5b12\" properties : \"text\" : > {% if is_state('cover.my_cover', 'closing') %} {{ \"\\uE6C0\" | e }} {%-elif is_state('cover.my_cover', 'opening') %} {{ \"\\uE6C3\" | e }} {%-elif is_state('cover.my_cover', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.my_cover', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} - obj : \"p5b14\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b15\" event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b16\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.my_cover\"","title":"Covers like in Lovelace"},{"location":"integrations/home-assistant/sampl_conf/#media-player","text":"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 { \"page\" : 6 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 , \"bg_opa\" : 0 , \"shadow_opa\" : 140 , \"shadow_color\" : \"black\" , \"shadow_width\" : 20 , \"shadow_spread\" : 0 } { \"page\" : 6 , \"id\" : 11 , \"obj\" : \"obj\" , \"x\" : 8 , \"y\" : 38 , \"w\" : 200 , \"h\" : 84 , \"click\" : 0 } { \"page\" : 6 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 48 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 83 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 14 , \"obj\" : \"bar\" , \"x\" : 8 , \"y\" : 117 , \"w\" : 200 , \"h\" : 5 , \"min\" : 0 , \"max\" : 100 , \"border_opa\" : 0 , \"pad_top\" : 0 , \"pad_bottom\" : 0 , \"pad_left\" : 0 , \"pad_right\" : 0 } { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"dropdown\" , \"x\" : 8 , \"y\" : 129 , \"w\" : 120 , \"h\" : 30 , \"options\" : \"Source1\\nSource2\\nSource3\" , \"direction\" : 3 , \"max_height\" : 300 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"dropdown\" , \"x\" : 133 , \"y\" : 129 , \"w\" : 75 , \"h\" : 30 , \"options\" : \"Jazz\\nPop\\nRock\" , \"direction\" : 2 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 17 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 166 , \"w\" : 50 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AE\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 18 , \"obj\" : \"btn\" , \"x\" : 66 , \"y\" : 166 , \"w\" : 83 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE40A\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 19 , \"obj\" : \"btn\" , \"x\" : 157 , \"y\" : 166 , \"w\" : 51 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AD\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 20 , \"obj\" : \"slider\" , \"x\" : 212 , \"y\" : 38 , \"w\" : 20 , \"h\" : 244 , \"min\" : 0 , \"max\" : 100 , \"val\" : 85 } { \"page\" : 6 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE425\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 60 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE457\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 111 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE49E\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 163 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE57E\" , \"text_font\" : 32 } 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 - obj : \"p6b12\" # artist label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_artist') if state_attr('media_player.sound_my_room1','media_artist') else '-' }}\" - obj : \"p6b13\" # title label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_title') if state_attr('media_player.sound_my_room1','media_title') else '-' }}\" - obj : \"p6b15\" # sources list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','source_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{\"(no source)\\n\"|e}} {%- for source in state_attr('media_player.sound_my_room1','source_list') -%} {{source+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %} {% if state_attr('media_player.sound_my_room1','source') == None %}0{% else %} {%for source in state_attr('media_player.sound_my_room1','source_list')%} {{loop.index if source == state_attr('media_player.sound_my_room1','source') }} {%-endfor%}{%-endif %}{%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_source data : entity_id : media_player.sound_my_room1 source : \"{{ text }}\" - obj : \"p6b16\" # sound modes list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','sound_mode_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {%-for soundmode in state_attr('media_player.sound_my_room1','sound_mode_list')-%} {{soundmode+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %}{%for source in state_attr('media_player.sound_my_room1','sound_mode_list')%} {{loop.index -1 if source == state_attr('media_player.sound_my_room1','sound_mode') }} {%-endfor%}{% endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_sound_mode data : entity_id : media_player.sound_my_room1 sound_mode : \"{{ text }}\" - obj : \"p6b14\" # progressbar properties : \"max\" : \"{{ state_attr('media_player.sound_my_room1','media_duration') | int }}\" \"val\" : \"{{ state_attr('media_player.sound_my_room1','media_position') | int }}\" - obj : \"p6b18\" # play/pause/stop properties : \"text\" : > {% if is_state('media_player.sound_my_room1', 'playing') %} {{ \"\\uE3E4\" | e }} {%-else %} {{ \"\\uE40A\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_play_pause target : entity_id : media_player.sound_my_room1 \"long\" : - service : media_player.media_stop target : entity_id : media_player.sound_my_room1 - obj : \"p6b17\" # prev properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_previous_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b19\" # next properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_next_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b20\" # volume slider properties : \"val\" : > {% if (state_attr('media_player.sound_my_room1','volume_level') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{ state_attr('media_player.sound_my_room1','volume_level') * 100 | int(default=80) }} {%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" \"up\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" - obj : \"p6b21\" # power properties : \"text_color\" : \"{{ '#B00000' if states('media_player.sound_my_room1') == 'off' else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.toggle data : entity_id : media_player.sound_my_room1 - obj : \"p6b22\" # repeat properties : \"text\" : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} {{ \"\\uE458\" | e }} {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} {{ \"\\uE456\" | e }} {%-else %} {{ \"\\uE457\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.repeat_set data : entity_id : media_player.sound_my_room1 repeat : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} all {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} off {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'off') %} one {%-endif %} - obj : \"p6b23\" # shuffle properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} {{ \"\\uE49D\" | e }} {%-else %} {{ \"\\uE49E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.shuffle_set data : entity_id : media_player.sound_my_room1 shuffle : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} false {% else %} true {%-endif %} - obj : \"p6b24\" # mute properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} {{ \"\\uE75F\" | e }} {%-else %} {{ \"\\uE57E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.volume_mute data : entity_id : media_player.sound_my_room1 is_volume_muted : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} false {% else %} true {%-endif %} Note that the 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.","title":"Media player"},{"location":"integrations/home-assistant/sampl_conf/#generic-thermostatclimate","text":"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. Your browser does not support the video tag. relevant openHASP config: (screen size 240x320) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 20 , \"obj\" : \"arc\" , \"x\" : 5 , \"y\" : 37 , \"w\" : 230 , \"h\" : 230 , \"min\" : 170 , \"max\" : 300 , \"val\" : 250 , \"border_side\" : 0 , \"type\" : 0 , \"rotation\" : 0 , \"start_angle\" : 135 , \"end_angle\" : 45 , \"adjustable\" : \"true\" , \"line_width\" : 21 , \"line_width10\" : 21 , \"line_color10\" : \"#34bdeb\" , \"bg_opa\" : 0 , \"pad_top20\" : 5 , \"pad_bottom20\" : 5 , \"pad_left20\" : 5 , \"pad_right20\" : 5 , \"pad_top\" : 5 , \"pad_bottom\" : 5 , \"pad_left\" : 5 , \"pad_right\" : 5 } { \"page\" : 3 , \"id\" : 21 , \"obj\" : \"gauge\" , \"x\" : 28 , \"y\" : 28 , \"w\" : 175 , \"h\" : 175 , \"parentid\" : 20 , \"min\" : 170 , \"max\" : 300 , \"val\" : 224 , \"format\" : 1 , \"critical_value\" : 301 , \"label_count\" : 14 , \"line_count\" : 27 , \"border_width\" : 0 , \"pad_top\" : 2 , \"pad_bottom\" : 2 , \"pad_left\" : 2 , \"pad_right\" : 2 , \"value_str\" : \"\u00b0C\" , \"value_ofs_y\" : 55 , \"value_font\" : 16 , \"bg_opa\" : 0 , \"line_width10\" : 3 , \"line_rounded10\" : 1 , \"line_color\" : \"#348feb\" , \"line_color60\" : \"#348feb\" , \"scale_grad_color\" : \"#eb4934\" , \"scale_grad_color60\" : \"#eb4934\" , \"scale_end_color60\" : \"#eb4934\" } { \"page\" : 3 , \"id\" : 22 , \"obj\" : \"obj\" , \"x\" : 85 , \"y\" : 85 , \"w\" : 60 , \"h\" : 60 , \"parentid\" : 20 , \"click\" : 0 , \"radius\" : 30 , \"border_width\" : 2 , \"border_opa\" : 200 } { \"page\" : 3 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 80 , \"y\" : 100 , \"w\" : 70 , \"h\" : 30 , \"parentid\" : 20 , \"text\" : \"22.4\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 24 , \"obj\" : \"obj\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"click\" : 0 , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 25 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"25\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 26 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 220 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" , \"border_width\" : 0 } { \"page\" : 3 , \"id\" : 30 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 235 , \"w\" : 240 , \"h\" : 80 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 , \"radius\" : 0 } { \"page\" : 3 , \"id\" : 31 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 32 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 33 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 41 , \"obj\" : \"switch\" , \"x\" : 35 , \"y\" : 10 , \"w\" : 60 , \"h\" : 30 , \"parentid\" : 31 , \"radius\" : 25 , \"radius20\" : 25 } { \"page\" : 3 , \"id\" : 42 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 32 , \"options\" : \"fan_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 43 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 33 , \"options\" : \"hvac_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } 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 - obj : \"p3b20\" # arc slider properties : \"val\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') | int * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"line_color1\" : > {% if is_state('climate.thermostat_1', 'cool') %} {{ \"#346beb\" }} {%-elif is_state('climate.thermostat_1', 'heat_cool') %} {{ \"#34bdeb\" }} {%-elif is_state('climate.thermostat_1', 'heat') %} {{ \"#eb3434\" }} {%-elif is_state('climate.thermostat_1', 'dry') %} {{ \"#ebeb34\" }} {%-elif is_state('climate.thermostat_1', 'fan_only') %} {{ \"#34eb77\" }} {%-else %} {{ \"#9f96b0\" }} {% endif %} event : \"changed\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" - obj : \"p3b21\" # gauge current temp properties : \"val\" : > {% if not (is_state('sensor.ble_atlaghomerseklet','unavailable') or is_state('sensor.ble_atlaghomerseklet','unknown')) %} {{ states('sensor.ble_atlaghomerseklet') | float (default=0) * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"critical_value\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 + 1 }} {%- endif %} \"label_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int + 1 }} {%- endif %} \"line_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ (state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int) * 2 + 1 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b23\" # label current temp (and +/- with short/long touch) properties : \"text\" : > {% if (is_state('sensor.temp_room_1','unavailable') or is_state('sensor.temp_room_1','unknown')) %} {{ \"--.-\" }} {%-else %} {{ states('sensor.temp_room_1') | round(1,default=0) }} {%- endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') + state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" \"long\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') - state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" - obj : \"p3b25\" # label target temp properties : \"text\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b41\" # on/off switch properties : \"val\" : \"{{ 0 if (is_state('climate.thermostat_1', 'off') or is_state('climate.thermostat_1', 'unavailable')) else 1 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"down\" : - service_template : > {% if val == 0 -%} climate.turn_on {% else -%} climate.turn_off {% endif -%} entity_id : \"climate.thermostat_1\" - obj : \"p3b30\" # tab dots event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p3b26.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 2 %} {{ \"#909090 \\u2022# #909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p3b42\" # dropdown with fan_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','fan_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {%- if mode == 'auto' -%} Automatic{{\"\\n\"|e}} {%- elif mode == 'low' -%} Low{{\"\\n\"|e}} {%- elif mode == 'medium' -%} Medium{{\"\\n\"|e}} {%- elif mode == 'high' -%} High{{\"\\n\"|e}} {%- elif mode == 'turbo' -%} Turbo{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {{loop.index -1 if mode == state_attr('climate.thermostat_1','fan_mode') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_fan_mode target : entity_id : climate.thermostat_1 data : fan_mode : > {% if text == \"Automatic\" -%} auto {% elif text == 'Low' -%} low {% elif text == 'Medium' -%} medium {% elif text == 'High' -%} high {% elif text == 'Turbo' -%} turbo {% endif -%} - obj : \"p3b43\" # dropdown with hvac_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','hvac_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {%- if mode == 'off' -%} Off{{\"\\n\"|e}} {%- elif mode == 'heat' -%} Heating{{\"\\n\"|e}} {%- elif mode == 'cool' -%} Cooling{{\"\\n\"|e}} {%- elif mode == 'heat_cool' -%} Heat/Cool{{\"\\n\"|e}} {%- elif mode == 'dry' -%} Drying{{\"\\n\"|e}} {%- elif mode == 'fan_only' -%} Fan only{{\"\\n\"|e}} {%- else -%} On{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {{loop.index -1 if mode == states('climate.thermostat_1') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_hvac_mode target : entity_id : climate.thermostat_1 data : hvac_mode : > {% if text == \"Off\" -%} off {% elif text == 'Heating' -%} heat {% elif text == 'Cooling' -%} cool {% elif text == 'Heat/Cool' -%} heat_cool {% elif text == 'Drying' -%} dry {% elif text == 'Fan only' -%} fan_only {% endif -%}","title":"Generic thermostat/climate"},{"location":"integrations/home-assistant/sampl_conf/#current-weather-and-forecasts","text":"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 {target= blank} (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: light theme dark theme 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 { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"WEATHER\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"img\" , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 2 , \"auto_size\" : 1 , \"w\" : 128 , \"offset_x\" : -6 , \"offset_y\" : -10 } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"label\" , \"x\" : 100 , \"y\" : 10 , \"w\" : 130 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"date current\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 34 , \"w\" : 95 , \"h\" : 40 , \"align\" : \"center\" , \"text\" : \"00.0\u00b0C\" , \"parentid\" : 2 , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 17 , \"obj\" : \"label\" , \"x\" : 110 , \"y\" : 78 , \"w\" : 120 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"condition\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 19 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 95 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#000000 \\u2022# #909090 \\u2022#\" , \"parentid\" : 2 , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" } { \"page\" : 5 , \"id\" : 10 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 260 , \"parentid\" : 2 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 21 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 123 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+2\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 123 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 31 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 154 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+3\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 32 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 154 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 33 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 41 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 186 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+4\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 42 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 186 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 43 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 51 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 218 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+5\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 52 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 218 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 53 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 61 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 123 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+1\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 62 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 63 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 64 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 71 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 154 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+2\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 72 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 73 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 74 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 81 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 186 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+3\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 82 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 83 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 84 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 91 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 218 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+4\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 92 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 93 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 94 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } 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 - obj : \"p5b14\" # Icon properties : \"src\" : \"{{ 'L:/w-128-' + states('weather.openweathermap') + '.png' if not is_state('weather.openweathermap','unavailable') }}\" - obj : \"p5b15\" # Current date (adjust format to your needs) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set day = (states.weather.openweathermap.last_changed).strftime('%w') %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{- days[ day | int -1 ] }} {{ (states.weather.openweathermap.last_changed).strftime('%m. %d. ') }} {% endif -%} - obj : \"p5b16\" # Current temp (you can use your own outdoor temp sensor if you have one) properties : \"text\" : \"{{ state_attr('weather.openweathermap','temperature') |string + '\u00b0C' if not is_state('weather.openweathermap','unavailable') }}\" # or \"{{ states('sensor.your_own_temp_sensor') if not is_state('sensor.your_own_temp_sensor','unavailable') else '--' }}\u00b0C\" - obj : \"p5b17\" # Current weather condition properties : \"text\" : > {% if is_state('weather.openweathermap','clear-night') -%} Clear night {% elif is_state('weather.openweathermap','cloudy') -%} Cloudy {% elif is_state('weather.openweathermap','fog') -%} Fog {% elif is_state('weather.openweathermap','hail') -%} Hail {% elif is_state('weather.openweathermap','lightning') -%} Lightning {% elif is_state('weather.openweathermap','lightning-rainy') -%} Thunderstorms {% elif is_state('weather.openweathermap','partlycloudy') -%} Partly cloudy {% elif is_state('weather.openweathermap','pouring') -%} Pouring rain {% elif is_state('weather.openweathermap','rainy') -%} Rainy {% elif is_state('weather.openweathermap','snowy') -%} Snowy {% elif is_state('weather.openweathermap','snowy-rainy') -%} Snowy-rainy {% elif is_state('weather.openweathermap','sunny') -%} Sunny {% elif is_state('weather.openweathermap','windy') -%} Windy {% elif is_state('weather.openweathermap','windy-variant') -%} Windy {% elif is_state('weather.openweathermap','exceptional') -%} Exceptional {% elif is_state('weather.openweathermap','unavailable') -%} (not available) {% else -%} {{ states('weather.openweathermap') }} {% endif -%} - obj : \"p5b10\" # tab dots - MAKE SURE YOU UPDATE THIS ONE!! event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p5b19.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p5b21\" # Forecast time +1h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b22\" # Forecast temp +1h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[1]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b23\" # Forecast condition +1h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b31\" # Forecast time +2h (using Dawn/Morn etc instead of Today/Tomorrow) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set hour = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) | timestamp_custom(\"%-H\") | int %} {%- if 4 <= hour < 6 %} Dawning {%- elif 6 <= hour < 9 %} Morning {%- elif 9 <= hour < 12 %} Forenoon {%- elif 12 <= hour < 18 %} Afternoon {%- elif 18 <= hour < 23 %} Evening {%- elif 23 <= hour or hour < 4 %} Night {%- endif %} {{- \" \" + hour |string + \" o'clock\" }} {%- endif %} - obj : \"p5b32\" # Forecast temp +2h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[3]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b33\" # Forecast condition +2h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[3]['condition'] }}.png {%- endif %} - obj : \"p5b41\" # Forecast time +4h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[6]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b42\" # Forecast temp +4h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[6]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b43\" # Forecast condition +4h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[6]['condition'] }}.png {%- endif %} - obj : \"p5b51\" # Forecast time +8h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[12]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b52\" # Forecast temp +8h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[12]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b53\" # Forecast condition +8h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[12]['condition'] }}.png {%- endif %} - obj : \"p5b61\" # Forecast date +1d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[0]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b62\" # Forecast temp min +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b63\" # Forecast temp max +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b64\" # Forecast condition +1d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[0]['condition'] }}.png {%- endif %} - obj : \"p5b71\" # Forecast date +2d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b72\" # Forecast temp min +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b73\" # Forecast temp max +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b74\" # Forecast condition +2d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b81\" # Forecast date +3d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[2]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b82\" # Forecast temp min +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b83\" # Forecast temp max +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b84\" # Forecast condition +3d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[2]['condition'] }}.png {%- endif %} - obj : \"p5b91\" # Forecast date +4d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b92\" # Forecast temp min +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b93\" # Forecast temp max +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b94\" # Forecast condition +4d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[3]['condition'] }}.png {%- endif %} Attribution Icons are copyright from manifestinteractive and merlinthered .","title":"Current weather and forecasts"},{"location":"integrations/home-assistant/sampl_conf/#fan-and-scent-diffuser","text":"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. fan perfume 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_width10\" : 19 , \"line_color10\" : \"#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 state_attr(\"input_select.fan_presets\",\"options\") is not none -%} {% 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 states('input_select.fan_presets') in ['unavailable', 'unknown', 'OFF'] else 255 }}\" \"jsonl\" : > {% if is_state('number.plate_test_page_number', '4') %} {% if is_state('input_select.fan_presets', 'Alap') %} {\"speed\":7000,\"line_color10\":\"#31de70\"} {%-elif is_state('input_select.fan_presets', 'K\u00f6z\u00e9p') %} {\"speed\":1700,\"line_color10\":\"#dede1f\"} {%-elif is_state('input_select.fan_presets', 'Magas') %} {\"speed\":800,\"line_color10\":\"#d6a11a\"} {%-elif is_state('input_select.fan_presets', 'Turb\u00f3') %} {\"speed\":250,\"line_color10\":\"#ff4a4a\"} {% endif %} {% else -%} {\"speed\":0} {% endif %} - obj : \"p4b54\" # Scent Diffuser ON/OFF button properties : \"val\" : '{{ 1 if is_state(\"fan.scent_diffuser_intensity\", \"on\") else 0 }}' \"enabled\" : \"{{ 'false' if states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 .","title":"Fan and scent diffuser"},{"location":"integrations/home-assistant/sampl_conf/#using-tags","text":"You can avoid too much code repetition when you have multiple similar objects on a page, doing the same thing with different entities, and you'd like to make accessible some advanced options too. Presenting everyting flat will overwhelm your user interface, so it would be better to just show the most used controls, and only display the advanced options in popups related to unique objects. Tag property was made to ease this task.","title":"Using tags"},{"location":"integrations/home-assistant/sampl_conf/#colored-lights-panel","text":"In the example below we have four coloured lights. Squeezing the ON/OFF button, the color picker and the brightness selector for all four lights on a single page can be challenging - and the result will likely be useless on a small touch screen. Instead, we'll just place the toggle buttons with descriptive labels on the page, and we'll only display the color picker and the brightness selector on demand, in this case when the user touches the descriptive coloured label. While dynamically drawing these objects we're setting the tag property for the color picker and the slider to the entity_id of the light we want to adjust, so that when we're interacting with them, the Custom Component can know which light it has to send the adjustments to. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"COLOURED LIGHTS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"I.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"II.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"III.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"IV.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p5b11\" # toggle button for ON/OFF switching of light I. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_1\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_1\" - obj : \"p5b12\" # toggle button for ON/OFF switching of light II. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_2\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_2\" - obj : \"p5b13\" # toggle button for ON/OFF switching of light III. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_3\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_3\" - obj : \"p5b14\" # toggle button for ON/OFF switching of light IV. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_4\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_4\" - obj : \"p5b2\" # label showing the current color of light I. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_1','on') %} {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_1 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light I. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light I.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_1\",\"color\": {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_1\",\"val\": {{- state_attr('light.dmx_vbar_1', 'brightness') -}} } - obj : \"p5b3\" # label showing the current color of light II. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_2','on') %} {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_2 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light II. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light II.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_2\",\"color\": {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_2\",\"val\": {{- state_attr('light.dmx_vbar_2', 'brightness') -}} } - obj : \"p5b4\" # label showing the current color of light III. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_3','on') %} {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_3 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light III. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light III.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_3\",\"color\": {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_3\",\"val\": {{- state_attr('light.dmx_vbar_3', 'brightness') -}} } - obj : \"p5b5\" # label showing the current color of light IV. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_4','on') %} {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_4 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light IV. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light IV.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_4\",\"color\": {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_4\",\"val\": {{- state_attr('light.dmx_vbar_4', 'brightness') -}} } - obj : \"p5b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b201\" # set the color of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b202\" # set the brightness of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" brightness : \"{{ val }}\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete Without tags, the last 3 object definitions would have to be added for each light, and also it would be needed to be drawn separately for each light, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design.","title":"Colored lights panel"},{"location":"integrations/home-assistant/sampl_conf/#shutter-control-panel","text":"In the second example, we have five windows with motorized shutters. In addition to the usual UP/STOP/DOWN buttons, the inhabitants want to have three shortcut positions for each shutter, and also a slider for free positioning. Useless to say that it's impossible to put all these on a page, and also it would be a pity to use up 5 pages just for these. We'll just put the most used, UP/STOP/DOWN buttons on the page (this already looks a bit much...) and we'll use a long press event on the middle STOP button to show a pop-up with the extra required settings related to the desired shutter. The tag here will be a JSON object referencing both the entity_id and the position specific to the desired shutter, eg. \"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"} , this will be set for the buttons and the slider appearing in the popup. Since the shutters are different sizes and types, the same intermediate physical position may correspond to different numeric values in Home Assistant. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 2 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"MOTORIZED COVERS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 2 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 7 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"I.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 53 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"II.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 99 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"III.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"IV.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 191 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"V.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 31 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 32 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 33 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 41 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 42 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 43 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 51 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 52 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 53 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p2b11\" # shutter I. up button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b13\" # shutter I. down button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b12\" # shutter I. middle stop button properties : \"text\" : > {% if is_state('cover.bigroom_i', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_i', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_i\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - I.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"54\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_i','current_position') -}} } - obj : \"p2b21\" # shutter II. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b23\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b22\" properties : \"text\" : > {% if is_state('cover.bigroom_ii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_ii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_ii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - II.\",\"align\":\"center\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"18\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_ii','current_position') -}} } - obj : \"p2b31\" # shutter III. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b33\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b32\" properties : \"text\" : > {% if is_state('cover.bigroom_iii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - III.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iii','current_position') -}} } - obj : \"p2b41\" # shutter IV. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b43\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b42\" properties : \"text\" : > {% if is_state('cover.bigroom_iv', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iv', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iv\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - IV.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iv','current_position') -}} } - obj : \"p2b51\" # shutter V. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b53\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b52\" properties : \"text\" : > {% if is_state('cover.bigroom_v', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_v', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_v\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - V.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"55\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"19\"},\"val\": {{- state_attr('cover.bigroom_v','current_position') -}} } - obj : \"p2b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b201\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b202\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b203\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b204\" # set the shutter position from the slider for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"up\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ val | int }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete Again - without tags, the last 5 object definitions would have to be added for each shutter, and also it would be needed to be drawn separately for each one, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. 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.","title":"Shutter control panel"},{"location":"integrations/node-red/","text":"Node-RED ~ You can integrate an openHASP plate in Node-RED by subscribing and publishing to its MQTT topics. The following is an example of how to use Node-RED to read PIN numbers from an alarm button matrix on page 12, and display those numbers back to the screen on p12b2. First we define p12b1 as the matrix, and p12b2 as the area where to re-display the PIN. Add the following to pages_online.jsonl { \"comment\" : \" ----------- Page 12 layout ------------\" } { \"page\" : 12 , \"id\" : 1 , \"obj\" : \"btnmatrix\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 220 , \"h\" : 220 , \"options\" :[ \"1\" , \"2\" , \"3\" , \"\\n\" , \"4\" , \"5\" , \"6\" , \"\\n\" , \"7\" , \"8\" , \"9\" , \"\\n\" , \"Home\" , \"0\" , \"Away\" ], \"toggle\" : false , \"one_check\" : false } { \"page\" : 12 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 104 , \"y\" : 22 , \"h\" : 30 , \"w\" : 40 , \"text\" : \" \" , \"text_color\" : \"white\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } The following jsonl is for 13 Lanbon L8 panels and can be imported [ { \"id\" : \"0b80aa53cbe8e6e2\" , \"type\" : \"tab\" , \"label\" : \"Lanbon Security Panel\" , \"disabled\" : false , \"info\" : \"\" , \"env\" : [] }, { \"id\" : \"e7faec55927cd35a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/livingroom/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 80 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"99cabcc7d52bfc9b\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"active\" : true , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"payload\" , \"targetType\" : \"msg\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 1290 , \"y\" : 200 , \"wires\" : [] }, { \"id\" : \"ac7b661dc1513061\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MakeNums\" , \"rules\" : [ { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":0,\\\"text\\\":\\\"1\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"1\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":1,\\\"text\\\":\\\"2\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"2\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":2,\\\"text\\\":\\\"3\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"3\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":3,\\\"text\\\":\\\"4\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"4\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":4,\\\"text\\\":\\\"5\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"5\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":5,\\\"text\\\":\\\"6\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"6\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":6,\\\"text\\\":\\\"7\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"7\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":7,\\\"text\\\":\\\"8\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"8\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":8,\\\"text\\\":\\\"9\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"9\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":10,\\\"text\\\":\\\"0\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"0\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 450 , \"y\" : 160 , \"wires\" : [ [ \"9739abb6f93766f6\" ] ] }, { \"id\" : \"d23a2c349910face\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"BuildPIN\" , \"func\" : \"var pin=global.get('pin') || \\\"\\\";\\n\\nvar count=global.get('count') || 0;\\ncount +=1;\\nglobal.set('count',count)\\n\\npin = pin+msg.payload;\\nglobal.set('pin',pin)\\n\\n\\nif (count >= 4) {\\n msg.payload=pin;\\n global.set('count',undefined)\\n global.set('pin',undefined)\\n return msg;\\n}\\n\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 680 , \"y\" : 180 , \"wires\" : [ [ \"194eed57a4506f13\" , \"eaa539f1f670e8ea\" , \"978adaf5813fc4c9\" , \"421fb70f969f4c42\" , \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"8ac3fdee648284fe\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"OnDown\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"cont\" , \"v\" : \"{\\\"event\\\":\\\"down\\\"\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 1 , \"x\" : 420 , \"y\" : 80 , \"wires\" : [ [ \"5249d096ebe1aab7\" , \"ac7b661dc1513061\" ] ] }, { \"id\" : \"978adaf5813fc4c9\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Disarm Alarm\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_disarm\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":msg.payload}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 920 , \"y\" : 200 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"8b34728627566066\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mainhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 140 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"da5ff263f7265cee\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/ensuite/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 200 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"16c2241ebfe6d928\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mbr/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 160 , \"y\" : 260 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9152a3b91fa4ce8a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/porch/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 320 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"df2df457211af7fa\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/dining/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 380 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"ef006a2ad5f4033f\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 440 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"6dc9dabe1edb7af5\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/kitchen/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 500 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"fb8196aa68104765\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/garage/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 560 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"a416144df4052b42\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 620 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9305a215bd8a3a87\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishMood\" , \"topic\" : \"hasp/plates/command\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 40 , \"wires\" : [] }, { \"id\" : \"5249d096ebe1aab7\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"White\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 255, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 650 , \"y\" : 40 , \"wires\" : [ [ \"1c99afe47fe6da11\" , \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"3a59fcd31e572bb0\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 810 , \"y\" : 80 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"197cb8bad0ea98a3\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmAway\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_away\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 320 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"eaa539f1f670e8ea\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Purple\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 0, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 950 , \"y\" : 380 , \"wires\" : [ [ \"9305a215bd8a3a87\" , \"cae42e223294ce38\" ] ] }, { \"id\" : \"194eed57a4506f13\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Reset\" , \"func\" : \" global.set('count',undefined)\\n global.set('pin',undefined)\\n msg.payload = \\\"\\\"\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 670 , \"y\" : 240 , \"wires\" : [ [ \"421fb70f969f4c42\" ] ] }, { \"id\" : \"9739abb6f93766f6\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"0-9HomeAway\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"btwn\" , \"v\" : \"0\" , \"vt\" : \"num\" , \"v2\" : \"9\" , \"v2t\" : \"num\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":9,\\\"text\\\":\\\"Home\\\"}\" , \"vt\" : \"str\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":11,\\\"text\\\":\\\"Away\\\"}\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 3 , \"x\" : 440 , \"y\" : 240 , \"wires\" : [ [ \"d23a2c349910face\" , \"f9f85bc88ea6f404\" ], [ \"194eed57a4506f13\" ], [ \"194eed57a4506f13\" , \"c861944aac699e3e\" , \"206a424a07c9fb22\" ] ] }, { \"id\" : \"11dad534fd1a944e\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1010 , \"y\" : 440 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"cae42e223294ce38\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"1\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 880 , \"y\" : 440 , \"wires\" : [ [ \"11dad534fd1a944e\" ] ] }, { \"id\" : \"4b8a2bd06dcf1342\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishPIN\" , \"topic\" : \"hasp/plates/command/p12b2.text\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 120 , \"wires\" : [] }, { \"id\" : \"f9f85bc88ea6f404\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"DisplayPIN\" , \"func\" : \"var pin=global.get('pin')\\n// pin = pin+msg.payload;\\nmsg.payload = pin;\\nreturn msg;\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 690 , \"y\" : 140 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"149782424f319147\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"****\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 500 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" , \"88031b2f0bea8fef\" ] ] }, { \"id\" : \"421fb70f969f4c42\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 500 , \"wires\" : [ [ \"149782424f319147\" ] ] }, { \"id\" : \"88031b2f0bea8fef\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 560 , \"wires\" : [ [ \"bf47160c100015ca\" ] ] }, { \"id\" : \"bf47160c100015ca\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \" \" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 560 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"c861944aac699e3e\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"15\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 300 , \"wires\" : [ [ \"371b17d0dd9918dc\" , \"24f9431e18e5d5f2\" ] ] }, { \"id\" : \"1c99afe47fe6da11\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"300\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 670 , \"y\" : 80 , \"wires\" : [ [ \"3a59fcd31e572bb0\" ] ] }, { \"id\" : \"206a424a07c9fb22\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"30 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"Alarm will arm away in 30 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 300 , \"wires\" : [ [] ] }, { \"id\" : \"24f9431e18e5d5f2\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"15 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"15 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 360 , \"wires\" : [ [] ] }, { \"id\" : \"371b17d0dd9918dc\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"10\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 360 , \"wires\" : [ [ \"b8098924ec49405c\" , \"56b96ab40a26daeb\" ] ] }, { \"id\" : \"b8098924ec49405c\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"5\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 420 , \"wires\" : [ [ \"197cb8bad0ea98a3\" ] ] }, { \"id\" : \"56b96ab40a26daeb\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"5 Secs\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"5 Seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 420 , \"wires\" : [ [] ] }, { \"id\" : \"0b8f9dbd664953e2\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmHome\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_home\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 260 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"0bf633ce2d98dd79\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/upbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 680 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"e3bf26032c55a701\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"debug 1\" , \"active\" : false , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"false\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 640 , \"y\" : 580 , \"wires\" : [] }, { \"id\" : \"9a8d3eea339efbdc\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/allys_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 740 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"7aac330a4bb67fe8\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/victorias_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 130 , \"y\" : 800 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"441d674c9c4a7f07\" , \"type\" : \"mqtt-broker\" , \"name\" : \"192.168.0.21\" , \"broker\" : \"192.168.0.21\" , \"port\" : \"1883\" , \"clientid\" : \"\" , \"autoConnect\" : true , \"usetls\" : false , \"protocolVersion\" : \"4\" , \"keepalive\" : \"60\" , \"cleansession\" : true , \"birthTopic\" : \"\" , \"birthQos\" : \"0\" , \"birthPayload\" : \"\" , \"birthMsg\" : {}, \"closeTopic\" : \"\" , \"closeQos\" : \"0\" , \"closePayload\" : \"\" , \"closeMsg\" : {}, \"willTopic\" : \"\" , \"willQos\" : \"0\" , \"willPayload\" : \"\" , \"willMsg\" : {}, \"sessionExpiry\" : \"\" }, { \"id\" : \"669eed80.4f9844\" , \"type\" : \"server\" , \"name\" : \"Home Assistant\" , \"version\" : 5 , \"addon\" : true , \"rejectUnauthorizedCerts\" : true , \"ha_boolean\" : \"y|yes|true|on|home|open\" , \"connectionDelay\" : false , \"cacheJson\" : false , \"heartbeat\" : false , \"heartbeatInterval\" : 30 , \"areaSelector\" : \"friendlyName\" , \"deviceSelector\" : \"friendlyName\" , \"entitySelector\" : \"friendlyName\" , \"statusSeparator\" : \"at: \" , \"statusYear\" : \"hidden\" , \"statusMonth\" : \"short\" , \"statusDay\" : \"numeric\" , \"statusHourCycle\" : \"h23\" , \"statusTimeFormat\" : \"h:m\" , \"enableGlobalContextStore\" : true } ]","title":"Node-RED"},{"location":"integrations/node-red/#node-red","text":"You can integrate an openHASP plate in Node-RED by subscribing and publishing to its MQTT topics. The following is an example of how to use Node-RED to read PIN numbers from an alarm button matrix on page 12, and display those numbers back to the screen on p12b2. First we define p12b1 as the matrix, and p12b2 as the area where to re-display the PIN. Add the following to pages_online.jsonl { \"comment\" : \" ----------- Page 12 layout ------------\" } { \"page\" : 12 , \"id\" : 1 , \"obj\" : \"btnmatrix\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 220 , \"h\" : 220 , \"options\" :[ \"1\" , \"2\" , \"3\" , \"\\n\" , \"4\" , \"5\" , \"6\" , \"\\n\" , \"7\" , \"8\" , \"9\" , \"\\n\" , \"Home\" , \"0\" , \"Away\" ], \"toggle\" : false , \"one_check\" : false } { \"page\" : 12 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 104 , \"y\" : 22 , \"h\" : 30 , \"w\" : 40 , \"text\" : \" \" , \"text_color\" : \"white\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } The following jsonl is for 13 Lanbon L8 panels and can be imported [ { \"id\" : \"0b80aa53cbe8e6e2\" , \"type\" : \"tab\" , \"label\" : \"Lanbon Security Panel\" , \"disabled\" : false , \"info\" : \"\" , \"env\" : [] }, { \"id\" : \"e7faec55927cd35a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/livingroom/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 80 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"99cabcc7d52bfc9b\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"active\" : true , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"payload\" , \"targetType\" : \"msg\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 1290 , \"y\" : 200 , \"wires\" : [] }, { \"id\" : \"ac7b661dc1513061\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MakeNums\" , \"rules\" : [ { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":0,\\\"text\\\":\\\"1\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"1\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":1,\\\"text\\\":\\\"2\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"2\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":2,\\\"text\\\":\\\"3\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"3\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":3,\\\"text\\\":\\\"4\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"4\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":4,\\\"text\\\":\\\"5\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"5\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":5,\\\"text\\\":\\\"6\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"6\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":6,\\\"text\\\":\\\"7\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"7\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":7,\\\"text\\\":\\\"8\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"8\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":8,\\\"text\\\":\\\"9\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"9\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":10,\\\"text\\\":\\\"0\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"0\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 450 , \"y\" : 160 , \"wires\" : [ [ \"9739abb6f93766f6\" ] ] }, { \"id\" : \"d23a2c349910face\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"BuildPIN\" , \"func\" : \"var pin=global.get('pin') || \\\"\\\";\\n\\nvar count=global.get('count') || 0;\\ncount +=1;\\nglobal.set('count',count)\\n\\npin = pin+msg.payload;\\nglobal.set('pin',pin)\\n\\n\\nif (count >= 4) {\\n msg.payload=pin;\\n global.set('count',undefined)\\n global.set('pin',undefined)\\n return msg;\\n}\\n\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 680 , \"y\" : 180 , \"wires\" : [ [ \"194eed57a4506f13\" , \"eaa539f1f670e8ea\" , \"978adaf5813fc4c9\" , \"421fb70f969f4c42\" , \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"8ac3fdee648284fe\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"OnDown\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"cont\" , \"v\" : \"{\\\"event\\\":\\\"down\\\"\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 1 , \"x\" : 420 , \"y\" : 80 , \"wires\" : [ [ \"5249d096ebe1aab7\" , \"ac7b661dc1513061\" ] ] }, { \"id\" : \"978adaf5813fc4c9\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Disarm Alarm\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_disarm\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":msg.payload}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 920 , \"y\" : 200 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"8b34728627566066\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mainhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 140 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"da5ff263f7265cee\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/ensuite/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 200 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"16c2241ebfe6d928\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mbr/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 160 , \"y\" : 260 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9152a3b91fa4ce8a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/porch/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 320 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"df2df457211af7fa\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/dining/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 380 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"ef006a2ad5f4033f\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 440 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"6dc9dabe1edb7af5\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/kitchen/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 500 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"fb8196aa68104765\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/garage/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 560 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"a416144df4052b42\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 620 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9305a215bd8a3a87\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishMood\" , \"topic\" : \"hasp/plates/command\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 40 , \"wires\" : [] }, { \"id\" : \"5249d096ebe1aab7\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"White\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 255, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 650 , \"y\" : 40 , \"wires\" : [ [ \"1c99afe47fe6da11\" , \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"3a59fcd31e572bb0\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 810 , \"y\" : 80 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"197cb8bad0ea98a3\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmAway\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_away\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 320 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"eaa539f1f670e8ea\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Purple\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 0, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 950 , \"y\" : 380 , \"wires\" : [ [ \"9305a215bd8a3a87\" , \"cae42e223294ce38\" ] ] }, { \"id\" : \"194eed57a4506f13\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Reset\" , \"func\" : \" global.set('count',undefined)\\n global.set('pin',undefined)\\n msg.payload = \\\"\\\"\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 670 , \"y\" : 240 , \"wires\" : [ [ \"421fb70f969f4c42\" ] ] }, { \"id\" : \"9739abb6f93766f6\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"0-9HomeAway\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"btwn\" , \"v\" : \"0\" , \"vt\" : \"num\" , \"v2\" : \"9\" , \"v2t\" : \"num\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":9,\\\"text\\\":\\\"Home\\\"}\" , \"vt\" : \"str\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":11,\\\"text\\\":\\\"Away\\\"}\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 3 , \"x\" : 440 , \"y\" : 240 , \"wires\" : [ [ \"d23a2c349910face\" , \"f9f85bc88ea6f404\" ], [ \"194eed57a4506f13\" ], [ \"194eed57a4506f13\" , \"c861944aac699e3e\" , \"206a424a07c9fb22\" ] ] }, { \"id\" : \"11dad534fd1a944e\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1010 , \"y\" : 440 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"cae42e223294ce38\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"1\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 880 , \"y\" : 440 , \"wires\" : [ [ \"11dad534fd1a944e\" ] ] }, { \"id\" : \"4b8a2bd06dcf1342\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishPIN\" , \"topic\" : \"hasp/plates/command/p12b2.text\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 120 , \"wires\" : [] }, { \"id\" : \"f9f85bc88ea6f404\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"DisplayPIN\" , \"func\" : \"var pin=global.get('pin')\\n// pin = pin+msg.payload;\\nmsg.payload = pin;\\nreturn msg;\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 690 , \"y\" : 140 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"149782424f319147\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"****\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 500 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" , \"88031b2f0bea8fef\" ] ] }, { \"id\" : \"421fb70f969f4c42\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 500 , \"wires\" : [ [ \"149782424f319147\" ] ] }, { \"id\" : \"88031b2f0bea8fef\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 560 , \"wires\" : [ [ \"bf47160c100015ca\" ] ] }, { \"id\" : \"bf47160c100015ca\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \" \" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 560 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"c861944aac699e3e\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"15\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 300 , \"wires\" : [ [ \"371b17d0dd9918dc\" , \"24f9431e18e5d5f2\" ] ] }, { \"id\" : \"1c99afe47fe6da11\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"300\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 670 , \"y\" : 80 , \"wires\" : [ [ \"3a59fcd31e572bb0\" ] ] }, { \"id\" : \"206a424a07c9fb22\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"30 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"Alarm will arm away in 30 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 300 , \"wires\" : [ [] ] }, { \"id\" : \"24f9431e18e5d5f2\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"15 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"15 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 360 , \"wires\" : [ [] ] }, { \"id\" : \"371b17d0dd9918dc\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"10\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 360 , \"wires\" : [ [ \"b8098924ec49405c\" , \"56b96ab40a26daeb\" ] ] }, { \"id\" : \"b8098924ec49405c\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"5\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 420 , \"wires\" : [ [ \"197cb8bad0ea98a3\" ] ] }, { \"id\" : \"56b96ab40a26daeb\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"5 Secs\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"5 Seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 420 , \"wires\" : [ [] ] }, { \"id\" : \"0b8f9dbd664953e2\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmHome\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_home\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 260 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"0bf633ce2d98dd79\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/upbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 680 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"e3bf26032c55a701\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"debug 1\" , \"active\" : false , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"false\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 640 , \"y\" : 580 , \"wires\" : [] }, { \"id\" : \"9a8d3eea339efbdc\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/allys_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 740 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"7aac330a4bb67fe8\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/victorias_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 130 , \"y\" : 800 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"441d674c9c4a7f07\" , \"type\" : \"mqtt-broker\" , \"name\" : \"192.168.0.21\" , \"broker\" : \"192.168.0.21\" , \"port\" : \"1883\" , \"clientid\" : \"\" , \"autoConnect\" : true , \"usetls\" : false , \"protocolVersion\" : \"4\" , \"keepalive\" : \"60\" , \"cleansession\" : true , \"birthTopic\" : \"\" , \"birthQos\" : \"0\" , \"birthPayload\" : \"\" , \"birthMsg\" : {}, \"closeTopic\" : \"\" , \"closeQos\" : \"0\" , \"closePayload\" : \"\" , \"closeMsg\" : {}, \"willTopic\" : \"\" , \"willQos\" : \"0\" , \"willPayload\" : \"\" , \"willMsg\" : {}, \"sessionExpiry\" : \"\" }, { \"id\" : \"669eed80.4f9844\" , \"type\" : \"server\" , \"name\" : \"Home Assistant\" , \"version\" : 5 , \"addon\" : true , \"rejectUnauthorizedCerts\" : true , \"ha_boolean\" : \"y|yes|true|on|home|open\" , \"connectionDelay\" : false , \"cacheJson\" : false , \"heartbeat\" : false , \"heartbeatInterval\" : 30 , \"areaSelector\" : \"friendlyName\" , \"deviceSelector\" : \"friendlyName\" , \"entitySelector\" : \"friendlyName\" , \"statusSeparator\" : \"at: \" , \"statusYear\" : \"hidden\" , \"statusMonth\" : \"short\" , \"statusDay\" : \"numeric\" , \"statusHourCycle\" : \"h23\" , \"statusTimeFormat\" : \"h:m\" , \"enableGlobalContextStore\" : true } ]","title":"Node-RED"},{"location":"integrations/openhab/integration_openhab/","text":"openHAB Integration ~ Page Layout ~ We call plate any device running openHASP in your system. Installation ~ The openHAB configuration files to have this demo load automatically can be found here . Update the IP-address for your MQTT-broker in the haspLVGL_demo.things file. Make sure you have your plate connected to the network and to your MQTT boker, and your topic is set to demo_plate . Code ~ To add an openHASP plate to your installation with Jaffa Sunrise sample configuration, upload a pages.jsonl file with the folowing content to your plate: in the plate's web UI select Mono UI theme and reboot, upload a pages.jsonl file with the folowing content to your plate and reboot: 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 { \"page\" : 1 , \"comment\" : \"---------- Page 1 ----------\" } { \"obj\" : \"btn\" , \"id\" : 4 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights On\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE6E8\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 5 , \"x\" : 5 , \"y\" : 68 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Daylight\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE599\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 6 , \"x\" : 5 , \"y\" : 131 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Night\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE594\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 7 , \"x\" : 5 , \"y\" : 194 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights Off\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE335\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"page\" : 2 , \"comment\" : \"---------- Page 2 ----------\" } { \"obj\" : \"label\" , \"id\" : 8 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Kitchen Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 9 , \"x\" : 5 , \"y\" : 80 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Dining Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 10 , \"x\" : 5 , \"y\" : 165 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Front Blinds\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"slider\" , \"id\" : 11 , \"x\" : 20 , \"y\" : 40 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 80 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 12 , \"x\" : 20 , \"y\" : 120 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 13 , \"x\" : 20 , \"y\" : 205 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 25 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"page\" : 3 , \"comment\" : \"---------- Page 3 ----------\" } { \"obj\" : \"label\" , \"id\" : 14 , \"x\" : 42 , \"y\" : 10 , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Gold\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 15 , \"x\" : 42 , \"y\" : 60 , \"mode\" : \"scroll\" , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Chet Faker\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 16 , \"x\" : 2 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AE\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 17 , \"x\" : 82 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE3E4\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 18 , \"x\" : 162 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AD\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"bar\" , \"id\" : 19 , \"x\" : 2 , \"y\" : 105 , \"w\" : 236 , \"h\" : 20 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 15 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" } { \"obj\" : \"slider\" , \"id\" : 20 , \"x\" : 35 , \"y\" : 220 , \"w\" : 170 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 30 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"label\" , \"id\" : 21 , \"x\" : 2 , \"y\" : 10 , \"w\" : 40 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75A\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 22 , \"x\" : 2 , \"y\" : 60 , \"w\" : 36 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE004\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 23 , \"x\" : 5 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75F\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 24 , \"x\" : 210 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE57E\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"page\" : 0 , \"comment\" : \"---------- All pages ----------\" } { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 5 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE04D\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 2 , \"x\" : 83 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE2DC\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 161 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE054\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } Restart the plate and the demo page should load automatically to your device.","title":"openHAB Integration"},{"location":"integrations/openhab/integration_openhab/#openhab-integration","text":"","title":"openHAB Integration"},{"location":"integrations/openhab/integration_openhab/#page-layout","text":"We call plate any device running openHASP in your system.","title":"Page Layout"},{"location":"integrations/openhab/integration_openhab/#installation","text":"The openHAB configuration files to have this demo load automatically can be found here . Update the IP-address for your MQTT-broker in the haspLVGL_demo.things file. Make sure you have your plate connected to the network and to your MQTT boker, and your topic is set to demo_plate .","title":"Installation"},{"location":"integrations/openhab/integration_openhab/#code","text":"To add an openHASP plate to your installation with Jaffa Sunrise sample configuration, upload a pages.jsonl file with the folowing content to your plate: in the plate's web UI select Mono UI theme and reboot, upload a pages.jsonl file with the folowing content to your plate and reboot: 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 { \"page\" : 1 , \"comment\" : \"---------- Page 1 ----------\" } { \"obj\" : \"btn\" , \"id\" : 4 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights On\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE6E8\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 5 , \"x\" : 5 , \"y\" : 68 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Daylight\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE599\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 6 , \"x\" : 5 , \"y\" : 131 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Night\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE594\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 7 , \"x\" : 5 , \"y\" : 194 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights Off\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE335\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"page\" : 2 , \"comment\" : \"---------- Page 2 ----------\" } { \"obj\" : \"label\" , \"id\" : 8 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Kitchen Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 9 , \"x\" : 5 , \"y\" : 80 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Dining Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 10 , \"x\" : 5 , \"y\" : 165 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Front Blinds\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"slider\" , \"id\" : 11 , \"x\" : 20 , \"y\" : 40 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 80 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 12 , \"x\" : 20 , \"y\" : 120 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 13 , \"x\" : 20 , \"y\" : 205 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 25 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"page\" : 3 , \"comment\" : \"---------- Page 3 ----------\" } { \"obj\" : \"label\" , \"id\" : 14 , \"x\" : 42 , \"y\" : 10 , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Gold\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 15 , \"x\" : 42 , \"y\" : 60 , \"mode\" : \"scroll\" , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Chet Faker\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 16 , \"x\" : 2 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AE\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 17 , \"x\" : 82 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE3E4\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 18 , \"x\" : 162 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AD\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"bar\" , \"id\" : 19 , \"x\" : 2 , \"y\" : 105 , \"w\" : 236 , \"h\" : 20 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 15 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" } { \"obj\" : \"slider\" , \"id\" : 20 , \"x\" : 35 , \"y\" : 220 , \"w\" : 170 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 30 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"label\" , \"id\" : 21 , \"x\" : 2 , \"y\" : 10 , \"w\" : 40 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75A\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 22 , \"x\" : 2 , \"y\" : 60 , \"w\" : 36 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE004\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 23 , \"x\" : 5 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75F\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 24 , \"x\" : 210 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE57E\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"page\" : 0 , \"comment\" : \"---------- All pages ----------\" } { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 5 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE04D\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 2 , \"x\" : 83 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE2DC\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 161 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE054\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } Restart the plate and the demo page should load automatically to your device.","title":"Code"}]}
\ No newline at end of file
+{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"openHASP Control your home-automation devices from a customizable touchscreen UI connected via MQTT. openHASP is a re-implementation of the popular HASwitchPlate sketch created by aderusha. The HASPone project uses a Wemos D1 mini and requires a Nextion/TJC HMI display. This project is a complete rewrite and implements the Light and Versatile Graphics Library on the MCU to drive a commodity display. openHASP uses an ESP32 to take advantage of the additional hardware capabilities. Demo Screens ~ Click on the demo screen to show the example configuration: Quotes ~ kazimir Hey man, openHASP is amazing. Currently running 12 pieces of Lanbon L8 plates in my house with your firmware. danielo Oh man, integrating this with Home Assistant was super easy. Lucky you can't see me getting hyped about turning on/off my office lights from a tinny screen (and doing it like 3 or 4 times on a row...) Support ~ For support using openHASP you can find us on Github, Discord or Home Assistant: Github Discussions Discord Chat Home Assistant Forum Donate ~ The firmware is opensource and free to use! If you like this project you can show your appreciation by making a small donation. This will help with ofssetting the cost of the different hardware devices we support.","title":"Overview"},{"location":"#demo-screens","text":"Click on the demo screen to show the example configuration:","title":"Demo Screens"},{"location":"#quotes","text":"kazimir Hey man, openHASP is amazing. Currently running 12 pieces of Lanbon L8 plates in my house with your firmware. danielo Oh man, integrating this with Home Assistant was super easy. Lucky you can't see me getting hyped about turning on/off my office lights from a tinny screen (and doing it like 3 or 4 times on a row...)","title":"Quotes"},{"location":"#support","text":"For support using openHASP you can find us on Github, Discord or Home Assistant: Github Discussions Discord Chat Home Assistant Forum","title":"Support"},{"location":"#donate","text":"The firmware is opensource and free to use! If you like this project you can show your appreciation by making a small donation. This will help with ofssetting the cost of the different hardware devices we support.","title":"Donate"},{"location":"commands/","text":"Commands are not related to an object on the screen but can get or set global properties or invoke system commands on the device. MQTT Topics ~ hasp/plate01/command/ is for sending commands to the screen hasp/plate01/state/ is for receiving updates from the screen So the topic depends on the direction of the data flow. Sending a message to topic hasp/plate01/command/p1b2.val with payload 25 would be a valid command. You can send a test MQTT message with a standalone program like MQTT Explorer or mosuito_pub. Issuing commands ~ Commands can be issued via the Serial commandline, telnet commandline or MQTT. For MQTT, you can use either: hasp//command topic with payload = hasp//command/ topic with payload Leave the payload empty to get the current state without changing it. Batch processing ~ Commands can be processed in batch one after another from .cmd script files located in the flash storage of the plate. General rules when creating .cmd batch scripts: can contain any command empty lines are ignored # or // can be used for comments space or tab in front of a command is ignored lines starting with { are processed as jsonl payloads lines starting with [ are processed as json payloads other lines are processed as CR , LF or CRLF line endings allowed UTF8 encoding is required for special characters To start a batch script, use run command. System scripts ~ If any of the following scripts is present on the filesystem, it will be run automatically according to the rules below: L:/boot.cmd is executed when the plate has finished (re)booting L:/online.cmd will be executed after connection to the network was successfull L:/offline.cmd will be executed after connection to the WiFi is lost This makes it possible to disable or hide buttons, load a special offline page, etc. See example . Global commands ~ run ~ accepted parameters: name of a .cmd or .jsonl file present on the flash filesystem of the plate. Filename must be preceeded by the / character Run a batch script or load a jsonl page. Example run /script.cmd run /pages_party_mode.jsonl jsonl ~ accepted parameters: one or more json formatted lines Create new objects or update the properties of an existing object. When updating an existing object the obj property is not required and will be ignored. Each line in the jsonl payload defines one object and has to be in the json format. If the payload exceeds the MQTT buffer of 2 kB it will be cut off to fit, don't send too many lines in a single payload, you can always sends multiple jsonl commands. Example 1 jso nl { \"obj\" : \"btn\" , \"id\" : 14 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"Test\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } For more details see Pages and Objects . json ~ accepted parameters: json array of strings Use the json command to send multiple commands as an array of strings in one payload. Example 1 jso n [ 'page 3 ' , 'backligh t { \"state\" : \"ON\" , \"brightness\" : 100 } ' , 'idle o ff ' ] This command will change to page 3, turn the backlight on at ~40% brightness and reset the idle timer. page ~ accepted parameters: [1-12] , prev , next or back Switches the display to show the objects from a different page and return the page number in state/page . Calling the page command without a parameter will return the value of the current page in state/page . clearpage ~ accepted parameters: [0-12] or all Deletes all objects on a given page. If no page number is specified, it clears the current page. Use clearpage all to clear all objects on all pages. To delete individual objects, you can issue the pXbY.delete command. backlight ~ accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 Example backlight {\"state\":\"on\",\"brightness\":128} sets the display to half the brightness. Instead of a json payload, you can use a simple payload. To change the state, use either on / off , true / false , 0 , yes / no . A simple integer payload of 1..255 will adjust the brightness. Example backlight off backlight 200 sets the display brightness to ~80%. moodlight ~ accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 color or r, g, b: 0..255 An RGB moodlight can be controlled by configuring 3 GPIO pins as type Mood Red , Mood Green and Mood blue . These leds can then be controlled together using the moodlight command. Example 1 2 3 4 moodligh t { \"state\" : \"off\" , \"color\" : \"green\" } moodligh t { \"state\" : true , \"color\" : \"#ff00e7\" } moodligh t { \"color\" : 12345 } moodligh t { \"state\" : \"on\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 255 } The state key accepts boolean values to turn the moodlight on or off The brightness key can be set between 1 and 255 to dim the moodlight The color key accepts color values to set the RGB channels at once Individual r , g and b keys can also be used to set each channel separately Calling the moodlight command without parameters (or sending an empty payload to the hasp//command/moodlight topic) returns the current state: Example 1 \"state/moodlight\" { \"state\" : \"ON\" , \"brightness\" : 255 , \"color\" : \"#ff0000\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 0 } The color is returned as a hexadecimal value and as individual RGB channels. idle ~ accepted parameters: off , short or long Sets the idle state of the device and publishes the new state via a state/idle status message. off resets the idle counter as if a touch event occurred on the device. This is helpful e.g. when you want to wake up the display when an external event has occurred, like a PIR motion sensor. short or long sets the idle timer to the number of seconds configured in the Display Settings . You can use this to force an idle state, for example at night or when leaving the house. Calling the idle command without a parameter will also return the current idle state short , long or off in the state/idle topic. output[x] ~ where [x] is number of the gpio pin (0-39) accepted json keys: state: on / off , true / false , 0 / 1 , yes / no val: 0..255 Changes the state GPIO pin to on or off . If the pin is configured as a LED or Serial Dimmer then the val key will control the brightness. Note If the GPIO is assigned to a group then objects and other GPIOs that share the same groupid will change state accordingly. input[x] ~ where [x] is number of the gpio pin (0-39) read-only Returns a JSON object containing the current state of the input, either on or off Example 1 i n pu t 4 => { \"state\" : \"on\" } System Commands ~ antiburn ~ accepted parameters: on / off , true / false , 0 / 1 , yes / no Start LCD anti burn-in protection. This cycles the display to a full black, red, green, blue and white color each second to relief the tension put on each individual pixel. The cycle stops when either: 30 seconds have passed antiburn=off is received The screen is touched If you're using Home Assistant, check out the automation example to make it run on a regular basis. calibrate ~ Start on-screen touch calibration. You need to issue a soft reboot command to save the new calibration settings. If you do a hard reset of the device, the calibration settings will be lost. discovery ~ Trigger the sending of the discovery payload. sensors ~ Trigger the sending of the sensor data. factoryreset ~ Clear the filesystem and EEPROM and reboot the device in its initial state. Warning There is no confirmation prompt nor an undo function! reboot or restart ~ Saves any changes in the configuration file and reboots the device. screenshot ~ Saves a picture of the current screen to the flash filesystem. You can retrieve it via http:///screenshot.bmp. This can be handy for bug reporting or documentation. The previous screenshot is overwritten. service ~ Start or stop some of the processes running on the plate. Currently supported parameters: start stop Currently supported services: http (web interface) telnet (remote console) console (serial console) Example To stop the web interface of the plate, send to topic hasp//command/service the string stop http . To start the web interface of the plate, send to topic hasp//command/service the string start http . Tip Once these services are stopped, connection is lost/not possible to the plate through them. They can be started at any time by sending service start commands in through MQTT. It's possible to create self-built firmware binaries which have services stopped by default at boot, using customization . statusupdate ~ Reports the status of the MCU. The response will be posted to the state topic. Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \"hasp//state/statusupdate\" => { \"node\" : \"plate01\" , \"idle\" : \"long\" , \"version\" : \"0.6.3\" , \"uptime\" : 11027 , \"ssid\" : \"my_network\" , \"rssi\" : -60 , \"ip\" : \"192.168.0.133\" , \"mac\" : \"7C:87:CE:E3:55:55\" , \"heapFree\" : 58756 , \"heapFrag\" : 7 , \"core\" : \"v4.4.1\" , \"canUpdate\" : \"false\" , \"page\" : 1 , \"numPages\" : 12 , \"tftDriver\" : \"ILI9488\" , \"tftWidth\" : 480 , \"tftHeight\" : 320 } unzip ~ Unzip a file-packgage on the plate. You can upload uncompressed ZIP files to the flash space of your plate and unzip them locally. This is useful for cases when you need a lot of small files to be uploaded - putting them in an uncompressed zip allows to upload them in one go, and then extract them with a single command: Example unzip /openhasp-weathericons-day.zip update ~ accepted parameters: [url] Update the firmware from the url provided. Reboots when update was successful. Configuration Settings ~ Wi-FI ~ ssid ~ Set network name of the access point to connect to. pass ~ Set the optional password for the access point to connect to. MQTT ~ hostname ~ Set the hostname of the device and mqtt topic for the node to hasp// mqtthost ~ Set the IP address or hostname of the mqtt broker. mqttport ~ Set the port of the mqtt broker. mqttuser ~ Set the optional username for the mqtt broker. mqttpass ~ Set the optional password for the mqtt broker. config/submodule ~ You can get or set the configuration of an openHASP submodule in json format. To get the configuration, use the command config/ : config/wifi config/mqtt config/http config/mdns config/hasp config/gui config/debug config/gpio The result will be published to hasp//state/config . Passwords will be omitted from the result. To update the configuration simply issue the same command config/ with updated json payload. Example config/gui {\"idle2\":0} disable long idle (don't turn off the screen completely) config/debug {\"tele\":300} set the telemetry period to 300 seconds config/hasp {\"startdim\":255} to set the startup brightness to 255","title":"Commands"},{"location":"commands/#mqtt-topics","text":"hasp/plate01/command/ is for sending commands to the screen hasp/plate01/state/ is for receiving updates from the screen So the topic depends on the direction of the data flow. Sending a message to topic hasp/plate01/command/p1b2.val with payload 25 would be a valid command. You can send a test MQTT message with a standalone program like MQTT Explorer or mosuito_pub.","title":"MQTT Topics"},{"location":"commands/#issuing-commands","text":"Commands can be issued via the Serial commandline, telnet commandline or MQTT. For MQTT, you can use either: hasp//command topic with payload = hasp//command/ topic with payload Leave the payload empty to get the current state without changing it.","title":"Issuing commands"},{"location":"commands/#batch-processing","text":"Commands can be processed in batch one after another from .cmd script files located in the flash storage of the plate. General rules when creating .cmd batch scripts: can contain any command empty lines are ignored # or // can be used for comments space or tab in front of a command is ignored lines starting with { are processed as jsonl payloads lines starting with [ are processed as json payloads other lines are processed as CR , LF or CRLF line endings allowed UTF8 encoding is required for special characters To start a batch script, use run command.","title":"Batch processing"},{"location":"commands/#system-scripts","text":"If any of the following scripts is present on the filesystem, it will be run automatically according to the rules below: L:/boot.cmd is executed when the plate has finished (re)booting L:/online.cmd will be executed after connection to the network was successfull L:/offline.cmd will be executed after connection to the WiFi is lost This makes it possible to disable or hide buttons, load a special offline page, etc. See example .","title":"System scripts"},{"location":"commands/#global-commands","text":"","title":"Global commands"},{"location":"commands/#run","text":"accepted parameters: name of a .cmd or .jsonl file present on the flash filesystem of the plate. Filename must be preceeded by the / character Run a batch script or load a jsonl page. Example run /script.cmd run /pages_party_mode.jsonl","title":"run"},{"location":"commands/#jsonl","text":"accepted parameters: one or more json formatted lines Create new objects or update the properties of an existing object. When updating an existing object the obj property is not required and will be ignored. Each line in the jsonl payload defines one object and has to be in the json format. If the payload exceeds the MQTT buffer of 2 kB it will be cut off to fit, don't send too many lines in a single payload, you can always sends multiple jsonl commands. Example 1 jso nl { \"obj\" : \"btn\" , \"id\" : 14 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"Test\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } For more details see Pages and Objects .","title":"jsonl"},{"location":"commands/#json","text":"accepted parameters: json array of strings Use the json command to send multiple commands as an array of strings in one payload. Example 1 jso n [ 'page 3 ' , 'backligh t { \"state\" : \"ON\" , \"brightness\" : 100 } ' , 'idle o ff ' ] This command will change to page 3, turn the backlight on at ~40% brightness and reset the idle timer.","title":"json"},{"location":"commands/#page","text":"accepted parameters: [1-12] , prev , next or back Switches the display to show the objects from a different page and return the page number in state/page . Calling the page command without a parameter will return the value of the current page in state/page .","title":"page"},{"location":"commands/#clearpage","text":"accepted parameters: [0-12] or all Deletes all objects on a given page. If no page number is specified, it clears the current page. Use clearpage all to clear all objects on all pages. To delete individual objects, you can issue the pXbY.delete command.","title":"clearpage"},{"location":"commands/#backlight","text":"accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 Example backlight {\"state\":\"on\",\"brightness\":128} sets the display to half the brightness. Instead of a json payload, you can use a simple payload. To change the state, use either on / off , true / false , 0 , yes / no . A simple integer payload of 1..255 will adjust the brightness. Example backlight off backlight 200 sets the display brightness to ~80%.","title":"backlight"},{"location":"commands/#moodlight","text":"accepted json keys: state: on / off , true / false , 0 / 1 , yes / no brightness: 1..255 color or r, g, b: 0..255 An RGB moodlight can be controlled by configuring 3 GPIO pins as type Mood Red , Mood Green and Mood blue . These leds can then be controlled together using the moodlight command. Example 1 2 3 4 moodligh t { \"state\" : \"off\" , \"color\" : \"green\" } moodligh t { \"state\" : true , \"color\" : \"#ff00e7\" } moodligh t { \"color\" : 12345 } moodligh t { \"state\" : \"on\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 255 } The state key accepts boolean values to turn the moodlight on or off The brightness key can be set between 1 and 255 to dim the moodlight The color key accepts color values to set the RGB channels at once Individual r , g and b keys can also be used to set each channel separately Calling the moodlight command without parameters (or sending an empty payload to the hasp//command/moodlight topic) returns the current state: Example 1 \"state/moodlight\" { \"state\" : \"ON\" , \"brightness\" : 255 , \"color\" : \"#ff0000\" , \"r\" : 255 , \"g\" : 0 , \"b\" : 0 } The color is returned as a hexadecimal value and as individual RGB channels.","title":"moodlight"},{"location":"commands/#idle","text":"accepted parameters: off , short or long Sets the idle state of the device and publishes the new state via a state/idle status message. off resets the idle counter as if a touch event occurred on the device. This is helpful e.g. when you want to wake up the display when an external event has occurred, like a PIR motion sensor. short or long sets the idle timer to the number of seconds configured in the Display Settings . You can use this to force an idle state, for example at night or when leaving the house. Calling the idle command without a parameter will also return the current idle state short , long or off in the state/idle topic.","title":"idle"},{"location":"commands/#outputx","text":"where [x] is number of the gpio pin (0-39) accepted json keys: state: on / off , true / false , 0 / 1 , yes / no val: 0..255 Changes the state GPIO pin to on or off . If the pin is configured as a LED or Serial Dimmer then the val key will control the brightness. Note If the GPIO is assigned to a group then objects and other GPIOs that share the same groupid will change state accordingly.","title":"output[x]"},{"location":"commands/#inputx","text":"where [x] is number of the gpio pin (0-39) read-only Returns a JSON object containing the current state of the input, either on or off Example 1 i n pu t 4 => { \"state\" : \"on\" }","title":"input[x]"},{"location":"commands/#system-commands","text":"","title":"System Commands"},{"location":"commands/#antiburn","text":"accepted parameters: on / off , true / false , 0 / 1 , yes / no Start LCD anti burn-in protection. This cycles the display to a full black, red, green, blue and white color each second to relief the tension put on each individual pixel. The cycle stops when either: 30 seconds have passed antiburn=off is received The screen is touched If you're using Home Assistant, check out the automation example to make it run on a regular basis.","title":"antiburn"},{"location":"commands/#calibrate","text":"Start on-screen touch calibration. You need to issue a soft reboot command to save the new calibration settings. If you do a hard reset of the device, the calibration settings will be lost.","title":"calibrate"},{"location":"commands/#discovery","text":"Trigger the sending of the discovery payload.","title":"discovery"},{"location":"commands/#sensors","text":"Trigger the sending of the sensor data.","title":"sensors "},{"location":"commands/#factoryreset","text":"Clear the filesystem and EEPROM and reboot the device in its initial state. Warning There is no confirmation prompt nor an undo function!","title":"factoryreset"},{"location":"commands/#reboot-or-restart","text":"Saves any changes in the configuration file and reboots the device.","title":"reboot or restart"},{"location":"commands/#screenshot","text":"Saves a picture of the current screen to the flash filesystem. You can retrieve it via http:///screenshot.bmp. This can be handy for bug reporting or documentation. The previous screenshot is overwritten.","title":"screenshot"},{"location":"commands/#service","text":"Start or stop some of the processes running on the plate. Currently supported parameters: start stop Currently supported services: http (web interface) telnet (remote console) console (serial console) Example To stop the web interface of the plate, send to topic hasp//command/service the string stop http . To start the web interface of the plate, send to topic hasp//command/service the string start http . Tip Once these services are stopped, connection is lost/not possible to the plate through them. They can be started at any time by sending service start commands in through MQTT. It's possible to create self-built firmware binaries which have services stopped by default at boot, using customization .","title":"service"},{"location":"commands/#statusupdate","text":"Reports the status of the MCU. The response will be posted to the state topic. Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \"hasp//state/statusupdate\" => { \"node\" : \"plate01\" , \"idle\" : \"long\" , \"version\" : \"0.6.3\" , \"uptime\" : 11027 , \"ssid\" : \"my_network\" , \"rssi\" : -60 , \"ip\" : \"192.168.0.133\" , \"mac\" : \"7C:87:CE:E3:55:55\" , \"heapFree\" : 58756 , \"heapFrag\" : 7 , \"core\" : \"v4.4.1\" , \"canUpdate\" : \"false\" , \"page\" : 1 , \"numPages\" : 12 , \"tftDriver\" : \"ILI9488\" , \"tftWidth\" : 480 , \"tftHeight\" : 320 }","title":"statusupdate"},{"location":"commands/#unzip","text":"Unzip a file-packgage on the plate. You can upload uncompressed ZIP files to the flash space of your plate and unzip them locally. This is useful for cases when you need a lot of small files to be uploaded - putting them in an uncompressed zip allows to upload them in one go, and then extract them with a single command: Example unzip /openhasp-weathericons-day.zip","title":"unzip"},{"location":"commands/#update","text":"accepted parameters: [url] Update the firmware from the url provided. Reboots when update was successful.","title":"update"},{"location":"commands/#configuration-settings","text":"","title":"Configuration Settings"},{"location":"commands/#wi-fi","text":"","title":"Wi-FI"},{"location":"commands/#mqtt","text":"","title":"MQTT"},{"location":"commands/#configsubmodule","text":"You can get or set the configuration of an openHASP submodule in json format. To get the configuration, use the command config/ : config/wifi config/mqtt config/http config/mdns config/hasp config/gui config/debug config/gpio The result will be published to hasp//state/config . Passwords will be omitted from the result. To update the configuration simply issue the same command config/ with updated json payload. Example config/gui {\"idle2\":0} disable long idle (don't turn off the screen completely) config/debug {\"tele\":300} set the telemetry period to 300 seconds config/hasp {\"startdim\":255} to set the startup brightness to 255","title":"config/submodule"},{"location":"gallery/","text":"","title":"Gallery"},{"location":"assets/buy/waveshare-tft-touch-shield/","text":" GND 5V <--> 5V RX <--> RX (not reversed!) TX <--> TX (not reversed!) Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Once the connections are made, flash the GS-T3E ESP32 binary like on any other device. GPIO Settings ~ 3-gang EU version GS-T3E ~ Pin Mode GS-T3E Group Default 45 Output Relay L1 1 Low (Normal) 46 Output Relay L2 2 Low (Normal) 44 Output Relay L3 3 Low (Normal) Tip To configure the GPIOs as light switches at once for GS-T3E send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 655918 , 656172 , 655661 , 0 , 0 , 0 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721454 , 721708 , 721197 , 0 , 0 , 0 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 } Wiring Diagram ~ The switch supports this wiring configuration: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring. Product Video ~ Your browser does not support the video tag. Gallery ~","title":"Golden Security"},{"location":"hardware/golden-security/gs-t3e/#gs-t3e","text":"","title":"GS-T3E "},{"location":"hardware/golden-security/gs-t3e/#models","text":"EU model: 3 gang relay switch CN model: 4 gang relay switch Only the PCB revision v2.3 (20221205) is supported by openHASP. Specify that you want the new device with PCB revision v2.3 when ordering from known vendor Golden Security on Alibaba. Warning Do NOT buy PCB revision v1.23 (20220817) because the internal antenna connector is NOT soldered onto the board. Those devices will have no WiFi reception on the ESP32! This version is now discontinued, but some sellers might have old stock.","title":"Models"},{"location":"hardware/golden-security/gs-t3e/#packaging","text":"","title":"Packaging"},{"location":"hardware/golden-security/gs-t3e/#flashing","text":"Disclaimer Never connect high-voltage when the panel is not properly secured in place. Device can be flashed by either using the USB port or the flash header pins and a FTDI serial programmer device. Steps to flash via USB: Disengage the panel from high-voltage power Detach the panel from the PSU power supply Connect a Micro USB cable Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Steps to flash via UART: Disengage the panel from high-voltage power Detach the panel from the PSU power supply Connect jumper wires: GND <--> GND 5V <--> 5V RX <--> RX (not reversed!) TX <--> TX (not reversed!) Connect IO0 to GND to activate flash mode! Press the KEY button to powercycle ( RESET ) the board Once the connections are made, flash the GS-T3E ESP32 binary like on any other device.","title":"Flashing"},{"location":"hardware/golden-security/gs-t3e/#gpio-settings","text":"","title":"GPIO Settings"},{"location":"hardware/golden-security/gs-t3e/#3-gang-eu-version-gs-t3e","text":"Pin Mode GS-T3E Group Default 45 Output Relay L1 1 Low (Normal) 46 Output Relay L2 2 Low (Normal) 44 Output Relay L3 3 Low (Normal) Tip To configure the GPIOs as light switches at once for GS-T3E send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 655918 , 656172 , 655661 , 0 , 0 , 0 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721454 , 721708 , 721197 , 0 , 0 , 0 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 }","title":"3-gang EU version GS-T3E"},{"location":"hardware/golden-security/gs-t3e/#wiring-diagram","text":"The switch supports this wiring configuration: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring.","title":"Wiring Diagram"},{"location":"hardware/golden-security/gs-t3e/#product-video","text":"Your browser does not support the video tag.","title":"Product Video"},{"location":"hardware/golden-security/gs-t3e/#gallery","text":"","title":"Gallery"},{"location":"hardware/lanbon/lanbon-l8/","text":"Lanbon L8 ~ Models ~ L8-HS: 3 Relays - load up to 200W/gang L8-HD: 1 Dimmer - load up to 200W/gang L8-HB: Boiler switch - load up to 16A L8-HT: Thermostat switch - not tested! Warning Choose a model that works with Apple HomeKit because those are WiFi versions with the internal antenna connected to the ESP32. Do NOT buy a version that is powered by Tuya Smart Life because the internal antenna is connected to the Tuya chip. Those devices will have very bad WiFi reception of the ESP32! Form factor ~ EU model: 86mm x 86mm US model: 120mm x 74mm All models are rated at AC 100-250V ~50-60Hz, the form factor can be a design choice regardless of the continental area. The models have the same recessed housing sliding into the wall, sized 50x50mm, with rounded corners creating a diameter of about 59mm. This makes them suitable for both EU and US wall fixtures. The EU model fits in a properly deployed, standard 60mm round wall box and can be fixed with two side screws (use the screws which belong to the box instead of the ones shipped with the device), the US model fits in the standard rectangular box and can be fixed through the oval holes located 3 1/4\" apart. The depth of the wall box has to be at least 35-40mm because some room is needed for the wires coming out straight of the device. Bezel Color ~ Black White Features: ~ Input voltage 110-250V ~ 50-60Hz AC ESP32-WROVER-B Capacitive touch screen Energy counter Pros Cons 8 MB flash Mood LEDS not uniform 8 MB PSram Capactitive touch Built-in PSU Energy monitor Standard wallmount form factor both EU and US Buy Note 1 An earlier revision V1.14 (20191203) of the PCB had an analog temperature sensor onboard. It was removed from V1.15 (20200521) of the PCB. You are likely not to get it when buying a recent switch. Note 2 There is a new V1.17 of the PCB with Tuya support. openHASP does not support the proprietary Tuya chip, but you can still flash the firmware and use the other Lanbon L8 features just fine. Contents ~ Flashing ~ Disclaimer Never connect high-voltage when the panel is not properly secured in place. You can follow this flashing guide on blakadder.com or this discussion post with instructions and photos to flash the firmware without having to open the device. Steps: Disengage the high-voltage power Detach the panel from the PSU power supply Connect RX , TX , IO0 , GND and 5V pins to the female pinheader Because there is no RESET pin, you need to powercycle the board while IO0 is connected to GND to activate flash mode Make sure you have a USB to serial adapter than can provide sufficient power on the 5V pin . Once the serial connections are made, flash the Lanbon-L8 ESP32 binary like on any other device. GPIO Settings ~ 3-gang version L8-HS ~ Pin Mode L8-HS Group Default 12 Output Relay (K3) 1 Low (Normal) 14 Output Relay 2 Low (Normal) 26 Output Mood Red 4 Low (Normal) 27 Output Relay 3 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs as light switches at once for L8-HS send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 197658 , 263456 , 329249 , 655628 , 655886 , 656155 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721164 , 721422 , 197658 , 721691 , 263456 , 329249 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 } Dimmer version L8-HD ~ Pin Mode L8-HD Group Default 12 Output Dimmer TX (K3) 1 Low (Normal) 26 Output Mood Red 4 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Warning There are two versions of the dimmer configuration: EU and AU . The protocol used to command the dimmer module differs between the two! Make sure that you have the correct type configured under your GPIO Output settings for pin 12 . Use the AU configuration for any 120V/US compatible dimmer modules. Tip To configure the GPIOs at once for L8-HD send to topic hasp//config/gpio a message with payload: EU version: 1 { \"config\" :[ 3211532 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} AU/US version: 1 { \"config\" :[ 3277068 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} Boiler version L8-HB ~ Pin Mode L8-HB Group Default 26 Output Mood Red 4 Low (Normal) 27 Output Relay 16A (K1) 1 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs at once for L8-HB send to topic hasp//config a message with payload: 1 { \"gpio\" :{ \"config\" :[ 197658 , 263456 , 329249 , 721179 , 14 , 27 , 0 , 0 ]}} Developer Note You can build your own firmware with GPIOs and many other parameters pre-configured in user_config_override.h as factory defaults for Lanbon L8. Wiring Diagrams ~ The switch supports several wiring configurations: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring. Product Video ~ Your browser does not support the video tag. Gallery ~ LCD Configuration ~ The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 st7789v = -D ST7789_DRIVER = 1 ;-D CGRAM_OFFSET=1 ; Library will add offsets required -D TFT_SDA_READ ; Read from display, it only provides an SDA pin -D TFT_WIDTH = 240 -D TFT_HEIGHT = 320 -D TFT_ROTATION = 2 ; see TFT_ROTATION values ; -D TFT_INVERSION_OFF ; for normal colors ; -D TFT_RGB_ORDER=TFT_RGB ; Colour order Red-Green-Blue -D TFT_RGB_ORDER = TFT_BGR ; Colour order Blue-Green-Red -D SPI_FREQUENCY = 80000000 -D SPI_READ_FREQUENCY = 6000000 -D USER_SETUP_LOADED = 1 -D SUPPORT_TRANSACTIONS HASP build_flags ~ Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 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 build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.ps_ram} ;region -- TFT_eSPI build options ------------------------ ${lcd.st7789v} -D LANBONL8 -D TFT_RST = 18 ; FCP pin2 RESET -D TFT_SCLK = 19 ; FCP pin3 SCL -D TFT_DC = 21 ; FCP pin4 D/C -D TFT_CS = 22 ; FCP pin5 CS -D TFT_MOSI = 23 ; FCP pin6 SDA -D TFT_MISO = 25 ; FCP pin7 SDO -D TFT_BCKL = 5 -D TOUCH_DRIVER = 6336 -D TOUCH_SDA = 4 -D TOUCH_SCL = 0 -D TOUCH_IRQ = -1 ; not connected -D TOUCH_RST = -1 ; not used, connected to 3.3V on FCP pin10 -D TOUCH_FREQUENCY = 400000 -D LED_RED = 26 -D LED_GREEN = 32 -D LED_BLUE = 33 -D RELAY_1 = 12 -D RELAY_2 = 24 -D RELAY_3 = 37 ;endregion","title":"Lanbon"},{"location":"hardware/lanbon/lanbon-l8/#lanbon-l8","text":"","title":"Lanbon L8"},{"location":"hardware/lanbon/lanbon-l8/#models","text":"L8-HS: 3 Relays - load up to 200W/gang L8-HD: 1 Dimmer - load up to 200W/gang L8-HB: Boiler switch - load up to 16A L8-HT: Thermostat switch - not tested! Warning Choose a model that works with Apple HomeKit because those are WiFi versions with the internal antenna connected to the ESP32. Do NOT buy a version that is powered by Tuya Smart Life because the internal antenna is connected to the Tuya chip. Those devices will have very bad WiFi reception of the ESP32!","title":"Models"},{"location":"hardware/lanbon/lanbon-l8/#contents","text":"","title":"Contents"},{"location":"hardware/lanbon/lanbon-l8/#flashing","text":"Disclaimer Never connect high-voltage when the panel is not properly secured in place. You can follow this flashing guide on blakadder.com or this discussion post with instructions and photos to flash the firmware without having to open the device. Steps: Disengage the high-voltage power Detach the panel from the PSU power supply Connect RX , TX , IO0 , GND and 5V pins to the female pinheader Because there is no RESET pin, you need to powercycle the board while IO0 is connected to GND to activate flash mode Make sure you have a USB to serial adapter than can provide sufficient power on the 5V pin . Once the serial connections are made, flash the Lanbon-L8 ESP32 binary like on any other device.","title":"Flashing"},{"location":"hardware/lanbon/lanbon-l8/#gpio-settings","text":"","title":"GPIO Settings"},{"location":"hardware/lanbon/lanbon-l8/#3-gang-version-l8-hs","text":"Pin Mode L8-HS Group Default 12 Output Relay (K3) 1 Low (Normal) 14 Output Relay 2 Low (Normal) 26 Output Mood Red 4 Low (Normal) 27 Output Relay 3 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs as light switches at once for L8-HS send to topic hasp//config/gpio a message with payload: 1 { \"config\" :[ 197658 , 263456 , 329249 , 655628 , 655886 , 656155 , 0 , 0 ]} Or for power switches : 1 { \"config\" :[ 721164 , 721422 , 197658 , 721691 , 263456 , 329249 , 0 , 0 ]} The difference is only the device class you want them to be autodetected as in Home Assistant: light vs. switch Example jsonl To create a page displaying the local relays as switches, try this very simple pages.jsonl : 1 2 3 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 40 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 1 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 122 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 2 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"switch\" , \"x\" : 30 , \"y\" : 205 , \"w\" : 180 , \"h\" : 75 , \"radius\" : 40 , \"radius20\" : 40 , \"groupid\" : 3 }","title":"3-gang version L8-HS"},{"location":"hardware/lanbon/lanbon-l8/#dimmer-version-l8-hd","text":"Pin Mode L8-HD Group Default 12 Output Dimmer TX (K3) 1 Low (Normal) 26 Output Mood Red 4 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Warning There are two versions of the dimmer configuration: EU and AU . The protocol used to command the dimmer module differs between the two! Make sure that you have the correct type configured under your GPIO Output settings for pin 12 . Use the AU configuration for any 120V/US compatible dimmer modules. Tip To configure the GPIOs at once for L8-HD send to topic hasp//config/gpio a message with payload: EU version: 1 { \"config\" :[ 3211532 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]} AU/US version: 1 { \"config\" :[ 3277068 , 197658 , 263456 , 329249 , 0 , 0 , 0 , 0 ]}","title":"Dimmer version L8-HD"},{"location":"hardware/lanbon/lanbon-l8/#boiler-version-l8-hb","text":"Pin Mode L8-HB Group Default 26 Output Mood Red 4 Low (Normal) 27 Output Relay 16A (K1) 1 Low (Normal) 32 Output Mood Green 5 Low (Normal) 33 Output Mood Blue 6 Low (Normal) Tip To configure the GPIOs at once for L8-HB send to topic hasp//config a message with payload: 1 { \"gpio\" :{ \"config\" :[ 197658 , 263456 , 329249 , 721179 , 14 , 27 , 0 , 0 ]}} Developer Note You can build your own firmware with GPIOs and many other parameters pre-configured in user_config_override.h as factory defaults for Lanbon L8.","title":"Boiler version L8-HB"},{"location":"hardware/lanbon/lanbon-l8/#wiring-diagrams","text":"The switch supports several wiring configurations: Warning Always follow the instructions from the installation guide and local safety regulations. Consult a licensed electrician when changing your electrical wiring.","title":"Wiring Diagrams"},{"location":"hardware/lanbon/lanbon-l8/#product-video","text":"Your browser does not support the video tag.","title":"Product Video"},{"location":"hardware/lanbon/lanbon-l8/#gallery","text":"","title":"Gallery"},{"location":"hardware/lanbon/lanbon-l8/#lcd-configuration","text":"The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 st7789v = -D ST7789_DRIVER = 1 ;-D CGRAM_OFFSET=1 ; Library will add offsets required -D TFT_SDA_READ ; Read from display, it only provides an SDA pin -D TFT_WIDTH = 240 -D TFT_HEIGHT = 320 -D TFT_ROTATION = 2 ; see TFT_ROTATION values ; -D TFT_INVERSION_OFF ; for normal colors ; -D TFT_RGB_ORDER=TFT_RGB ; Colour order Red-Green-Blue -D TFT_RGB_ORDER = TFT_BGR ; Colour order Blue-Green-Red -D SPI_FREQUENCY = 80000000 -D SPI_READ_FREQUENCY = 6000000 -D USER_SETUP_LOADED = 1 -D SUPPORT_TRANSACTIONS","title":"LCD Configuration"},{"location":"hardware/lanbon/lanbon-l8/#hasp-build_flags","text":"Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 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 build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.ps_ram} ;region -- TFT_eSPI build options ------------------------ ${lcd.st7789v} -D LANBONL8 -D TFT_RST = 18 ; FCP pin2 RESET -D TFT_SCLK = 19 ; FCP pin3 SCL -D TFT_DC = 21 ; FCP pin4 D/C -D TFT_CS = 22 ; FCP pin5 CS -D TFT_MOSI = 23 ; FCP pin6 SDA -D TFT_MISO = 25 ; FCP pin7 SDO -D TFT_BCKL = 5 -D TOUCH_DRIVER = 6336 -D TOUCH_SDA = 4 -D TOUCH_SCL = 0 -D TOUCH_IRQ = -1 ; not connected -D TOUCH_RST = -1 ; not used, connected to 3.3V on FCP pin10 -D TOUCH_FREQUENCY = 400000 -D LED_RED = 26 -D LED_GREEN = 32 -D LED_BLUE = 33 -D RELAY_1 = 12 -D RELAY_2 = 24 -D RELAY_3 = 37 ;endregion","title":"HASP build_flags"},{"location":"hardware/lilygo/lilygo-lily-pi/","text":"LilyGO\u00ae Lily Pi ~ Features ~ ESP32-WROVER ILI9481 or ST7796 3.5\" (480*320) TFT screen in 4-wire SPI mode FT6X36 or GT911 Capacitive Touch Controller CP2104 USB-to-UART IC USB-C connector DC 5-12V barrel jack (5.5x2.1mm) Relay HFD3 5V 2A microSD card holder Real Time Clock PCF8563 Battery voltage divider connected to GPIO35 GPIO output via USB-A type connectors The Lily Pi is designed to resemble the Raspberry Pi appearance. The PCB layout and ports also mimmicks the Rasberry Pi. There is even the familiar 2x20 expansion port inside that match the Raspberry Pi GPIO pinout. Some Rpi expansion boards could work on this PCB too depending on the pins used. Pros Cons 480x320 display Non-standard USB-A connectors as GPIO 16 MB flash 8 MB PSram Capacitive Touchscreen The RTC and SD card are not supported by openHASP 0.7.0-rc9. Models ~ Model TN ST7796 FT6236 IPS ILI9481 GT911 SKU K113 K113-01 Resolution 480x320 480x320 TFT controller ST7796 ILI9481 Interface SPI SPI Touchscreen Capacitive Capacitive Touch controller FT6236 GT911 Screen dimming yes yes Buy AliExpress Tindie Buy AliExpress Tindie Video ~ Backlight Control ~ The GPIO that controls the backlight is GPIO12 . Documentation ~ The Lily Pi comes with the following information cards describing all the GPIOs used: Flashing ~ The LilyGO Lily Pi can easily be flashed over USB like any ESP32 development board. Dimensions ~ Size: 99.7 x 62.5 x 31.2mm","title":"Lily Pi"},{"location":"hardware/lilygo/lilygo-lily-pi/#lilygo-lily-pi","text":"","title":"LilyGO\u00ae Lily Pi"},{"location":"hardware/lilygo/lilygo-lily-pi/#features","text":"ESP32-WROVER ILI9481 or ST7796 3.5\" (480*320) TFT screen in 4-wire SPI mode FT6X36 or GT911 Capacitive Touch Controller CP2104 USB-to-UART IC USB-C connector DC 5-12V barrel jack (5.5x2.1mm) Relay HFD3 5V 2A microSD card holder Real Time Clock PCF8563 Battery voltage divider connected to GPIO35 GPIO output via USB-A type connectors The Lily Pi is designed to resemble the Raspberry Pi appearance. The PCB layout and ports also mimmicks the Rasberry Pi. There is even the familiar 2x20 expansion port inside that match the Raspberry Pi GPIO pinout. Some Rpi expansion boards could work on this PCB too depending on the pins used. Pros Cons 480x320 display Non-standard USB-A connectors as GPIO 16 MB flash 8 MB PSram Capacitive Touchscreen The RTC and SD card are not supported by openHASP 0.7.0-rc9.","title":"Features"},{"location":"hardware/lilygo/lilygo-lily-pi/#models","text":"Model TN ST7796 FT6236 IPS ILI9481 GT911 SKU K113 K113-01 Resolution 480x320 480x320 TFT controller ST7796 ILI9481 Interface SPI SPI Touchscreen Capacitive Capacitive Touch controller FT6236 GT911 Screen dimming yes yes Buy AliExpress Tindie Buy AliExpress Tindie","title":"Models"},{"location":"hardware/lilygo/lilygo-lily-pi/#video","text":"","title":"Video"},{"location":"hardware/lilygo/lilygo-lily-pi/#backlight-control","text":"The GPIO that controls the backlight is GPIO12 .","title":"Backlight Control"},{"location":"hardware/lilygo/lilygo-lily-pi/#documentation","text":"The Lily Pi comes with the following information cards describing all the GPIOs used:","title":"Documentation"},{"location":"hardware/lilygo/lilygo-lily-pi/#flashing","text":"The LilyGO Lily Pi can easily be flashed over USB like any ESP32 development board.","title":"Flashing"},{"location":"hardware/lilygo/lilygo-lily-pi/#dimensions","text":"Size: 99.7 x 62.5 x 31.2mm","title":"Dimensions"},{"location":"hardware/lilygo/lilygo-t-display-s3/","text":"LilyGO\u00ae T-Display-S3 ~ Warning The configuration for this board is under development and not finilized yet. LILYGO\u00ae T-Display-S3 ESP32-S3 1.9\" ST7789 LCD Display Development Board WIFI Bluetooth5.0 Wireless Module 170*320 Resolution T-Display-S3 is a development board whose main control chip is ESP32-S3. It is equipped with a 1.9\" LCD color screen and two programmable buttons. Communication using the I8080 interface Retains the same layout design as T-Display. You can directly use ESP32S3 for USB communication or programming. Specifications ~ Pros Cons MCU ESP32-S3R8 Dual-core LX7 microprocessor Wireless Connectivity Wi-Fi 802.11, BLE 5 + BT mesh Flash 16MB PSRAM 8MB Bat voltage detection IO04 Onboard functions Boot + Reset + IO14 Button LCD 1.9\" diagonal, Full-color TFT Display Drive Chip ST7789V Resolution 170(H)RGB x320(V) 8-Bit Parallel Interface Connectors JST-GH 1.25mm 2PIN STEMMA QT / Qwiic JST-SH 1.0mm 4-PIN Touch Edition ~ ESP32-S3 1.9\" ST7789 LCD Display with Touch Screen Development Board. Basic Edition ~ The Basic Edition of the LilyGO\u00ae T-Display-S3 does not have a touchscreen. It can only be used to display information. You can not interact with objects on the screen. However, you can connect GPIOs and/or use the push buttons to integrate the device into your Home Automation system. Documentation ~ Documentation ~ Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"T-Display-S3"},{"location":"hardware/lilygo/lilygo-t-display-s3/#lilygo-t-display-s3","text":"Warning The configuration for this board is under development and not finilized yet. LILYGO\u00ae T-Display-S3 ESP32-S3 1.9\" ST7789 LCD Display Development Board WIFI Bluetooth5.0 Wireless Module 170*320 Resolution T-Display-S3 is a development board whose main control chip is ESP32-S3. It is equipped with a 1.9\" LCD color screen and two programmable buttons. Communication using the I8080 interface Retains the same layout design as T-Display. You can directly use ESP32S3 for USB communication or programming.","title":"LilyGO\u00ae T-Display-S3"},{"location":"hardware/lilygo/lilygo-t-display-s3/#specifications","text":"Pros Cons MCU ESP32-S3R8 Dual-core LX7 microprocessor Wireless Connectivity Wi-Fi 802.11, BLE 5 + BT mesh Flash 16MB PSRAM 8MB Bat voltage detection IO04 Onboard functions Boot + Reset + IO14 Button LCD 1.9\" diagonal, Full-color TFT Display Drive Chip ST7789V Resolution 170(H)RGB x320(V) 8-Bit Parallel Interface Connectors JST-GH 1.25mm 2PIN STEMMA QT / Qwiic JST-SH 1.0mm 4-PIN","title":"Specifications"},{"location":"hardware/lilygo/lilygo-t-display-s3/#touch-edition","text":"ESP32-S3 1.9\" ST7789 LCD Display with Touch Screen Development Board.","title":"Touch Edition"},{"location":"hardware/lilygo/lilygo-t-display-s3/#basic-edition","text":"The Basic Edition of the LilyGO\u00ae T-Display-S3 does not have a touchscreen. It can only be used to display information. You can not interact with objects on the screen. However, you can connect GPIOs and/or use the push buttons to integrate the device into your Home Automation system.","title":"Basic Edition"},{"location":"hardware/lilygo/lilygo-t-display-s3/#documentation","text":"","title":"Documentation"},{"location":"hardware/lilygo/lilygo-t-display-s3/#documentation_1","text":"Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"Documentation"},{"location":"hardware/lilygo/lilygo-t-hmi/","text":"LILYGO\u00ae T-HMI ESP32-S3 ~ Warning The configuration for this board is currently being tested. T-HMI is currently LILYGO's largest touch display screen equipped with ESP32-S3 chip. The screen uses a 2.8-inch ST7789 LCD and is equipped with a resistive screen stylus/pen. It has 16 MB onboard Flash and 8MB PSram. It can be powered via the USB-C interface, 5V DC seat or battery connector. Pros Cons 16 MB flash Resistive Touchscreen 8 MB PSram 3 Groove ports The SD card is not supported by openHASP 0.7.0-rc9. AliExpress Tindie","title":"T-HMI ESP32-S3"},{"location":"hardware/lilygo/lilygo-t-hmi/#lilygo-t-hmi-esp32-s3","text":"Warning The configuration for this board is currently being tested. T-HMI is currently LILYGO's largest touch display screen equipped with ESP32-S3 chip. The screen uses a 2.8-inch ST7789 LCD and is equipped with a resistive screen stylus/pen. It has 16 MB onboard Flash and 8MB PSram. It can be powered via the USB-C interface, 5V DC seat or battery connector. Pros Cons 16 MB flash Resistive Touchscreen 8 MB PSram 3 Groove ports The SD card is not supported by openHASP 0.7.0-rc9. AliExpress Tindie","title":"LILYGO\u00ae T-HMI ESP32-S3 "},{"location":"hardware/lilygo/lilygo-t-rgb-s3/","text":"LilyGO\u00ae T-RGB ESP32-S3 ~ Warning The configuration for this board is under development and not finilized yet. Oval Edition ~ Round Edition ~ There is an Oval and a Round Edition of the LilyGO\u00ae T-RGB ESP32-S3. Both have a capacitive touchscreen.","title":"T-RGB-S3 2.1\""},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#lilygo-t-rgb-esp32-s3","text":"Warning The configuration for this board is under development and not finilized yet.","title":"LilyGO\u00ae T-RGB ESP32-S3"},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#oval-edition","text":"","title":"Oval Edition"},{"location":"hardware/lilygo/lilygo-t-rgb-s3/#round-edition","text":"There is an Oval and a Round Edition of the LilyGO\u00ae T-RGB ESP32-S3. Both have a capacitive touchscreen.","title":"Round Edition"},{"location":"hardware/lilygo/ttgo-t7-s3/","text":"Warning The configuration for this board is under development and not finilized yet. LilyGO\u00ae T7 S3 ESP32-S3 ~ T7 S3 is an ESP32 module based on the ESP32-S3-WROOM-1, with 16 MB built-in Flash and 8MB PSram. AliExpress Tindie","title":"T7-S3 v1.1"},{"location":"hardware/lilygo/ttgo-t7-s3/#lilygo-t7-s3-esp32-s3","text":"T7 S3 is an ESP32 module based on the ESP32-S3-WROOM-1, with 16 MB built-in Flash and 8MB PSram. AliExpress Tindie","title":"LilyGO\u00ae T7 S3 ESP32-S3"},{"location":"hardware/lolin/lolin-tft-shield/","text":"Lolin TFT 2.4\" Touch Shield ~ Features ~ This Lolin TFT has a 2.4\" touchscreen with XPT2046 resistive touch controller. There are 3 ways to connect an ESP32: Plug a compatible ESP32 onto the female headers on the back Attach a LOLIN D32 Pro V2.0 using the 10-pin TFT connector and cable Solder headers onto the bottom pinholes for pluging into a breadboard or jumper cables for any other ESP32 Pros Cons Plug-and-play Resistive touchscreen Limited soldering required Availability Choice of several ESP32 MCUs Price Buy Compatible ESP32 dev boards ~ The Lolin TFT 2.4\" headers are plug-and-play compatible with these development boards, no need to use any jumper cables: Model Minimal Better Best SKU D1 Mini ESP32 TTGO T7 V1.5 Mini32 Lolin D32 Pro V2.0 MCU ESP32-WROOM ESP32-WROVER ESP32-WROVER Flash 4 MB 4 or 16 MB 4 or 16 MB PSram No 8 MB 8 MB Connection Two 1x8 Pinheaders\u00b2 Two 1x8 Pinheaders\u00b2 10-pin TFT cable (optional) SD Card no no yes Battery charging no yes yes USB Chip CH9102F CH340C Screen dimming yes yes yes Buy Buy Buy Warning The D1 Mini ESP32 board may suffer from brown-out reboots if not powered adequately. Note (\u00b2) Because the board is developed for the D1-mini, you must only solder a row of 1x8 male pins to pads TXD-5V and RST-3V3 each. Product Video ~ Backlight Control ~ To use PWM dimming on the Lolin TFT 2.4\" you must bridge the center TFT-LED pin to the D1 solder pad next to it. This pin is configured by default in the firmware. Warning Do not use D3 for backlight control because it is already in use for touch! Do not use D4 for backlight control because it is already in use for PSram on the ESP32-WROVER. The D1-mini has D4 connected to the on-board LED and boot fails if pulled LOW. Documentation ~ Wemos Wiki Schematics Dimensions ~","title":"Lolin"},{"location":"hardware/lolin/lolin-tft-shield/#lolin-tft-24-touch-shield","text":"","title":"Lolin TFT 2.4\" Touch Shield"},{"location":"hardware/lolin/lolin-tft-shield/#features","text":"This Lolin TFT has a 2.4\" touchscreen with XPT2046 resistive touch controller. There are 3 ways to connect an ESP32: Plug a compatible ESP32 onto the female headers on the back Attach a LOLIN D32 Pro V2.0 using the 10-pin TFT connector and cable Solder headers onto the bottom pinholes for pluging into a breadboard or jumper cables for any other ESP32 Pros Cons Plug-and-play Resistive touchscreen Limited soldering required Availability Choice of several ESP32 MCUs Price Buy","title":"Features"},{"location":"hardware/lolin/lolin-tft-shield/#compatible-esp32-dev-boards","text":"The Lolin TFT 2.4\" headers are plug-and-play compatible with these development boards, no need to use any jumper cables: Model Minimal Better Best SKU D1 Mini ESP32 TTGO T7 V1.5 Mini32 Lolin D32 Pro V2.0 MCU ESP32-WROOM ESP32-WROVER ESP32-WROVER Flash 4 MB 4 or 16 MB 4 or 16 MB PSram No 8 MB 8 MB Connection Two 1x8 Pinheaders\u00b2 Two 1x8 Pinheaders\u00b2 10-pin TFT cable (optional) SD Card no no yes Battery charging no yes yes USB Chip CH9102F CH340C Screen dimming yes yes yes Buy Buy Buy Warning The D1 Mini ESP32 board may suffer from brown-out reboots if not powered adequately. Note (\u00b2) Because the board is developed for the D1-mini, you must only solder a row of 1x8 male pins to pads TXD-5V and RST-3V3 each.","title":"Compatible ESP32 dev boards"},{"location":"hardware/lolin/lolin-tft-shield/#product-video","text":"","title":"Product Video"},{"location":"hardware/lolin/lolin-tft-shield/#backlight-control","text":"To use PWM dimming on the Lolin TFT 2.4\" you must bridge the center TFT-LED pin to the D1 solder pad next to it. This pin is configured by default in the firmware. Warning Do not use D3 for backlight control because it is already in use for touch! Do not use D4 for backlight control because it is already in use for PSram on the ESP32-WROVER. The D1-mini has D4 connected to the on-board LED and boot fails if pulled LOW.","title":"Backlight Control"},{"location":"hardware/lolin/lolin-tft-shield/#documentation","text":"Wemos Wiki Schematics","title":"Documentation"},{"location":"hardware/lolin/lolin-tft-shield/#dimensions","text":"","title":"Dimensions"},{"location":"hardware/m5stack/core2/","text":"M5Stack core2 ~ M5Stack core2 is the second generation core device in the M5Stack development kit series. The core2 features a 2\" capacitive touchscreen, unlike its predecessor, making it very suitable to run openHASP. The device is packed with a beefy ESP32 model D0WDQ6-V3 and lots of sensors. Features ~ 1W Speaker SPM1423 Microphone Vibration Motor 3.7V / 390 mAh battery with power management chip SD card slot (16 GB maximum size) IMU (3-axis gyroscope & 3-axis accelerometer) Dimensions: 54 x 54 x 16mm Pros Cons 16 MB flash Small display 8 MB PSram Internal Battery Capacitive Touchscreen Available from: M5stack Mouser Digikey Amazon Product Video ~ Schematic ~ Schematics M5Stack Library ~ The M5Stack series comes with an opensource library to give you a jump start in deveopment for this device, including a Getting Started guide, examples and API reference. Visit the M5Stack Github repo.","title":"M5stack"},{"location":"hardware/m5stack/core2/#m5stack-core2","text":"M5Stack core2 is the second generation core device in the M5Stack development kit series. The core2 features a 2\" capacitive touchscreen, unlike its predecessor, making it very suitable to run openHASP. The device is packed with a beefy ESP32 model D0WDQ6-V3 and lots of sensors.","title":"M5Stack core2"},{"location":"hardware/m5stack/core2/#features","text":"1W Speaker SPM1423 Microphone Vibration Motor 3.7V / 390 mAh battery with power management chip SD card slot (16 GB maximum size) IMU (3-axis gyroscope & 3-axis accelerometer) Dimensions: 54 x 54 x 16mm Pros Cons 16 MB flash Small display 8 MB PSram Internal Battery Capacitive Touchscreen Available from: M5stack Mouser Digikey Amazon","title":"Features"},{"location":"hardware/m5stack/core2/#product-video","text":"","title":"Product Video"},{"location":"hardware/m5stack/core2/#schematic","text":"Schematics","title":"Schematic"},{"location":"hardware/m5stack/core2/#m5stack-library","text":"The M5Stack series comes with an opensource library to give you a jump start in deveopment for this device, including a Getting Started guide, examples and API reference. Visit the M5Stack Github repo.","title":"M5Stack Library"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/","text":"ESP32-S3 Parallel TFT with Touch ~ Warning The configuration for this board is under development and not finilized yet. more images... Features ~ The Makerfabs ESP32-S3 Parallel TFT Touch development board incorporates a 3.5\u201d, 4.0\u201d or 4.3\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and PSram. There is also an SD-card slot, USB-C connectors and two expansion ports. Models ~ Model 3.5\" Parallel 4.0\" Parallel 4.3\" Parallel SKU ESP32S335D E32S3RGB40 E32S3RGB43 Flash 16 MB 16 MB 16 MB PSram 2 MB 8 MB 8 MB Display 3.5\" 480x320 4.0\" IPS 4.3\" IPS Resolution 480x320 480x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Real Time Clock no no yes Screen dimming GPIO45 GPIO2 GPIO2 Buy Buy Buy Also available on Tindie The real-time clock and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ The backlight of the 3.5\" model can be controlled by PWM on pin GPIO45 . The backlight on the 4.0\" model is always on and can not be controlled. The backlight of the 4.3\" model can be controlled by PWM on pin GPIO02 if the PCB is v1.3 only. With PCB v2.0 the backlight can not be adjusted and the screen is always on. Video ~ ESP32-S3 Parallel TFT with Touch 3.5'' ILI9488 ~ ESP32-S3 Parallel TFT with Touch 4.0\" ~ ESP32-S3 Parallel TFT with Touch 4.3\" ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"ESP32-S3 Parallel TFT"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch","text":"Warning The configuration for this board is under development and not finilized yet. more images...","title":"ESP32-S3 Parallel TFT with Touch"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#features","text":"The Makerfabs ESP32-S3 Parallel TFT Touch development board incorporates a 3.5\u201d, 4.0\u201d or 4.3\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and PSram. There is also an SD-card slot, USB-C connectors and two expansion ports.","title":"Features"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#models","text":"Model 3.5\" Parallel 4.0\" Parallel 4.3\" Parallel SKU ESP32S335D E32S3RGB40 E32S3RGB43 Flash 16 MB 16 MB 16 MB PSram 2 MB 8 MB 8 MB Display 3.5\" 480x320 4.0\" IPS 4.3\" IPS Resolution 480x320 480x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Real Time Clock no no yes Screen dimming GPIO45 GPIO2 GPIO2 Buy Buy Buy Also available on Tindie The real-time clock and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#backlight-control","text":"The backlight of the 3.5\" model can be controlled by PWM on pin GPIO45 . The backlight on the 4.0\" model is always on and can not be controlled. The backlight of the 4.3\" model can be controlled by PWM on pin GPIO02 if the PCB is v1.3 only. With PCB v2.0 the backlight can not be adjusted and the screen is always on.","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-35-ili9488","text":"","title":"ESP32-S3 Parallel TFT with Touch 3.5'' ILI9488"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-40","text":"","title":"ESP32-S3 Parallel TFT with Touch 4.0\""},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#esp32-s3-parallel-tft-with-touch-43","text":"","title":"ESP32-S3 Parallel TFT with Touch 4.3\""},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-s3-parallel-tft-touch/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/","text":"ESP32-S3 SPI TFT with Touch ~ more images... Features ~ The ESP32-S3 SPI TFT with Touch development board incorporates a 3.5\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and 2MB of PSram. There is also an SD-card slot, USB-C connectors and expansion port with 14 GPIOs. Models ~ Model 3.5\" SPI SKU ESP32S3SPI35 Flash 16 MB PSram 2 MB Resolution 3.5\" 480x320 Touch Screen Capacitive SD Card yes Screen dimming yes Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ The backlight can be controlled by PWM on GPIO48 . Video ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"ESP32-S3 SPI TFT"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#esp32-s3-spi-tft-with-touch","text":"more images...","title":"ESP32-S3 SPI TFT with Touch"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#features","text":"The ESP32-S3 SPI TFT with Touch development board incorporates a 3.5\u201d capacitive touch display which makes it a very suitable platform for any openHASP project. At the back sits an ESP32-S3-WROOM module with 16MB of flash and 2MB of PSram. There is also an SD-card slot, USB-C connectors and expansion port with 14 GPIOs.","title":"Features"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#models","text":"Model 3.5\" SPI SKU ESP32S3SPI35 Flash 16 MB PSram 2 MB Resolution 3.5\" 480x320 Touch Screen Capacitive SD Card yes Screen dimming yes Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#backlight-control","text":"The backlight can be controlled by PWM on GPIO48 .","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-s3-spi-tft-touch/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"hardware/makerfabs/esp32-tft-touch/","text":"ESP32 TFT Touch with Camera ~ more images... Features ~ The Makerfabs ESP32 TFT Touch development board incorporates a 3.2\u201d or 3.5\u201d touch display, with a built-in 2M pixel OV2640 camera, which makes it a very suitable platform for any ESP32 project. There is a version with capacitive and resistive touch. At the back sits an ESP32-WROVER module with 16MB of flash and 8MB of PSram. There is also an SD-card slot, USB-C connector and expansion port with 14 GPIOs. Models ~ Model 3.2\" Resistive 3.5\" Resistive 3.5\" Capacitive SKU ESPTFT32CA ESPTFT35RE ESPTFT35CA Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Resolution 3.2\" 320x240 3.5\" 480x320 3.5\" 480x320 Touch Screen Resistive Resistive Capacitive OV2640 Camera 2M pixel 2M pixel 2M pixel SD Card yes yes yes Screen dimming no no no Buy Buy Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9. Backlight Control ~ Unfortunately, there is no support for backlight control. The display is always-on. Video ~ Documentation ~ More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics Acrylic Case ~ All 3 models have the option to add a protective acrylic case for only $2.90 extra:","title":"ESP32 SPI TFT with Camera"},{"location":"hardware/makerfabs/esp32-tft-touch/#esp32-tft-touch-with-camera","text":"more images...","title":"ESP32 TFT Touch with Camera"},{"location":"hardware/makerfabs/esp32-tft-touch/#features","text":"The Makerfabs ESP32 TFT Touch development board incorporates a 3.2\u201d or 3.5\u201d touch display, with a built-in 2M pixel OV2640 camera, which makes it a very suitable platform for any ESP32 project. There is a version with capacitive and resistive touch. At the back sits an ESP32-WROVER module with 16MB of flash and 8MB of PSram. There is also an SD-card slot, USB-C connector and expansion port with 14 GPIOs.","title":"Features"},{"location":"hardware/makerfabs/esp32-tft-touch/#models","text":"Model 3.2\" Resistive 3.5\" Resistive 3.5\" Capacitive SKU ESPTFT32CA ESPTFT35RE ESPTFT35CA Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Resolution 3.2\" 320x240 3.5\" 480x320 3.5\" 480x320 Touch Screen Resistive Resistive Capacitive OV2640 Camera 2M pixel 2M pixel 2M pixel SD Card yes yes yes Screen dimming no no no Buy Buy Buy Also available on Tindie Tip An optional environmental expansion board can be added to provide a temperature, humidity and air quality sensor. The camera can not be used at the same time as the expansion port. The camera and SD card are not supported by openHASP 0.7.0-rc9.","title":"Models"},{"location":"hardware/makerfabs/esp32-tft-touch/#backlight-control","text":"Unfortunately, there is no support for backlight control. The display is always-on.","title":"Backlight Control"},{"location":"hardware/makerfabs/esp32-tft-touch/#video","text":"","title":"Video"},{"location":"hardware/makerfabs/esp32-tft-touch/#documentation","text":"More information can be found in the Makerfabs Wiki and there are plenty of example projects available on the Github repository. Makerfabs Wiki Github Repo Schematics","title":"Documentation"},{"location":"hardware/makerfabs/esp32-tft-touch/#acrylic-case","text":"All 3 models have the option to add a protective acrylic case for only $2.90 extra:","title":"Acrylic Case"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/","text":"SenseCAP Indicator D1 ~ more images... SenseCAP Indicator D1 is a 4-inch touch screen driven by an ESP32-S3 and RP2040 dual-MCU and supports Wi-Fi/BLE communication. The ESP32-S3 has 8 MB flash and 8 MB PSRAM. It is a powerful, fully open-source IoT development platform. It can be powered via USB-C 2.0 on the bottom or the backside of the device. It is suitable for mounting on the wall or placement on a desk using the kickback stand. Models ~ The SenseCAP Indicator series offers four different versions: D1, D1S, D1L, and D1Pro. Each version is designed to meet different application needs without any extra cost from unnecessary hardware. Here are the differences between the versions: Attention openHASP does not support the D1S sensors or D1L Lora communications. Buy Mouser Kiwi Electronics Seeed Studio Documentation Product Video ~ Introduction to the SenseCAP Indicator D1: Gallery ~","title":"Seeed Studio"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#sensecap-indicator-d1","text":"more images... SenseCAP Indicator D1 is a 4-inch touch screen driven by an ESP32-S3 and RP2040 dual-MCU and supports Wi-Fi/BLE communication. The ESP32-S3 has 8 MB flash and 8 MB PSRAM. It is a powerful, fully open-source IoT development platform. It can be powered via USB-C 2.0 on the bottom or the backside of the device. It is suitable for mounting on the wall or placement on a desk using the kickback stand.","title":"SenseCAP Indicator D1"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#models","text":"The SenseCAP Indicator series offers four different versions: D1, D1S, D1L, and D1Pro. Each version is designed to meet different application needs without any extra cost from unnecessary hardware. Here are the differences between the versions: Attention openHASP does not support the D1S sensors or D1L Lora communications. Buy Mouser Kiwi Electronics Seeed Studio Documentation","title":"Models"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#product-video","text":"Introduction to the SenseCAP Indicator D1:","title":"Product Video"},{"location":"hardware/seeed-studio/sensecap-indicator-d1/#gallery","text":"","title":"Gallery"},{"location":"hardware/sunton/esp32-1732s019/","text":"Sunton ESP32-1732S019 ~ Warning The configuration for this board is under development and not finilized yet. These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress. Versions ~ There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: ESP32-3248S035 ~ Sunton ESP32 3.5inch Display Case Stand from Printables.com ESP32-4827S043 ~ Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-1732S019"},{"location":"hardware/sunton/esp32-1732s019/#sunton-esp32-1732s019","text":"Warning The configuration for this board is under development and not finilized yet. These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress.","title":"Sunton ESP32-1732S019 "},{"location":"hardware/sunton/esp32-1732s019/#versions","text":"There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Versions"},{"location":"hardware/sunton/esp32-1732s019/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-1732s019/#cases","text":"If you have a 3D printer, cases are becoming available:","title":"Cases"},{"location":"hardware/sunton/esp32-1732s019/#esp32-3248s035","text":"Sunton ESP32 3.5inch Display Case Stand from Printables.com","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-1732s019/#esp32-4827s043","text":"Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-1732s019/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-1732s019/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-1732s019/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-2432s028/","text":"Sunton ESP32-2432S028 ~ These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress. Versions ~ There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: ESP32-3248S035 ~ Sunton ESP32 3.5inch Display Case Stand from Printables.com ESP32-4827S043 ~ Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-2432S028"},{"location":"hardware/sunton/esp32-2432s028/#sunton-esp32-2432s028","text":"These are great \"all-in-one\" device that have integrated ESP32/ESP32-S3 chips, many with PSRAM. Sizes from 1.9\" to a whopping 7\" display and built in touch. Available via the Sunton store on Aliexpress.","title":"Sunton ESP32-2432S028 "},{"location":"hardware/sunton/esp32-2432s028/#versions","text":"There are many versions: ESP32-1732S019 (ESP32-S3) - currently not supported ESP32-2432S028 (ESP32) ESP32-3248S035(r/c)* (ESP32) ESP32-4827S043(r/c)* (ESP32-S3) ESP32-8048S050 (ESP32-S3) ESP32-8048S070 (ESP32-S3) * Note : versions can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you load the correct firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Versions"},{"location":"hardware/sunton/esp32-2432s028/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-2432s028/#cases","text":"If you have a 3D printer, cases are becoming available:","title":"Cases"},{"location":"hardware/sunton/esp32-2432s028/#esp32-3248s035","text":"Sunton ESP32 3.5inch Display Case Stand from Printables.com","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-2432s028/#esp32-4827s043","text":"Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-2432s028/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-2432s028/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-2432s028/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-3248s035/","text":"Sunton ESP32-3248S035 ~ The ESP32-3248S035 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles. Models ~ Model Resistive Touch Capacitive Touch SKU ESP32-3248S035R ESP32-3248S035C MCU ESP32-D0WDQ6 ESP32-D0WDQ6 Flash 4 MB 4 MB PSram No No Display Panel 3.5\" TN 3.5' TN Resolution 480x320 480x320 Touch Screen Resistive Capacitive SD Card yes yes Screen dimming yes yes Buy Buy The SD card is not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32 Modules have no PSram and are less suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-3248S035"},{"location":"hardware/sunton/esp32-3248s035/#sunton-esp32-3248s035","text":"The ESP32-3248S035 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles.","title":"Sunton ESP32-3248S035 "},{"location":"hardware/sunton/esp32-3248s035/#models","text":"Model Resistive Touch Capacitive Touch SKU ESP32-3248S035R ESP32-3248S035C MCU ESP32-D0WDQ6 ESP32-D0WDQ6 Flash 4 MB 4 MB PSram No No Display Panel 3.5\" TN 3.5' TN Resolution 480x320 480x320 Touch Screen Resistive Capacitive SD Card yes yes Screen dimming yes yes Buy Buy The SD card is not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32 Modules have no PSram and are less suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-3248s035/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-3248s035/#cases","text":"If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-3248s035/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-3248s035/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-3248s035/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-4827s043/","text":"Sunton ESP32-4827S043 ~ The ESP32-4827s043 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles. Models ~ Model TN Without Touch TN Resistive Touch TN Capacitive Touch SKU ESP32-4827S043 ESP32-4827S043R ESP32-4827S043C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" TN 4.3\" TN 4.3\" TN Resolution 480x272 480x272 480x272 Touch Screen None Resistive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-4827S043"},{"location":"hardware/sunton/esp32-4827s043/#sunton-esp32-4827s043","text":"The ESP32-4827s043 boards all come with an integrated ESP32-S3 chip, 16 MB flash and 8 MB PSRAM. There are 3 models: without touch, with resistive touch or with capacitive touch. They have a TN panel with a display resolution of 480x272 and acceptable viewing angles.","title":"Sunton ESP32-4827S043 "},{"location":"hardware/sunton/esp32-4827s043/#models","text":"Model TN Without Touch TN Resistive Touch TN Capacitive Touch SKU ESP32-4827S043 ESP32-4827S043R ESP32-4827S043C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" TN 4.3\" TN 4.3\" TN Resolution 480x272 480x272 480x272 Touch Screen None Resistive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-4827s043/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-4827s043/#cases","text":"If you have a 3D printer, cases are becoming available: Sunton ESP32S3 8048s043c 4.3\" Screen Case from Printables.com Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-4827s043/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-4827s043/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-4827s043/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/sunton/esp32-8048s0xx/","text":"Sunton ESP32-8048S0xx ~ These are great \"all-in-one\" device that have integrated ESP32-S3 chips with 16 MB of flash and 8MB PSram. There are 3 sizes available with an 800x480 resolution ranging from 4.3\", 5\" to 7\" display and built in capacitive touch panel. The 4.3\" and 5\" model have an IPS panel so the viewing angles are great. The 7\" version uses a TN panel with acceptable viewing angles but a larger display area. Models ~ Model 4.3\" IPS Capacitive 5.0\" IPS Capacitive 7.0\" TN Capacitive SKU ESP32-8048S043C ESP32-8048S050C ESP32-8048S070C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" IPS 5.0\" IPS 7.0\" TN Resolution 800x480 800x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics. Features ~ The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet. Cases ~ If you have a 3D printer, cases are becoming available: SUNON ESP32-2432S028 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/esp32-2432s028-display-box SUNON ESP32-3248S035 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-3248s035-matsekberg SUNON ESP32-8048S050 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-8048s050-display-box Other cases maybe available, search printables, thingiverse, etc Flashing ~ Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files. Recommended method ~ Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that. Initial Setup Notes ~ Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"ESP32-8048S0xx"},{"location":"hardware/sunton/esp32-8048s0xx/#sunton-esp32-8048s0xx","text":"These are great \"all-in-one\" device that have integrated ESP32-S3 chips with 16 MB of flash and 8MB PSram. There are 3 sizes available with an 800x480 resolution ranging from 4.3\", 5\" to 7\" display and built in capacitive touch panel. The 4.3\" and 5\" model have an IPS panel so the viewing angles are great. The 7\" version uses a TN panel with acceptable viewing angles but a larger display area.","title":"Sunton ESP32-8048S0xx "},{"location":"hardware/sunton/esp32-8048s0xx/#models","text":"Model 4.3\" IPS Capacitive 5.0\" IPS Capacitive 7.0\" TN Capacitive SKU ESP32-8048S043C ESP32-8048S050C ESP32-8048S070C MCU ESP32-S3-Wroom ESP32-S3-Wroom ESP32-S3-Wroom Flash 16 MB 16 MB 16 MB PSram 8 MB 8 MB 8 MB Display Panel 4.3\" IPS 5.0\" IPS 7.0\" TN Resolution 800x480 800x480 800x480 Touch Screen Capacitive Capacitive Capacitive SD Card yes yes yes Screen dimming yes yes yes Buy Buy Buy The audio port and SD card are not supported by openHASP 0.7.0-rc9. Note Models can have Resistive (r) or Capacitive (c) touch screens, you need to ensure you purchase the correct version and load the corresponding firmware for the device you have. ESP32-S3 Modules have PSram and are more suitable for loading fonts, and graphics.","title":"Models"},{"location":"hardware/sunton/esp32-8048s0xx/#features","text":"The Sunton screens are fully featured and ready to use screens with ESP32(S3) integrated, touch control integrated (Resistive or Capacitive), with resultions as high has 800x480! (in the 4.3\"+ screens). The back has many GPIO pins avialable through an included connector, TF Slot, Audio out (some versions), note: audio/tf not supported in openHASP yet.","title":"Features"},{"location":"hardware/sunton/esp32-8048s0xx/#cases","text":"If you have a 3D printer, cases are becoming available: SUNON ESP32-2432S028 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/esp32-2432s028-display-box SUNON ESP32-3248S035 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-3248s035-matsekberg SUNON ESP32-8048S050 DISPLAY BOX: https://cults3d.com/en/3d-model/gadget/sunon-esp32-8048s050-display-box Other cases maybe available, search printables, thingiverse, etc","title":"Cases"},{"location":"hardware/sunton/esp32-8048s0xx/#flashing","text":"Compile your own via platform.io and platformio_override.ini environment templates. Also available via web installer at https://nightly.openhasp.com/ or the latest found under Github Actions , click on the latest action, and look under the Assets sections for zip files containing builds binary files.","title":"Flashing"},{"location":"hardware/sunton/esp32-8048s0xx/#recommended-method","text":"Use the Nightly build website to initially flash the device. Then update with the OTA file found under Actions , Assets on github. Or compile your own if comfortable doing that.","title":"Recommended method"},{"location":"hardware/sunton/esp32-8048s0xx/#initial-setup-notes","text":"Note that some of the screens have TWO versions, Resistive and Capacitive , so flash the correct firmware (ends in r or a c respectively). RESISTIVE : After first boot, Run a Calibration via the web ui -> Display Setup -> Calibrate Then on the screen, touch the indicated points.","title":"Initial Setup Notes"},{"location":"hardware/waveshare/waveshare-rpi-lcd/","text":"Waveshare RPi LCD (Rev C) ~ Models ~ The Waveshare RPi LCD (Rev C) display comes in 3.5\" and 4.0\" sizes: Model 3.5inch (Rev C) 4.0inch (Rev C) SKU 15811 16099 Resolution 480x320 480x320 TFT controller ILI9486 ST7796 Interface SPI SPI Touchscreen Resistive Resistive Touch controller XPT2046 XPT2046 Screen dimming yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy AliExpress Waveshare.com Backlight Control ~ By default the display is always on. To enable backlight dimming, you can connect the pads marked by the red arrow using a 0R resistor or a direct solder connection: Attention (*) The WaveShare 3.5\" RPi LCD Revision C (SKU 15811) and WaveShare 4.0\" RPi LCD Revision C (SKU 16099) have the solder jumper on the back to enable PWM backlight dimming. Most revisions of this board do not have this feature! Development Boards ~ ESP32 One ~ The Waveshare ESP32 One development board has the same form factor as the Raspberry Pi Zero, inluding a 40 pin GPIO header. The ESP32 One is plug-and-play compatible with the Waveshare RPi LCD (Rev C) 3.5\" and 4\". This board has 4 MB flash and 8 MB PSRAM. Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Schematics Gallery ~ Pin Configuration ~ LCD Pin Function ESP32 Pin Config Name Display Pin 1 Module Power 3.3V 3.3V 3.3V 2 Module Power 5v 5V 5V 3 Not connected N/C 4 5V 5-10 Not connected N/C 11 Touch Interrupt N/C TOUCH_IRQ TP_IRQ 12 (*) LED Backlight PWM GPIO26 TFT_BCKL LCD_LED 13 Not connected N/C 14 Module Ground GND GND 15-16 Not connected N/C 17 Module Power 3.3V 3.3V 18 Data Command control pin GPIO4 TFT_DC LCD_RS 19 SPI Master Out Slave In GPIO13 TFT_MOSI LCD/SI/TP_SI 20 Not connected N/C 21 Touch Panel Slave Out GPIO12 TFT_MISO TP_SO 22 LCD Reset pin GPIO32 TFT_RST RST 23 SPI Clock GPIO14 TFT_SCLK LCD_SCK/TP_SCK 24 Chip select control pin GPIO5 TFT_CS LCD_CS 25 Module Ground GND GND 26 Touch Chip Select GPIO22 TOUCH_CS TP_CS SPI MISO, MOSI and SCLK are shared between the touch controller and the LCD controller. You can also use jumper wires to connect the display to any ESP32 development board: 6 GPIOs are required to drive the SPI display. One additional GPIO is needed for the XPT2046 touch sensor and one extra GPIO for backlight dimming. Including the VCC and GND pins, a total of 13 connections need to be made to the MCU. LCD Configuration ~ The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 raspberrypi = -D RPI_DISPLAY_TYPE = 1 -D ST7796_DRIVER = 1 -D TFT_WIDTH = 320 -D TFT_HEIGHT = 480 -D TFT_ROTATION = 0 ; 0=0, 1=90, 2=180 or 3=270 degree -D SPI_FREQUENCY = 80000000 -D SPI_TOUCH_FREQUENCY = 2500000 -D USER_SETUP_LOADED = 1 -D TOUCH_DRIVER = 2046 ; XPT2046 Resistive touch panel driver -D SUPPORT_TRANSACTIONS HASP build_flags ~ Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 build_flags = ${env.build_flags} ${esp32.build_flags} -DBOARD_HAS_PSRAM ; uses 78kB ; -- TFT_eSPI build options ------------------------ ${lcd.raspberrypi} ${esp32.hspi} ; Use HSPI hardware SPI bus -D TFT_CS = 5 -D TFT_DC = 4 -D TFT_RST = 32 -D TFT_BCKL = 26 ; Default, configurable via web UI -D TOUCH_CS = 22 -D SD_CS = 15 ; Currently not supported","title":"Waveshare RPi LCD"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#waveshare-rpi-lcd-rev-c","text":"","title":"Waveshare RPi LCD (Rev C)"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#models","text":"The Waveshare RPi LCD (Rev C) display comes in 3.5\" and 4.0\" sizes: Model 3.5inch (Rev C) 4.0inch (Rev C) SKU 15811 16099 Resolution 480x320 480x320 TFT controller ILI9486 ST7796 Interface SPI SPI Touchscreen Resistive Resistive Touch controller XPT2046 XPT2046 Screen dimming yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy AliExpress Waveshare.com","title":"Models"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#backlight-control","text":"By default the display is always on. To enable backlight dimming, you can connect the pads marked by the red arrow using a 0R resistor or a direct solder connection: Attention (*) The WaveShare 3.5\" RPi LCD Revision C (SKU 15811) and WaveShare 4.0\" RPi LCD Revision C (SKU 16099) have the solder jumper on the back to enable PWM backlight dimming. Most revisions of this board do not have this feature!","title":"Backlight Control"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#development-boards","text":"","title":"Development Boards"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#esp32-one","text":"The Waveshare ESP32 One development board has the same form factor as the Raspberry Pi Zero, inluding a 40 pin GPIO header. The ESP32 One is plug-and-play compatible with the Waveshare RPi LCD (Rev C) 3.5\" and 4\". This board has 4 MB flash and 8 MB PSRAM. Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Schematics","title":"ESP32 One"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#gallery","text":"","title":"Gallery"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#pin-configuration","text":"LCD Pin Function ESP32 Pin Config Name Display Pin 1 Module Power 3.3V 3.3V 3.3V 2 Module Power 5v 5V 5V 3 Not connected N/C 4 5V 5-10 Not connected N/C 11 Touch Interrupt N/C TOUCH_IRQ TP_IRQ 12 (*) LED Backlight PWM GPIO26 TFT_BCKL LCD_LED 13 Not connected N/C 14 Module Ground GND GND 15-16 Not connected N/C 17 Module Power 3.3V 3.3V 18 Data Command control pin GPIO4 TFT_DC LCD_RS 19 SPI Master Out Slave In GPIO13 TFT_MOSI LCD/SI/TP_SI 20 Not connected N/C 21 Touch Panel Slave Out GPIO12 TFT_MISO TP_SO 22 LCD Reset pin GPIO32 TFT_RST RST 23 SPI Clock GPIO14 TFT_SCLK LCD_SCK/TP_SCK 24 Chip select control pin GPIO5 TFT_CS LCD_CS 25 Module Ground GND GND 26 Touch Chip Select GPIO22 TOUCH_CS TP_CS SPI MISO, MOSI and SCLK are shared between the touch controller and the LCD controller. You can also use jumper wires to connect the display to any ESP32 development board: 6 GPIOs are required to drive the SPI display. One additional GPIO is needed for the XPT2046 touch sensor and one extra GPIO for backlight dimming. Including the VCC and GND pins, a total of 13 connections need to be made to the MCU.","title":"Pin Configuration"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#lcd-configuration","text":"The lcd_config.ini file specifies the different properties of the display, except for the actual pin configuration: 1 2 3 4 5 6 7 8 9 10 11 raspberrypi = -D RPI_DISPLAY_TYPE = 1 -D ST7796_DRIVER = 1 -D TFT_WIDTH = 320 -D TFT_HEIGHT = 480 -D TFT_ROTATION = 0 ; 0=0, 1=90, 2=180 or 3=270 degree -D SPI_FREQUENCY = 80000000 -D SPI_TOUCH_FREQUENCY = 2500000 -D USER_SETUP_LOADED = 1 -D TOUCH_DRIVER = 2046 ; XPT2046 Resistive touch panel driver -D SUPPORT_TRANSACTIONS","title":"LCD Configuration"},{"location":"hardware/waveshare/waveshare-rpi-lcd/#hasp-build_flags","text":"Specify the LCD Configuration to use and define the GPIOs in the environment build flags: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 build_flags = ${env.build_flags} ${esp32.build_flags} -DBOARD_HAS_PSRAM ; uses 78kB ; -- TFT_eSPI build options ------------------------ ${lcd.raspberrypi} ${esp32.hspi} ; Use HSPI hardware SPI bus -D TFT_CS = 5 -D TFT_DC = 4 -D TFT_RST = 32 -D TFT_BCKL = 26 ; Default, configurable via web UI -D TOUCH_CS = 22 -D SD_CS = 15 ; Currently not supported","title":"HASP build_flags"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/","text":"Waveshare TFT Touch Shield ~ more images... Waveshare has a line of TFT Touch Shields for Arduino which are also plug-and-play compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 board. Unlike many other common Arduino UNO shields the Waveshare displays have an SPI interface with resistive touch controller and backlight control . Be sure to check if the LCD_BL , LCD_CS and TP_CS pins are present. If these pins are missing, the screen won't work with the pre-compiled builds. Models ~ There are 3 models of this TFT shield: Model 2.8\" Rev 2.1 3.5inch 4.0inch SKU 10684 13506 13587 Resolution 320x240 480x320 480x320 TFT controller ST7789 (Rev 2.1 only) ILI9486 ILI9486 Interface SPI SPI SPI Touchscreen Resistive Resistive Resistive Touch controller XPT2046 XPT2046 XPT2046 SD Card yes yes yes Screen dimming yes yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Backlight Control ~ All three models come with an LCD_BL pin that allows for backlight control. It is connected to GPIO13 on the D1 R32 development board. Documentation ~ Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\" Configuration ~ Note By default the DIP switches on the display are set in the ICSP position instead of the SPI position. If your board does not include an ICSP header, you need to switch the display over to use the SPI pins. To use the MISO , MOSI and SCLK SPI pins you first need to peel of the orange tape that sticks on top of the dip switches. Then move all 3 DIP switches to the ON position with a tiny screwdriver. The 2.8\" model has 3 solder jumpers SB1 , SB2 and SB3 that need to be bridged instead! Development Boards ~ D1 R32 ~ The Waveshare TFT Touch Shields are compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 development board. It contains an ESP32-WROOM module with 4MB flash. Warning The D1 R32 ESP32 board may suffer from brown-out reboots if not powered adequately. Arducam IoTai ESP32 ~ Onboard 4MB PSRAM, 4MByte Flash To be tested Adafruit Metro ESP32-S2 ~ With 4 MByte of Flash and 2 MByte of PSRAM Note This board has not been tested yet!","title":"Waveshare TFT Touch Shield"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#waveshare-tft-touch-shield","text":"more images... Waveshare has a line of TFT Touch Shields for Arduino which are also plug-and-play compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 board. Unlike many other common Arduino UNO shields the Waveshare displays have an SPI interface with resistive touch controller and backlight control . Be sure to check if the LCD_BL , LCD_CS and TP_CS pins are present. If these pins are missing, the screen won't work with the pre-compiled builds.","title":"Waveshare TFT Touch Shield"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#models","text":"There are 3 models of this TFT shield: Model 2.8\" Rev 2.1 3.5inch 4.0inch SKU 10684 13506 13587 Resolution 320x240 480x320 480x320 TFT controller ST7789 (Rev 2.1 only) ILI9486 ILI9486 Interface SPI SPI SPI Touchscreen Resistive Resistive Resistive Touch controller XPT2046 XPT2046 XPT2046 SD Card yes yes yes Screen dimming yes yes yes Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com Buy Amazon US Amazon UK Amazon DE Amazon FR Amazon ES Amazon NL AliExpress Waveshare.com","title":"Models"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#backlight-control","text":"All three models come with an LCD_BL pin that allows for backlight control. It is connected to GPIO13 on the D1 R32 development board.","title":"Backlight Control"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#documentation","text":"Please visit the Waveshare Wiki pages for more information, schematics and demo code: Waveshare Wiki TFT Touch Shield 2.8\" Rev 2.1 TFT Touch Shield 3.5\" TFT Touch Shield 4.0\"","title":"Documentation"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#configuration","text":"Note By default the DIP switches on the display are set in the ICSP position instead of the SPI position. If your board does not include an ICSP header, you need to switch the display over to use the SPI pins. To use the MISO , MOSI and SCLK SPI pins you first need to peel of the orange tape that sticks on top of the dip switches. Then move all 3 DIP switches to the ON position with a tiny screwdriver. The 2.8\" model has 3 solder jumpers SB1 , SB2 and SB3 that need to be bridged instead!","title":"Configuration"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#development-boards","text":"","title":"Development Boards"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#d1-r32","text":"The Waveshare TFT Touch Shields are compatible with the ESPDUINO-32 aka. Wemos \u201cTTGo\u201d D1 R32 development board. It contains an ESP32-WROOM module with 4MB flash. Warning The D1 R32 ESP32 board may suffer from brown-out reboots if not powered adequately.","title":"D1 R32"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#arducam-iotai-esp32","text":"Onboard 4MB PSRAM, 4MByte Flash To be tested","title":"Arducam IoTai ESP32"},{"location":"hardware/waveshare/waveshare-tft-touch-shield/#adafruit-metro-esp32-s2","text":"With 4 MByte of Flash and 2 MByte of PSRAM Note This board has not been tested yet!","title":"Adafruit Metro ESP32-S2"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/","text":"WT-86-32-3ZW1 ~ Warning This product with ESP32-S2 is not sold anymore and will soon become obsolete. Please get the ESP32-S3 model instead. The Wireless-Tag WT-86-32-3ZW1 is a 86x86mm touchscreen with 4 relays that can be mounted in a standard 86x86mm wall-box. It is currently only available from Alibaba for around US $40 excluding shipping. Features ~ Pros Cons 16 MB flash Display ghosting 8 MB PSram 320 kB SRAM (ESP32-S2) Price Can't fit in EU workbox Capacitive Touchscreen Issues ~ One issue we've noticed is temporary ghosting on the display reported by multiple users. When showing a UI with white, cyan or bright colors on a dark background, a dim ghost image of these bright colors can linger on the screen for some time after changing pages. If you notice this issue on your device, please report back in this Github discussion thread . Dimensions ~ Note The size of the PSU unit does not fit a regular EU wall-box and mounting it in a US wall-box needs testing. Flashing ~ All pins are conveniently broken out on the 2mm pitch female header. Make sure the USB port can deliver enough power. It is best to use a powered USB hub since most PC ports can not power the whole device. esptool.py --port COM6 erase_flash esptool.py --port COM6 write_flash 0x0 wt-86-32-3zw1_full_16MB_v0.6.3-dev_88a478d.bin --verify Gallery ~","title":"WT-86-32-3ZW1"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#wt-86-32-3zw1","text":"Warning This product with ESP32-S2 is not sold anymore and will soon become obsolete. Please get the ESP32-S3 model instead. The Wireless-Tag WT-86-32-3ZW1 is a 86x86mm touchscreen with 4 relays that can be mounted in a standard 86x86mm wall-box. It is currently only available from Alibaba for around US $40 excluding shipping.","title":"WT-86-32-3ZW1"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#features","text":"Pros Cons 16 MB flash Display ghosting 8 MB PSram 320 kB SRAM (ESP32-S2) Price Can't fit in EU workbox Capacitive Touchscreen","title":"Features"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#issues","text":"One issue we've noticed is temporary ghosting on the display reported by multiple users. When showing a UI with white, cyan or bright colors on a dark background, a dim ghost image of these bright colors can linger on the screen for some time after changing pages. If you notice this issue on your device, please report back in this Github discussion thread .","title":"Issues"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#dimensions","text":"Note The size of the PSU unit does not fit a regular EU wall-box and mounting it in a US wall-box needs testing.","title":"Dimensions"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#flashing","text":"All pins are conveniently broken out on the 2mm pitch female header. Make sure the USB port can deliver enough power. It is best to use a powered USB hub since most PC ports can not power the whole device. esptool.py --port COM6 erase_flash esptool.py --port COM6 write_flash 0x0 wt-86-32-3zw1_full_16MB_v0.6.3-dev_88a478d.bin --verify","title":"Flashing"},{"location":"hardware/wireless-tag/wt-86-32-3zw1/#gallery","text":"","title":"Gallery"},{"location":"hardware/wireless-tag/wt32-sc01-plus/","text":"WT32-SC01 Plus ~ Features ~ The SC01 Plus uses an ESP32-S3-WROVER module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there are some ports with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 8-bit Display Flashing the initial bootloader 2 MB PSram Serial Flashing tool recommended Capacitive Touchscreen JST 1.25mm Expansion headers IPS Viewing angles Sleek design The development board is powered via USB Type-C. Video ~ Cases ~ A 3D-printable case can be found on: https://www.printables.com/model/381026-wt32-sc01-plus-desk-case#preview","title":"WT32-SC01 Plus"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#wt32-sc01-plus","text":"","title":"WT32-SC01 Plus "},{"location":"hardware/wireless-tag/wt32-sc01-plus/#features","text":"The SC01 Plus uses an ESP32-S3-WROVER module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there are some ports with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 8-bit Display Flashing the initial bootloader 2 MB PSram Serial Flashing tool recommended Capacitive Touchscreen JST 1.25mm Expansion headers IPS Viewing angles Sleek design The development board is powered via USB Type-C.","title":"Features"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#video","text":"","title":"Video"},{"location":"hardware/wireless-tag/wt32-sc01-plus/#cases","text":"A 3D-printable case can be found on: https://www.printables.com/model/381026-wt32-sc01-plus-desk-case#preview","title":"Cases"},{"location":"hardware/wireless-tag/wt32-sc01/","text":"WT32-SC01 ~ Features ~ The WT32-SC01 incorporates an ESP32-WROVER-B module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 Display 4 MB flash on basic model 8 MB PSram Viewing angle in landscape mode Capacitive Touchscreen Mounting holes placement The development board is powered via USB Type-C. The basic version comes with only 4MB SPI Flash but there is a better WT32-SC01(16MB) SKU with a larger flash chip. Both models have 8MB of PSRAM. With 4MB flash available from: LCSC Seeed studio With 16MB flash available from: Alibaba Tip Please consider getting the model with 16MB flash size as it is more suitable for the large screen. Note The expansion connector has a 2.0mm pitch female header instead of the more common 2.54mm pitch. Datasheet Gallery ~ 3D Printed Case ~ Wt32-sc01 Case by mbenten on Sketchfab","title":"WT32-SC01"},{"location":"hardware/wireless-tag/wt32-sc01/#wt32-sc01","text":"","title":"WT32-SC01"},{"location":"hardware/wireless-tag/wt32-sc01/#features","text":"The WT32-SC01 incorporates an ESP32-WROVER-B module with a 3.5-inch capacitive touch display. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with GPIOs so you can expand the capabilities as needed. Pros Cons 480x320 Display 4 MB flash on basic model 8 MB PSram Viewing angle in landscape mode Capacitive Touchscreen Mounting holes placement The development board is powered via USB Type-C. The basic version comes with only 4MB SPI Flash but there is a better WT32-SC01(16MB) SKU with a larger flash chip. Both models have 8MB of PSRAM. With 4MB flash available from: LCSC Seeed studio With 16MB flash available from: Alibaba Tip Please consider getting the model with 16MB flash size as it is more suitable for the large screen. Note The expansion connector has a 2.0mm pitch female header instead of the more common 2.54mm pitch. Datasheet","title":"Features"},{"location":"hardware/wireless-tag/wt32-sc01/#gallery","text":"","title":"Gallery"},{"location":"hardware/wireless-tag/wt32-sc01/#3d-printed-case","text":"Wt32-sc01 Case by mbenten on Sketchfab","title":"3D Printed Case"},{"location":"hardware/yeacreate/nscreen32/","text":"YeaCreate Nscreen32 ~ Features ~ The Nscreen32 uses an ESP32-WROVER-IE module with a large 4-inch capacitive touch display. The display is connected via an 8-bit parallel bus resulting in a fast performance. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with 6 GPIOs (4 input only, RX & TX) so you add inputs if needed. The development board can be powered via micro USB or the 5V-in JST connector. Pros Cons 8-bit parallel display No backlight control 16 MB flash + 8 MB PSram Bright white power LED Capacitive Touchscreen Viewing angles External antenna YeaCreate Store Backlight Control ~ Unfortunately, there is no support for backlight control . The display is always-on. With a small hack it is possible to control the backlight using a PNP transistor connected to GPIO0 , R8 and 3.3V . Documentation ~ Some example projects and the schematics for the Nscreen32 can be found on the Yeacreate Github repository. Github Repo Schematics Product Video ~ Nscreen32 is the first device to receive the LVGL Certified Board label: Enclosure ~ We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Yeacreate"},{"location":"hardware/yeacreate/nscreen32/#yeacreate-nscreen32","text":"","title":"YeaCreate Nscreen32"},{"location":"hardware/yeacreate/nscreen32/#features","text":"The Nscreen32 uses an ESP32-WROVER-IE module with a large 4-inch capacitive touch display. The display is connected via an 8-bit parallel bus resulting in a fast performance. openHASP can take advantage of the 320x480 resolution to show a large custom user-interface. On the back there is an expansion port with 6 GPIOs (4 input only, RX & TX) so you add inputs if needed. The development board can be powered via micro USB or the 5V-in JST connector. Pros Cons 8-bit parallel display No backlight control 16 MB flash + 8 MB PSram Bright white power LED Capacitive Touchscreen Viewing angles External antenna YeaCreate Store","title":"Features"},{"location":"hardware/yeacreate/nscreen32/#backlight-control","text":"Unfortunately, there is no support for backlight control . The display is always-on. With a small hack it is possible to control the backlight using a PNP transistor connected to GPIO0 , R8 and 3.3V .","title":"Backlight Control"},{"location":"hardware/yeacreate/nscreen32/#documentation","text":"Some example projects and the schematics for the Nscreen32 can be found on the Yeacreate Github repository. Github Repo Schematics","title":"Documentation"},{"location":"hardware/yeacreate/nscreen32/#product-video","text":"Nscreen32 is the first device to receive the LVGL Certified Board label:","title":"Product Video"},{"location":"hardware/yeacreate/nscreen32/#enclosure","text":"We don't have any 3D printable enclosure yet to share here. If you have a case for this board, please let us know so we can share it here.","title":"Enclosure"},{"location":"integrations/home-assistant/howto/","text":"Home Assistant ~ The openHASP Custom Component simplifies synchronization of objects on one or more openHASP plates with Home Assistant entities. You can map any service supported by any entity in Home Assistant to any object event in openHASP. Moreover, you can set any property of any object in openHASP to any value from Home Assistant. This powerful concept gives you full freedom to create a completely customized, hardware-based control user interface for your home automation. We call plate any device running openHASP in your system. Note Before going forward make sure you have installed the MQTT add-on in Home Assistant and the option Enable Discovery is indeed enabled in the MQTT integration service. A working MQTT add-on with discovery enabled is a prerequisite for using the openHASP custom component. Installation ~ You have the option to install the custom component using HACS or via manual download: Using HACS Manual Install Install using HACS in one-click. This is the preferred and recommended method, as HACS provides a very effective way to keep the component updated and/or choose between various versions. Goto Home Assistant > HACS > Integrations . Click the Explore & Add Repositories button. Search for openHASP and click on the openHasp logo. Click Install this repository in HACS . Note: To install the current unstable development version select the Main . Click Install Reboot Home-Assistant Alternatively, you can also install it manually: Download ZIP Using the tool of choice open the directory (folder) for your HA configuration (where you find configuration.yaml ). If you do not have a custom_components directory there, you need to create it. In the custom_components directory create a new folder called openhasp . Download all the files from the custom_components/openhasp/ directory in this repository. Place the files you downloaded in the new directory you created. Edit your configuration.yaml file add an entry similar to the example below. Restart Home Assistant Note The download {target= blank} link points to the actual _development code in the master branch. Warning You have to use component version consistently with the firmware version on your plates. For example, if your plates are at firmware version 0.7.x , you also need to use component version 0.7.y to ensure interoperability. Only the first two digits matter, i.e. 0.7 , the last one can be different. Home Assistant will show a warning if it finds a version mismatch. Note that you can only have one version of the component installed at a time so a mix of plate firmware versions is not supported. Configuration ~ First prepare your plates to be integrated with Home Assistant (follow steps in order): Connect your plates to the network . Static DHCP or fixed IP is not needed as communication only happens through MQTT. Set the GPIO configuration corresponding to your hardware (important for them to be detected as entities), save and reboot. Restart Home Assistant. Set the MQTT server settings and make sure each plate has a unique node name, save and reboot. The component will automatically discover the plates and you will see them appearing in Lovelace UI's Configuration > Devices & Services > openHASP . When Home Assistant detects your plate, you will have to give it a name. In the examples below both name and node name is plate35 . You will be presented with options to set the backlight brightness level when the plate is idle and optionally you can set a path to a centrally located pages.jsonl file containing design for this plate - the component can send the contents of the file when the plate connects. From v0.6.3 of the component this file can also be a file with a .json extension. See the JSON Files section below. Note If you opt to store the pages.jsonl file on Home Assistant server, it will only be loaded on start of Home Assistant and reloaded on plate availability (becoming online). Optionally you should also check how to handle the offline state of the plate. Currently you will get a warning that you need to add manual configuration for the objects in your configuration.yaml , that's no problem, read ahead. Example ~ To add an openHASP plate to your installation with a sample configuration, upload a pages.jsonl file with the following content to your plate first: 1 2 3 4 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"openHASP\" , \"value_font\" : 22 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"mode\" : \"break\" , \"align\" : 1 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 10 , \"y\" : 140 , \"w\" : 170 , \"h\" : 30 , \"options\" : \"Apples\\nBananas\\nOranges\\nMelon\" } { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" } Assuming your plate's configured MQTT node name is plate35 , add the following to your configuration.yaml file (Home Assistant will deliberately ask for it when finished autodetection procedure): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 openhasp : plate35 : objects : - obj : \"p0b1\" # temperature label on all pages properties : \"text\" : '{{ states(\"sensor.my_room_temperature\") }}\u00b0C' - obj : \"p1b2\" # light-switch toggle button properties : \"val\" : '{{ 1 if states(\"light.my_room\") == \"on\" else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_room\", \"on\") else \"\\uE335\" | e }}' event : \"up\" : - service : homeassistant.toggle entity_id : \"light.my_room\" - obj : \"p1b3\" # dropdown event : \"changed\" : - service : persistent_notification.create data : message : I like {{ text }} Note The Home Assistant Custom Component is not limited to setting val and text properties on UI objects! There is nothing stopping you from using the full suite of template functions like state_attr in your templates to drive more sophisticated behaviors. See the Example Automations for more. Variable definitions ~ openhasp: (Required) The platform identifier. Required once in the configuration. plate35: (Required) Your plate identifier slug. For each plate in your system, such an entry is required, has to be unique. It is generated automatically from the plate name you gave during discovery, which by default equals to the HASP Node Name set in the plate's configuration . objects: (Optional) Definition of the objects reacting to changes in Home Assistant, or generating events for Home Assistant. obj: (string) (Required) The object identifier which we want to integrate with Home Assistant. Its name has the form pXbY where X represents the page where the object is located, and Y represents the id of the object on that page. properties: (Optional) List containing the properties of the object which we want to modify based on changes occurring in Home Assistant. In the example above text property gets updated whenever sensor.my_room_temperature changes. event: (Optional) List containing the events generated by the object when touched on the screen. These are object-specific and can be observed accurately with an MQTT client. Each event defines a list of services which will be processed in order (like actions list in an automation). In the example above, when object p1b2 (which is a toggle button) generates the on event, light.my_room will be turned on by the service call light.turn_on as specified in the event config. And similarly when off event comes through MQTT, the light will be turned off by the corresponding service call. Note Any variable coming from the MQTT message can be used between curly brackets and passed to the service call. In the example above when object p1b3 (which is a dropdown selector) generates the changed event, a persistent notification will appear in Home Assistant's Lovelace interface containing the selected text from the object, which was passed over from the MQTT message. See object events for more types of generated events. Reloading the configuration ~ After you make changes to the configuration of the plate you can apply them by either restarting Home Assistant or by reloading the integration from Lovelace user interface with option found in Configuration > Devices & Services > openHASP > (your plate >) 3dots menu > Reload . Note that this has to be done individually for each configured plate. You can achieve the same by with a service too: 1 2 3 service : homeassistant.reload_config_entry data : entry_id : 95f7d6fe3fa5f4e242797e9ae4a5dd1d With the entry_id found in .storage/core.config_entries file from your main Home Assistant configuration directory (do NOT edit this file!). Configuration tips ~ Multiple plates ~ If you have multiple plates you can add them all using different plate identifiers. Their configured topics have to be unique too: 1 2 3 4 5 6 7 8 9 10 openhasp : plate_my_room_1 : objects : # ... plate_my_room_2 : objects : # ... plate_my_room_3 : objects : # ... Split configuration ~ You can use Home Assistant's split configuration to help better organizing your config files. Instead of keeping the configuration of all openHASP plates in Home Assistant's main config file, you can keep openHASP config separately, by adding only this to configuration.yaml : openhasp: !include openhasp.yaml After this, you can move your openHASP configuration starting with plate_my_room: level to your separate openhasp.yaml file and restart Home Assistant. Moreover, if you have multiple plates, you can keep each one in a separate config file, to achieve this, make it like: openhasp: !include_dir_merge_named openhasp_configs/ Create a directory openhasp_configs right near configuration.yaml , and put in it all your plates configuration (only with plate_my_room: level) in separate yaml files and restart Home Assistant. Services ~ This component implements some specific services to make interactions with the plate even more comfortable. openhasp.wakeup Wakes up the display when an external event has occurred, like a presence or a PIR motion sensor. openhasp.next_page Changes plate to the next page. openhasp.prev_page Changes plate to the previous page. openhasp.change_page Changes plate directly to the specified page number. openhasp.clear_page Clears the contents of the specified page number. If page number not specified, clears all the pages. openhasp.load_pages Loads new design from pages.jsonl file from full path on Home Assistant server. The file must be located in an authorized location defined by allowlist_external_dirs (in case of hassio /config/ is the directory where Home Assistant's configuration.yaml resides, so in case of a subdirectory called openhasp the full path would be e.g. /config/openhasp/pages.jsonl , and you need to add /config/openhasp/ to your allowlist_external_dirs ). Note The contents of the file are loaded line by line thus \"page\":X has to be defined for each object. Unless you clear the page first, the objects will be updated. For example, to allow read-access to the folder, add these lines to your configuration.yaml : 1 2 3 homeassistant : allowlist_external_dirs : - \"/config/openhasp\" openhasp.command Wraps up any command so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! openhasp.config Wraps up any raw submodule config so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! Check out the example configurations and automations to learn how to use these services within Home Assistant. JSON Files ~ From v0.6.3 pages file supplied in the plate config within home assistant can be a .json , files with this extension will be parsed differently and expect a JSON array containing objects or strings. Objects must be valid JSONL lines and strings can be used for comments. As this file is valid JSON whitespace will be ignored when parsing and removed before sending the JSONL data to the plate. If you are storing your plate config along with your HA config, this allows you to have more readable config which will be formatted in your editor of choice. Example: 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 [ { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : false , \"text\" : \"Normal Button\" , \"mode\" : \"break\" , \"align\" : \"center\" }, \"Comment string will be removed when parsing\" , { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"#FFD700 Toggle# Button\" , \"mode\" : \"break\" , \"align\" : \"center\" } ] Debugging ~ Add these lines to your main configuration.yaml configuration and restart Home Assistant: 1 2 3 4 logger : default : warning logs : custom_components.openhasp : debug Look for the debug messages in the home-assistant.log file.","title":"How-To"},{"location":"integrations/home-assistant/howto/#home-assistant","text":"The openHASP Custom Component simplifies synchronization of objects on one or more openHASP plates with Home Assistant entities. You can map any service supported by any entity in Home Assistant to any object event in openHASP. Moreover, you can set any property of any object in openHASP to any value from Home Assistant. This powerful concept gives you full freedom to create a completely customized, hardware-based control user interface for your home automation. We call plate any device running openHASP in your system. Note Before going forward make sure you have installed the MQTT add-on in Home Assistant and the option Enable Discovery is indeed enabled in the MQTT integration service. A working MQTT add-on with discovery enabled is a prerequisite for using the openHASP custom component.","title":"Home Assistant"},{"location":"integrations/home-assistant/howto/#installation","text":"You have the option to install the custom component using HACS or via manual download: Using HACS Manual Install Install using HACS in one-click. This is the preferred and recommended method, as HACS provides a very effective way to keep the component updated and/or choose between various versions. Goto Home Assistant > HACS > Integrations . Click the Explore & Add Repositories button. Search for openHASP and click on the openHasp logo. Click Install this repository in HACS . Note: To install the current unstable development version select the Main . Click Install Reboot Home-Assistant Alternatively, you can also install it manually: Download ZIP Using the tool of choice open the directory (folder) for your HA configuration (where you find configuration.yaml ). If you do not have a custom_components directory there, you need to create it. In the custom_components directory create a new folder called openhasp . Download all the files from the custom_components/openhasp/ directory in this repository. Place the files you downloaded in the new directory you created. Edit your configuration.yaml file add an entry similar to the example below. Restart Home Assistant Note The download {target= blank} link points to the actual _development code in the master branch. Warning You have to use component version consistently with the firmware version on your plates. For example, if your plates are at firmware version 0.7.x , you also need to use component version 0.7.y to ensure interoperability. Only the first two digits matter, i.e. 0.7 , the last one can be different. Home Assistant will show a warning if it finds a version mismatch. Note that you can only have one version of the component installed at a time so a mix of plate firmware versions is not supported.","title":"Installation"},{"location":"integrations/home-assistant/howto/#configuration","text":"First prepare your plates to be integrated with Home Assistant (follow steps in order): Connect your plates to the network . Static DHCP or fixed IP is not needed as communication only happens through MQTT. Set the GPIO configuration corresponding to your hardware (important for them to be detected as entities), save and reboot. Restart Home Assistant. Set the MQTT server settings and make sure each plate has a unique node name, save and reboot. The component will automatically discover the plates and you will see them appearing in Lovelace UI's Configuration > Devices & Services > openHASP . When Home Assistant detects your plate, you will have to give it a name. In the examples below both name and node name is plate35 . You will be presented with options to set the backlight brightness level when the plate is idle and optionally you can set a path to a centrally located pages.jsonl file containing design for this plate - the component can send the contents of the file when the plate connects. From v0.6.3 of the component this file can also be a file with a .json extension. See the JSON Files section below. Note If you opt to store the pages.jsonl file on Home Assistant server, it will only be loaded on start of Home Assistant and reloaded on plate availability (becoming online). Optionally you should also check how to handle the offline state of the plate. Currently you will get a warning that you need to add manual configuration for the objects in your configuration.yaml , that's no problem, read ahead.","title":"Configuration"},{"location":"integrations/home-assistant/howto/#example","text":"To add an openHASP plate to your installation with a sample configuration, upload a pages.jsonl file with the following content to your plate first: 1 2 3 4 { \"page\" : 1 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"openHASP\" , \"value_font\" : 22 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 } { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"mode\" : \"break\" , \"align\" : 1 } { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 10 , \"y\" : 140 , \"w\" : 170 , \"h\" : 30 , \"options\" : \"Apples\\nBananas\\nOranges\\nMelon\" } { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" } Assuming your plate's configured MQTT node name is plate35 , add the following to your configuration.yaml file (Home Assistant will deliberately ask for it when finished autodetection procedure): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 openhasp : plate35 : objects : - obj : \"p0b1\" # temperature label on all pages properties : \"text\" : '{{ states(\"sensor.my_room_temperature\") }}\u00b0C' - obj : \"p1b2\" # light-switch toggle button properties : \"val\" : '{{ 1 if states(\"light.my_room\") == \"on\" else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_room\", \"on\") else \"\\uE335\" | e }}' event : \"up\" : - service : homeassistant.toggle entity_id : \"light.my_room\" - obj : \"p1b3\" # dropdown event : \"changed\" : - service : persistent_notification.create data : message : I like {{ text }} Note The Home Assistant Custom Component is not limited to setting val and text properties on UI objects! There is nothing stopping you from using the full suite of template functions like state_attr in your templates to drive more sophisticated behaviors. See the Example Automations for more.","title":"Example"},{"location":"integrations/home-assistant/howto/#variable-definitions","text":"openhasp: (Required) The platform identifier. Required once in the configuration. plate35: (Required) Your plate identifier slug. For each plate in your system, such an entry is required, has to be unique. It is generated automatically from the plate name you gave during discovery, which by default equals to the HASP Node Name set in the plate's configuration . objects: (Optional) Definition of the objects reacting to changes in Home Assistant, or generating events for Home Assistant. obj: (string) (Required) The object identifier which we want to integrate with Home Assistant. Its name has the form pXbY where X represents the page where the object is located, and Y represents the id of the object on that page. properties: (Optional) List containing the properties of the object which we want to modify based on changes occurring in Home Assistant. In the example above text property gets updated whenever sensor.my_room_temperature changes. event: (Optional) List containing the events generated by the object when touched on the screen. These are object-specific and can be observed accurately with an MQTT client. Each event defines a list of services which will be processed in order (like actions list in an automation). In the example above, when object p1b2 (which is a toggle button) generates the on event, light.my_room will be turned on by the service call light.turn_on as specified in the event config. And similarly when off event comes through MQTT, the light will be turned off by the corresponding service call. Note Any variable coming from the MQTT message can be used between curly brackets and passed to the service call. In the example above when object p1b3 (which is a dropdown selector) generates the changed event, a persistent notification will appear in Home Assistant's Lovelace interface containing the selected text from the object, which was passed over from the MQTT message. See object events for more types of generated events.","title":"Variable definitions"},{"location":"integrations/home-assistant/howto/#reloading-the-configuration","text":"After you make changes to the configuration of the plate you can apply them by either restarting Home Assistant or by reloading the integration from Lovelace user interface with option found in Configuration > Devices & Services > openHASP > (your plate >) 3dots menu > Reload . Note that this has to be done individually for each configured plate. You can achieve the same by with a service too: 1 2 3 service : homeassistant.reload_config_entry data : entry_id : 95f7d6fe3fa5f4e242797e9ae4a5dd1d With the entry_id found in .storage/core.config_entries file from your main Home Assistant configuration directory (do NOT edit this file!).","title":"Reloading the configuration"},{"location":"integrations/home-assistant/howto/#configuration-tips","text":"","title":"Configuration tips"},{"location":"integrations/home-assistant/howto/#services","text":"This component implements some specific services to make interactions with the plate even more comfortable. openhasp.wakeup Wakes up the display when an external event has occurred, like a presence or a PIR motion sensor. openhasp.next_page Changes plate to the next page. openhasp.prev_page Changes plate to the previous page. openhasp.change_page Changes plate directly to the specified page number. openhasp.clear_page Clears the contents of the specified page number. If page number not specified, clears all the pages. openhasp.load_pages Loads new design from pages.jsonl file from full path on Home Assistant server. The file must be located in an authorized location defined by allowlist_external_dirs (in case of hassio /config/ is the directory where Home Assistant's configuration.yaml resides, so in case of a subdirectory called openhasp the full path would be e.g. /config/openhasp/pages.jsonl , and you need to add /config/openhasp/ to your allowlist_external_dirs ). Note The contents of the file are loaded line by line thus \"page\":X has to be defined for each object. Unless you clear the page first, the objects will be updated. For example, to allow read-access to the folder, add these lines to your configuration.yaml : 1 2 3 homeassistant : allowlist_external_dirs : - \"/config/openhasp\" openhasp.command Wraps up any command so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! openhasp.config Wraps up any raw submodule config so that it can be called against the entity_id of the plate. Useful in Automations and Blueprints. Warning This service handles data without input validation. Only for advanced users. No support for any problems caused by using this! Check out the example configurations and automations to learn how to use these services within Home Assistant.","title":"Services"},{"location":"integrations/home-assistant/howto/#json-files","text":"From v0.6.3 pages file supplied in the plate config within home assistant can be a .json , files with this extension will be parsed differently and expect a JSON array containing objects or strings. Objects must be valid JSONL lines and strings can be used for comments. As this file is valid JSON whitespace will be ignored when parsing and removed before sending the JSONL data to the plate. If you are storing your plate config along with your HA config, this allows you to have more readable config which will be formatted in your editor of choice. Example: 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 [ { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : false , \"text\" : \"Normal Button\" , \"mode\" : \"break\" , \"align\" : \"center\" }, \"Comment string will be removed when parsing\" , { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"#FFD700 Toggle# Button\" , \"mode\" : \"break\" , \"align\" : \"center\" } ]","title":"JSON Files"},{"location":"integrations/home-assistant/howto/#debugging","text":"Add these lines to your main configuration.yaml configuration and restart Home Assistant: 1 2 3 4 logger : default : warning logs : custom_components.openhasp : debug Look for the debug messages in the home-assistant.log file.","title":"Debugging"},{"location":"integrations/home-assistant/sampl_autom/","text":"Display of the current album cover of a media player ~ Combined with a media player entity which supports entity_picture attribute, you can automate display of that using the push_image service of the Custom Component. On the plate (named plate_livingroom in this example) you'd have two objects, first a rectangular object with rounded corners, secod an image object placed inside of it. It's hidden by default so you could place this on top of your existing media player controls, and have it pop up only when there's a cover present. To look nice together use the clip_corner property: { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"obj\" , \"x\" : 3 , \"y\" : 48 , \"w\" : 200 , \"h\" : 200 , \"radius\" : 6 , \"clip_corner\" : 1 , \"hidden\" : 1 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"img\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 200 , \"h\" : 200 , \"parentid\" : 15 , \"src\" : \"\" , \"auto_size\" : 1 } The automation below takes care of unhiding them when a cover appears on the sound_livingroom media player, updating the picture when it changes and hiding them again when the player drops the entity_picture attribute (it's stopped or the played media doesn't have a corresponding picture): 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 - id : openhasp-sound_livingroom-detect-mediaplayer-coverart alias : openhasp-sound_livingroom-detect-mediaplayer-coverart trigger : - platform : state entity_id : media_player.sound_livingroom condition : - condition : template value_template : > {{ trigger.from_state.attributes.entity_picture != trigger.to_state.attributes.entity_picture }} action : - choose : - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') != None }}\" sequence : - service : openhasp.push_image target : entity_id : openhasp.plate_livingroom data : image : http://ip.of.your.ha:8123{{ state_attr('media_player.sound_livingroom','entity_picture') }} obj : p6b16 width : 200 height : 200 - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '0' - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') == None }}\" sequence : - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '1' Backlight ON (dimmed) if there's any light in the room, OFF otherwise ~ The night mode activates when all the lights are off and shutters are down below 25% (assuming it's dark enough for the backlight to be disturbing in such situation), the day mode activates otherwise. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. This will act directly on the plate in a certain room, as it is triggered by entities located in that room. If you have multiple plates in various rooms, you can create separate automations for each. 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 - id : openhasp-plate_myroom-day alias : \"openHASP Night mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":0}' - id : openhasp-plate_myroom-night alias : \"openHASP Day mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ not ( state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" ) }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":60}' Note the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes). Backlight ON (dimmed) during the day, OFF during the night for all the plates ~ The night mode activates when sun goes down, and the day mode activates when the sun comes up. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. Assuming your plate's configured MQTT group name is plates , this will affect all the plates in your system at once: 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 - id : openhasp-night alias : \"openHASP Night mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation below : -1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":120}' - id : openhasp-day alias : \"openHASP Day mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation above : 1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":0}' Note here too the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes). Turn ON moodlight when backlight goes OFF (and back) ~ If your plate has moodlights, it is useful in dark situations, when you don't want to have the screen backlit on all the time as above, but have the mood light on instead. During the day mood light doesn't light. Put your light.plate_my_room_moodlight to a Lovelace card entity row and select a nice color for moodlight. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - id : openhasp-moodlight-on alias : \"openHASP Moodlight ON when Backlight OFF\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'on' to : 'off' action : - service : light.turn_on target : entity_id : light.plate_my_room_moodlight - id : openhasp-moodlight-off alias : \"openHASP Moodlight OFF when Backlight ON\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'off' to : 'on' action : - service : light.turn_off target : entity_id : light.plate_my_room_moodlight Return to home page after some idle time ~ Apart from the idle times controlling backlight levels, one may want to return to page 1 after a while. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - id : openhasp-back-to-page-1 alias : \"openHASP back to page 1\" trigger : - platform : template value_template : \"{{ state_attr('openhasp.plate_my_room','idle') != 'off' }}\" for : \"00:05:00\" condition : - condition : template value_template : \"{{ states('openhasp.plate_my_room') != '1' and states('openhasp.plate_my_room') != 'unavailable' }}\" action : - service : openhasp.change_page target : entity_id : openhasp.plate_my_room data : page : 1 Prevent burn-in of the LCD screen ~ You can use this to protect and prolonge the lifetime of the LCD screens, thus being more green and generating less hazardous waste. Wall mounted LCD screens' main problem is that they display the same picture 99.999% of the time. Even if somebody turns off backlight during the night or dark periods, the LCD screen keeps showing the same picture, seen by nobody. There are high chances that this will lead to screen picture burn-in after a few years of operation. Pixel training One way to reduce this is to \"train\" the pixels periodically with completely different other content. Assuming your group name is configured as plates in your screens running openHASP, here is a possible solution to extend their life (all at once). The cycle runs for 30 seconds each time, can be stopped by touching. The trigger runs this 6 times each night. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - id : openhasp_antiburn_start_at_night alias : openHASP anti-burn-in start at night initial_state : 'on' trigger : - platform : time at : '00:20:00' - platform : time at : '01:20:00' - platform : time at : '02:20:00' - platform : time at : '03:20:00' - platform : time at : '04:20:00' - platform : time at : '05:20:00' action : - service : mqtt.publish data : topic : hasp/plates/command/antiburn payload : '1' Clear pixels when backlight off Another way to reduce the chance of burn-in is to clear the contents of the screen while the backlight is turned off, as nobody sees the pixels anyway. Just add these actions to the first automation example which draw an overlay with a black base object on page 0 when display is off, and deletes it when comes back on: for automation openhasp-moodlight-on , add to actions: 1 2 3 4 - service : mqtt.publish data : topic : hasp/plates/command/jsonl payload : '{\"page\":0,\"id\":99,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"hidden\":0,\"bg_grad_dir\":0,\"bg_color\":\"black\"}' for automation openhasp-moodlight-off , add to actions: 1 2 3 4 5 6 7 8 - service : mqtt.publish data : topic : hasp/plates/command/p0b99.hidden payload : '1' - service : mqtt.publish data : topic : hasp/plates/command/p0b99.delete payload : '' Don't forget to adjust the size of the object to your screen if it's not 240x320. Dynamically set UI element dimensions ~ Note This technique relies on small changes in the openHasp device firmware that should be present in all builds of 0.7 after 2021-01. openHasp devices report several device properties to the Custom Component... including tftWidth and tftHeight . These properties are exposed in home assistant as device attributes and can be used in template automations. Here is a modified version of the Display clock and temperature example configuration that will use a \"generic\" jsonl file that has no hard-coded layout attributes: x , y , w , h and will appear the same on devices with different resolutions and screen orientations. Tell the openHasp device to create three text labels. As we are not specifying x/y coordinates, when the device first powers on, all three labels will be drawn in the upper left corner with their default size/values. When plate00 comes online and connects to the MQTT broker, the openHasp Custom Component will be invoked and the yaml below will be executed. The templates will be executed and the computed x , y , w , h values for each UI component will be sent to the plate. 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 { \"page\" : 0 , \"comment\" : \"Default to page0 as the header and page/layout\" } { \"id\" : 1 , \"comment\" : \"Time in the top left\" , \"obj\" : \"label\" , \"text\" : \"00:00\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 2 , \"comment\" : \"Temp in the middle\" , \"obj\" : \"label\" , \"text\" : \"00.0\u00b0C\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 3 , \"comment\" : \"Humidity in the top right\" , \"obj\" : \"label\" , \"text\" : \"00.0%\" , \"bg_color\" : \"#2C3E50\" } Assuming that the above jsonl was deployed to a openHasp device named plate00 , configure the Home Assistant Custom Component with yaml like this: 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 # The top left corner is 0,0, X grows positive to the right and Y grows positive down plate00 : objects : # Header: Time - obj : \"p0b1\" properties : \"align\" : \"left\" \"text\" : \"{{ states('sensor.time') }}\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Temp - obj : \"p0b2\" properties : \"align\" : \"center\" \"text\" : \"{{ states('sensor.room_temperature') }}\u00b0C\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+hdrLblWd}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Humidity - obj : \"p0b3\" properties : \"align\" : \"right\" \"text\" : \"{{ states('sensor.room_humidity') }}%\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+(2*hdrLblWd)}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} You should be able to shift the screen orientation for plate00 by 90 degrees and restart the device to apply your change. When the device boots back up and connects to MQTT, openHasp should report a different value for it's tftHeight and tftWidth which will cause Home Assistant to re-evaluate the templates. A few seconds after connecting to MQTT, plate00 should have an updated layout that reflects it's new screen orientation.","title":"Example Automations"},{"location":"integrations/home-assistant/sampl_autom/#display-of-the-current-album-cover-of-a-media-player","text":"Combined with a media player entity which supports entity_picture attribute, you can automate display of that using the push_image service of the Custom Component. On the plate (named plate_livingroom in this example) you'd have two objects, first a rectangular object with rounded corners, secod an image object placed inside of it. It's hidden by default so you could place this on top of your existing media player controls, and have it pop up only when there's a cover present. To look nice together use the clip_corner property: { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"obj\" , \"x\" : 3 , \"y\" : 48 , \"w\" : 200 , \"h\" : 200 , \"radius\" : 6 , \"clip_corner\" : 1 , \"hidden\" : 1 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"img\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 200 , \"h\" : 200 , \"parentid\" : 15 , \"src\" : \"\" , \"auto_size\" : 1 } The automation below takes care of unhiding them when a cover appears on the sound_livingroom media player, updating the picture when it changes and hiding them again when the player drops the entity_picture attribute (it's stopped or the played media doesn't have a corresponding picture): 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 - id : openhasp-sound_livingroom-detect-mediaplayer-coverart alias : openhasp-sound_livingroom-detect-mediaplayer-coverart trigger : - platform : state entity_id : media_player.sound_livingroom condition : - condition : template value_template : > {{ trigger.from_state.attributes.entity_picture != trigger.to_state.attributes.entity_picture }} action : - choose : - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') != None }}\" sequence : - service : openhasp.push_image target : entity_id : openhasp.plate_livingroom data : image : http://ip.of.your.ha:8123{{ state_attr('media_player.sound_livingroom','entity_picture') }} obj : p6b16 width : 200 height : 200 - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '0' - conditions : - condition : template value_template : \"{{ state_attr('media_player.sound_livingroom','entity_picture') == None }}\" sequence : - service : openhasp.command target : entity_id : openhasp.plate_livingroom data : keyword : p6b15.hidden parameters : '1'","title":"Display of the current album cover of a media player"},{"location":"integrations/home-assistant/sampl_autom/#backlight-on-dimmed-if-theres-any-light-in-the-room-off-otherwise","text":"The night mode activates when all the lights are off and shutters are down below 25% (assuming it's dark enough for the backlight to be disturbing in such situation), the day mode activates otherwise. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. This will act directly on the plate in a certain room, as it is triggered by entities located in that room. If you have multiple plates in various rooms, you can create separate automations for each. 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 - id : openhasp-plate_myroom-day alias : \"openHASP Night mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":0}' - id : openhasp-plate_myroom-night alias : \"openHASP Day mode based on My Room entities\" trigger : - platform : state entity_id : light.plate_myroom_light_12 - platform : state entity_id : light.plate_myroom_light_14 - platform : state entity_id : cover.myroom_1 - platform : state entity_id : cover.myroom_2 - platform : state entity_id : openhasp.plate_myroom from : 'unavailable' mode : restart condition : condition : and conditions : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" - condition : template value_template : > {{ not ( state_attr(\"cover.myroom_1\", \"current_position\") | float(default=0) > 25 or state_attr(\"cover.myroom_2\", \"current_position\") | float(default=0) > 25 or states(\"light.plate_myroom_light_12\") == \"on\" or states(\"light.plate_myroom_light_14\") == \"on\" ) }} action : - service : openhasp.config target : entity_id : openhasp.plate_myroom data : submodule : gui parameters : '{\"idle2\":60}' Note the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes).","title":"Backlight ON (dimmed) if there's any light in the room, OFF otherwise"},{"location":"integrations/home-assistant/sampl_autom/#backlight-on-dimmed-during-the-day-off-during-the-night-for-all-the-plates","text":"The night mode activates when sun goes down, and the day mode activates when the sun comes up. During the day, when the screen is after short idle, it dims to the level configured in Home Assistant, but never turns off. During the night, the screen turns off after the long idle period. Assuming your plate's configured MQTT group name is plates , this will affect all the plates in your system at once: 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 - id : openhasp-night alias : \"openHASP Night mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation below : -1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":120}' - id : openhasp-day alias : \"openHASP Day mode\" trigger : - platform : numeric_state entity_id : sun.sun attribute : elevation above : 1 condition : - condition : template value_template : \"{{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 > 2 }}\" action : - service : mqtt.publish data : topic : hasp/plates/config/gui payload : '{\"idle2\":0}' Note here too the condition which assures to avoid triggering the automations falsely when Home Assistant (re)starts (allows running the automation only when Home Assistant has been up for at least 2 minutes).","title":"Backlight ON (dimmed) during the day, OFF during the night for all the plates"},{"location":"integrations/home-assistant/sampl_autom/#turn-on-moodlight-when-backlight-goes-off-and-back","text":"If your plate has moodlights, it is useful in dark situations, when you don't want to have the screen backlit on all the time as above, but have the mood light on instead. During the day mood light doesn't light. Put your light.plate_my_room_moodlight to a Lovelace card entity row and select a nice color for moodlight. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - id : openhasp-moodlight-on alias : \"openHASP Moodlight ON when Backlight OFF\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'on' to : 'off' action : - service : light.turn_on target : entity_id : light.plate_my_room_moodlight - id : openhasp-moodlight-off alias : \"openHASP Moodlight OFF when Backlight ON\" trigger : - platform : state entity_id : light.plate_my_room_backlight from : 'off' to : 'on' action : - service : light.turn_off target : entity_id : light.plate_my_room_moodlight","title":"Turn ON moodlight when backlight goes OFF (and back)"},{"location":"integrations/home-assistant/sampl_autom/#return-to-home-page-after-some-idle-time","text":"Apart from the idle times controlling backlight levels, one may want to return to page 1 after a while. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - id : openhasp-back-to-page-1 alias : \"openHASP back to page 1\" trigger : - platform : template value_template : \"{{ state_attr('openhasp.plate_my_room','idle') != 'off' }}\" for : \"00:05:00\" condition : - condition : template value_template : \"{{ states('openhasp.plate_my_room') != '1' and states('openhasp.plate_my_room') != 'unavailable' }}\" action : - service : openhasp.change_page target : entity_id : openhasp.plate_my_room data : page : 1","title":"Return to home page after some idle time"},{"location":"integrations/home-assistant/sampl_autom/#prevent-burn-in-of-the-lcd-screen","text":"You can use this to protect and prolonge the lifetime of the LCD screens, thus being more green and generating less hazardous waste. Wall mounted LCD screens' main problem is that they display the same picture 99.999% of the time. Even if somebody turns off backlight during the night or dark periods, the LCD screen keeps showing the same picture, seen by nobody. There are high chances that this will lead to screen picture burn-in after a few years of operation.","title":"Prevent burn-in of the LCD screen"},{"location":"integrations/home-assistant/sampl_autom/#dynamically-set-ui-element-dimensions","text":"Note This technique relies on small changes in the openHasp device firmware that should be present in all builds of 0.7 after 2021-01. openHasp devices report several device properties to the Custom Component... including tftWidth and tftHeight . These properties are exposed in home assistant as device attributes and can be used in template automations. Here is a modified version of the Display clock and temperature example configuration that will use a \"generic\" jsonl file that has no hard-coded layout attributes: x , y , w , h and will appear the same on devices with different resolutions and screen orientations. Tell the openHasp device to create three text labels. As we are not specifying x/y coordinates, when the device first powers on, all three labels will be drawn in the upper left corner with their default size/values. When plate00 comes online and connects to the MQTT broker, the openHasp Custom Component will be invoked and the yaml below will be executed. The templates will be executed and the computed x , y , w , h values for each UI component will be sent to the plate. 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 { \"page\" : 0 , \"comment\" : \"Default to page0 as the header and page/layout\" } { \"id\" : 1 , \"comment\" : \"Time in the top left\" , \"obj\" : \"label\" , \"text\" : \"00:00\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 2 , \"comment\" : \"Temp in the middle\" , \"obj\" : \"label\" , \"text\" : \"00.0\u00b0C\" , \"bg_color\" : \"#2C3E50\" } { \"id\" : 3 , \"comment\" : \"Humidity in the top right\" , \"obj\" : \"label\" , \"text\" : \"00.0%\" , \"bg_color\" : \"#2C3E50\" } Assuming that the above jsonl was deployed to a openHasp device named plate00 , configure the Home Assistant Custom Component with yaml like this: 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 # The top left corner is 0,0, X grows positive to the right and Y grows positive down plate00 : objects : # Header: Time - obj : \"p0b1\" properties : \"align\" : \"left\" \"text\" : \"{{ states('sensor.time') }}\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Temp - obj : \"p0b2\" properties : \"align\" : \"center\" \"text\" : \"{{ states('sensor.room_temperature') }}\u00b0C\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+hdrLblWd}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} # Header: Humidity - obj : \"p0b3\" properties : \"align\" : \"right\" \"text\" : \"{{ states('sensor.room_humidity') }}%\" \"mode\" : \"loop\" ## # Draw the labels with a 1% margin from the top and sides \"x\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {{hdrHorMargin+(2*hdrLblWd)}} \"y\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {{hdrVrtMargin}} # Width is 1/3 of the screen width after subtracting margins ## \"w\" : >- {% set numObj = 3 %} {% set scnWd = state_attr('openhasp.plate00', 'tftWidth') | int %} {% set hdrHorMargin = (scnWd*0.01) | int %} {% set usableHdrWd = scnWd-(2*hdrHorMargin) %} {% set hdrLblWd = (usableHdrWd/numObj) | int %} {{hdrLblWd}} # Height is 10% of the screen, after margin ## \"h\" : >- {% set scnHt = state_attr('openhasp.plate00', 'tftHeight') | int %} {% set hdrVrtMargin = (scnHt*0.01) | int %} {% set hdrHt = (scnHt*0.1) | int %} {% set hdrLblHt = hdrHt-hdrVrtMargin %} {{hdrLblHt}} You should be able to shift the screen orientation for plate00 by 90 degrees and restart the device to apply your change. When the device boots back up and connects to MQTT, openHasp should report a different value for it's tftHeight and tftWidth which will cause Home Assistant to re-evaluate the templates. A few seconds after connecting to MQTT, plate00 should have an updated layout that reflects it's new screen orientation.","title":"Dynamically set UI element dimensions"},{"location":"integrations/home-assistant/sampl_conf/","text":"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 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"00.0\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 220 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"\u00b0C\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration all you need for the objects is: 1 2 3 4 5 6 7 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\" - obj : \"p0b6\" properties : \"text\" : \"{{ states('sensor.time') }}\" Note: ~ You can of course omit the second label object with the unit and use the same for both value and unit: 1 2 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00.0\u00b0C\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration you will add the unit to the value using the template: 1 2 3 4 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\u00b0C\" 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 { \"page\" : 1 , \"id\" : 2 , \"obj\" : \"btn\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 105 , \"h\" : 90 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 , \"align\" : 1 } 1 2 3 4 5 6 7 8 - obj : \"p1b2\" # switch, checkbox or btn with toggle true properties : \"val\" : '{{ 1 if is_state(\"light.my_lamp\", \"on\") else 0 }}' \"text\" : '{{ \"\\uE6E8\" if is_state(\"light.my_lamp\", \"on\") else \"\\uE335\" | e }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.my_lamp\" Dropdown (self-populating from an input_select) ~ 1 { \"page\" : 1 , \"id\" : 3 , \"obj\" : \"dropdown\" , \"x\" : 5 , \"y\" : 40 , \"w\" : 230 , \"h\" : 30 , \"options\" : \"\" } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - obj : \"p1b3\" # dropdown properties : \"options\" : > {% if (state_attr('input_select.my_dropdown_selections','options') != none and states('input_select.my_dropdown_selections') not in ['unavailable', 'unknown']) %}{%for item in state_attr('input_select.my_dropdown_selections','options')%}{{item+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"val\" : > {% if (state_attr('input_select.my_dropdown_selections','options') != none and states('input_select.my_dropdown_selections') not in ['unavailable', 'unknown']) %}{%for item in state_attr('input_select.my_dropdown_selections','options')%} {{loop.index -1 if item == states('input_select.my_dropdown_selections') }} {%-endfor%}{% endif %} event : \"changed\" : - service : input_select.select_option data : option : '{{ text }}' target : entity_id : input_select.my_dropdown_selections - service : persistent_notification.create data : message : Selected {{ text }} Color coded icons ~ Color code a WiFi icon according to RSSI reported by the plate openHASP config: (screen size 240x320) 1 { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 120 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"\\uE5A9\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } relevant openHASP-custom-component config: 1 2 3 - obj : \"p0b1\" properties : \"text_color\" : \"{% if -30 <= state_attr('openhasp.openhasp_plate','rssi') |int %}green{% elif -31 > state_attr('openhasp.openhasp_plate','rssi') |int >= -50 %}orange{% elif -51 > state_attr('openhasp.openhasp_plate','rssi') |int >= -80 %}tomato{% else %}red{% endif %}\" Color code a temperature icon according to sensor values openHASP config: (screen size 240x320) 1 { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 165 , \"y\" : 1 , \"w\" : 30 , \"h\" : 40 , \"text_font\" : \"2\" , \"text\" : \"\\uE50F\" , \"text_color\" : \"gray\" , \"bg_opa\" : 0 , \"border_width\" : 0 } relevant openHASP-custom-component config: 1 2 3 - obj : \"p0b3\" properties : \"text_color\" : \"{% if states('sensor.room_temperature') |int <= 21 %}#4682B4{% elif 21 < states('sensor.room_temperature') |int <= 26 %}green{% else %}red{% endif %}\" Variable sized icons ~ Have a fan icon which changes its size depending on the speed of the fan, and goes off the screen when the fan is off. openHASP config: 1 { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 1 , \"y\" : 1 , \"h\" : 35 , \"w\" : 35 , \"text\" : \"\\uE210\" , \"align\" : \"left\" , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"yellow\" } relevant openHASP-custom-component config: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - obj : \"p0b1\" properties : \"jsonl\" : > {% if is_state('input_select.fan_speed', 'Low') %} {\"text_font\":12,\"x\":6,\"y\":7} {%-elif is_state('input_select.fan_speed', 'Medium') %} {\"text_font\":16,\"x\":5,\"y\":6} {%-elif is_state('input_select.fan_speed', 'Hign') %} {\"text_font\":24,\"x\":1,\"y\":2} {%-elif is_state('input_select.fan_speed', 'Turbo') %} {\"text_font\":32,\"x\":-2,\"y\":-3} {%-elif is_state('input_select.fan_speed', 'OFF') %} {\"text_font\":12,\"x\":-10,\"y\":-10} {% endif %} 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 { \"page\" : 1 , \"id\" : 31 , \"obj\" : \"slider\" , \"x\" : 6 , \"y\" : 15 , \"w\" : 14 , \"h\" : 180 , \"min\" : 1 , \"max\" : 255 } { \"page\" : 1 , \"id\" : 32 , \"obj\" : \"cpicker\" , \"x\" : 30 , \"y\" : 10 , \"w\" : 180 , \"h\" : 180 } 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 - obj : \"p1b31\" # Light brightness properties : \"val\" : \"{{ state_attr('light.plate_moodlight', 'brightness') if state_attr('light.plate_moodlight', 'brightness') != None else 0 }}\" event : \"changed\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" - obj : \"p1b32\" # Light color properties : \"color\" : > {% if is_state('light.plate_moodlight','on') %} {% set rgb = state_attr('light.plate_moodlight','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" The brightness slider value gets updated from the 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 { \"page\" : 1 , \"id\" : 4 , \"obj\" : \"btn\" , \"x\" : 5 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 5 , \"obj\" : \"btn\" , \"x\" : 83 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 6 , \"obj\" : \"btn\" , \"x\" : 161 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } 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 - obj : \"p1b4\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b5\" properties : \"text\" : > {% if is_state('cover.cover_1', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.cover_1', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b6\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.cover_1\" 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 { \"page\" : 4 , \"id\" : 20 , \"obj\" : \"btnmatrix\" , \"x\" : 0 , \"y\" : 20 , \"w\" : 240 , \"h\" : 70 , \"options\" :[ \"\\uE05D\" , \"\\uE4DB\" , \"\\uE045\" ], \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 } 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 - obj : \"p4b20\" properties : \"options\" : > {% if is_state('cover.cover_1', 'closing') %} [\"\\uE05D\",\"\\uE4DB\",\"#FFFF00 \\uE045\"] {%-elif is_state('cover.cover_1', 'opening') %} [\"#FFFF00 \\uE05D\",\"\\uE4DB\",\"\\uE045\"] {%-else %} [\"\\uE05D\",\"\\uE4DB\",\"\\uE045\"] {% endif %} event : \"down\" : - service : > {% if val == 0 %} cover.open_cover {%-elif val == 1 %} cover.stop_cover {%-elif val == 2 %} cover.close_cover {% endif %} target : entity_id : cover.cover_1 Covers like in Lovelace ~ The icon behaves like in Lovelace. UI theme set to Hasp Light in plate's web interface. Your browser does not support the video tag. 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 { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 33 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 43 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 1\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 69 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 79 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 2\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 25 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 26 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } 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 - obj : \"p5b12\" properties : \"text\" : > {% if is_state('cover.my_cover', 'closing') %} {{ \"\\uE6C0\" | e }} {%-elif is_state('cover.my_cover', 'opening') %} {{ \"\\uE6C3\" | e }} {%-elif is_state('cover.my_cover', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.my_cover', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} - obj : \"p5b14\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b15\" event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b16\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.my_cover\" 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 { \"page\" : 6 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 , \"bg_opa\" : 0 , \"shadow_opa\" : 140 , \"shadow_color\" : \"black\" , \"shadow_width\" : 20 , \"shadow_spread\" : 0 } { \"page\" : 6 , \"id\" : 11 , \"obj\" : \"obj\" , \"x\" : 8 , \"y\" : 38 , \"w\" : 200 , \"h\" : 84 , \"click\" : 0 } { \"page\" : 6 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 48 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 83 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 14 , \"obj\" : \"bar\" , \"x\" : 8 , \"y\" : 117 , \"w\" : 200 , \"h\" : 5 , \"min\" : 0 , \"max\" : 100 , \"border_opa\" : 0 , \"pad_top\" : 0 , \"pad_bottom\" : 0 , \"pad_left\" : 0 , \"pad_right\" : 0 } { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"dropdown\" , \"x\" : 8 , \"y\" : 129 , \"w\" : 120 , \"h\" : 30 , \"options\" : \"Source1\\nSource2\\nSource3\" , \"direction\" : 3 , \"max_height\" : 300 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"dropdown\" , \"x\" : 133 , \"y\" : 129 , \"w\" : 75 , \"h\" : 30 , \"options\" : \"Jazz\\nPop\\nRock\" , \"direction\" : 2 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 17 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 166 , \"w\" : 50 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AE\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 18 , \"obj\" : \"btn\" , \"x\" : 66 , \"y\" : 166 , \"w\" : 83 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE40A\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 19 , \"obj\" : \"btn\" , \"x\" : 157 , \"y\" : 166 , \"w\" : 51 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AD\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 20 , \"obj\" : \"slider\" , \"x\" : 212 , \"y\" : 38 , \"w\" : 20 , \"h\" : 244 , \"min\" : 0 , \"max\" : 100 , \"val\" : 85 } { \"page\" : 6 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE425\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 60 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE457\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 111 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE49E\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 163 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE57E\" , \"text_font\" : 32 } 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 - obj : \"p6b12\" # artist label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_artist') if state_attr('media_player.sound_my_room1','media_artist') else '-' }}\" - obj : \"p6b13\" # title label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_title') if state_attr('media_player.sound_my_room1','media_title') else '-' }}\" - obj : \"p6b15\" # sources list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','source_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{\"(no source)\\n\"|e}} {%- for source in state_attr('media_player.sound_my_room1','source_list') -%} {{source+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %} {% if state_attr('media_player.sound_my_room1','source') == None %}0{% else %} {%for source in state_attr('media_player.sound_my_room1','source_list')%} {{loop.index if source == state_attr('media_player.sound_my_room1','source') }} {%-endfor%}{%-endif %}{%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_source data : entity_id : media_player.sound_my_room1 source : \"{{ text }}\" - obj : \"p6b16\" # sound modes list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','sound_mode_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {%-for soundmode in state_attr('media_player.sound_my_room1','sound_mode_list')-%} {{soundmode+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %}{%for source in state_attr('media_player.sound_my_room1','sound_mode_list')%} {{loop.index -1 if source == state_attr('media_player.sound_my_room1','sound_mode') }} {%-endfor%}{% endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_sound_mode data : entity_id : media_player.sound_my_room1 sound_mode : \"{{ text }}\" - obj : \"p6b14\" # progressbar properties : \"max\" : \"{{ state_attr('media_player.sound_my_room1','media_duration') | int }}\" \"val\" : \"{{ state_attr('media_player.sound_my_room1','media_position') | int }}\" - obj : \"p6b18\" # play/pause/stop properties : \"text\" : > {% if is_state('media_player.sound_my_room1', 'playing') %} {{ \"\\uE3E4\" | e }} {%-else %} {{ \"\\uE40A\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_play_pause target : entity_id : media_player.sound_my_room1 \"long\" : - service : media_player.media_stop target : entity_id : media_player.sound_my_room1 - obj : \"p6b17\" # prev properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_previous_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b19\" # next properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_next_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b20\" # volume slider properties : \"val\" : > {% if (state_attr('media_player.sound_my_room1','volume_level') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{ state_attr('media_player.sound_my_room1','volume_level') * 100 | int(default=80) }} {%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" \"up\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" - obj : \"p6b21\" # power properties : \"text_color\" : \"{{ '#B00000' if states('media_player.sound_my_room1') == 'off' else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.toggle data : entity_id : media_player.sound_my_room1 - obj : \"p6b22\" # repeat properties : \"text\" : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} {{ \"\\uE458\" | e }} {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} {{ \"\\uE456\" | e }} {%-else %} {{ \"\\uE457\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.repeat_set data : entity_id : media_player.sound_my_room1 repeat : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} all {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} off {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'off') %} one {%-endif %} - obj : \"p6b23\" # shuffle properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} {{ \"\\uE49D\" | e }} {%-else %} {{ \"\\uE49E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.shuffle_set data : entity_id : media_player.sound_my_room1 shuffle : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} false {% else %} true {%-endif %} - obj : \"p6b24\" # mute properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} {{ \"\\uE75F\" | e }} {%-else %} {{ \"\\uE57E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.volume_mute data : entity_id : media_player.sound_my_room1 is_volume_muted : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} false {% else %} true {%-endif %} Note that the 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. Your browser does not support the video tag. relevant openHASP config: (screen size 240x320) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 20 , \"obj\" : \"arc\" , \"x\" : 5 , \"y\" : 37 , \"w\" : 230 , \"h\" : 230 , \"min\" : 170 , \"max\" : 300 , \"val\" : 250 , \"border_side\" : 0 , \"type\" : 0 , \"rotation\" : 0 , \"start_angle\" : 135 , \"end_angle\" : 45 , \"adjustable\" : \"true\" , \"line_width\" : 21 , \"line_width10\" : 21 , \"line_color10\" : \"#34bdeb\" , \"bg_opa\" : 0 , \"pad_top20\" : 5 , \"pad_bottom20\" : 5 , \"pad_left20\" : 5 , \"pad_right20\" : 5 , \"pad_top\" : 5 , \"pad_bottom\" : 5 , \"pad_left\" : 5 , \"pad_right\" : 5 } { \"page\" : 3 , \"id\" : 21 , \"obj\" : \"gauge\" , \"x\" : 28 , \"y\" : 28 , \"w\" : 175 , \"h\" : 175 , \"parentid\" : 20 , \"min\" : 170 , \"max\" : 300 , \"val\" : 224 , \"format\" : 1 , \"critical_value\" : 301 , \"label_count\" : 14 , \"line_count\" : 27 , \"border_width\" : 0 , \"pad_top\" : 2 , \"pad_bottom\" : 2 , \"pad_left\" : 2 , \"pad_right\" : 2 , \"value_str\" : \"\u00b0C\" , \"value_ofs_y\" : 55 , \"value_font\" : 16 , \"bg_opa\" : 0 , \"line_width10\" : 3 , \"line_rounded10\" : 1 , \"line_color\" : \"#348feb\" , \"line_color60\" : \"#348feb\" , \"scale_grad_color\" : \"#eb4934\" , \"scale_grad_color60\" : \"#eb4934\" , \"scale_end_color60\" : \"#eb4934\" } { \"page\" : 3 , \"id\" : 22 , \"obj\" : \"obj\" , \"x\" : 85 , \"y\" : 85 , \"w\" : 60 , \"h\" : 60 , \"parentid\" : 20 , \"click\" : 0 , \"radius\" : 30 , \"border_width\" : 2 , \"border_opa\" : 200 } { \"page\" : 3 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 80 , \"y\" : 100 , \"w\" : 70 , \"h\" : 30 , \"parentid\" : 20 , \"text\" : \"22.4\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 24 , \"obj\" : \"obj\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"click\" : 0 , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 25 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"25\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 26 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 220 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" , \"border_width\" : 0 } { \"page\" : 3 , \"id\" : 30 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 235 , \"w\" : 240 , \"h\" : 80 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 , \"radius\" : 0 } { \"page\" : 3 , \"id\" : 31 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 32 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 33 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 41 , \"obj\" : \"switch\" , \"x\" : 35 , \"y\" : 10 , \"w\" : 60 , \"h\" : 30 , \"parentid\" : 31 , \"radius\" : 25 , \"radius20\" : 25 } { \"page\" : 3 , \"id\" : 42 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 32 , \"options\" : \"fan_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 43 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 33 , \"options\" : \"hvac_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } 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 - obj : \"p3b20\" # arc slider properties : \"val\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') | int * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"line_color1\" : > {% if is_state('climate.thermostat_1', 'cool') %} {{ \"#346beb\" }} {%-elif is_state('climate.thermostat_1', 'heat_cool') %} {{ \"#34bdeb\" }} {%-elif is_state('climate.thermostat_1', 'heat') %} {{ \"#eb3434\" }} {%-elif is_state('climate.thermostat_1', 'dry') %} {{ \"#ebeb34\" }} {%-elif is_state('climate.thermostat_1', 'fan_only') %} {{ \"#34eb77\" }} {%-else %} {{ \"#9f96b0\" }} {% endif %} event : \"changed\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" - obj : \"p3b21\" # gauge current temp properties : \"val\" : > {% if not (is_state('sensor.ble_atlaghomerseklet','unavailable') or is_state('sensor.ble_atlaghomerseklet','unknown')) %} {{ states('sensor.ble_atlaghomerseklet') | float (default=0) * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"critical_value\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 + 1 }} {%- endif %} \"label_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int + 1 }} {%- endif %} \"line_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ (state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int) * 2 + 1 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b23\" # label current temp (and +/- with short/long touch) properties : \"text\" : > {% if (is_state('sensor.temp_room_1','unavailable') or is_state('sensor.temp_room_1','unknown')) %} {{ \"--.-\" }} {%-else %} {{ states('sensor.temp_room_1') | round(1,default=0) }} {%- endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') + state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" \"long\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') - state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" - obj : \"p3b25\" # label target temp properties : \"text\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b41\" # on/off switch properties : \"val\" : \"{{ 0 if (is_state('climate.thermostat_1', 'off') or is_state('climate.thermostat_1', 'unavailable')) else 1 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"down\" : - service_template : > {% if val == 0 -%} climate.turn_on {% else -%} climate.turn_off {% endif -%} entity_id : \"climate.thermostat_1\" - obj : \"p3b30\" # tab dots event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p3b26.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 2 %} {{ \"#909090 \\u2022# #909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p3b42\" # dropdown with fan_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','fan_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {%- if mode == 'auto' -%} Automatic{{\"\\n\"|e}} {%- elif mode == 'low' -%} Low{{\"\\n\"|e}} {%- elif mode == 'medium' -%} Medium{{\"\\n\"|e}} {%- elif mode == 'high' -%} High{{\"\\n\"|e}} {%- elif mode == 'turbo' -%} Turbo{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {{loop.index -1 if mode == state_attr('climate.thermostat_1','fan_mode') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_fan_mode target : entity_id : climate.thermostat_1 data : fan_mode : > {% if text == \"Automatic\" -%} auto {% elif text == 'Low' -%} low {% elif text == 'Medium' -%} medium {% elif text == 'High' -%} high {% elif text == 'Turbo' -%} turbo {% endif -%} - obj : \"p3b43\" # dropdown with hvac_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','hvac_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {%- if mode == 'off' -%} Off{{\"\\n\"|e}} {%- elif mode == 'heat' -%} Heating{{\"\\n\"|e}} {%- elif mode == 'cool' -%} Cooling{{\"\\n\"|e}} {%- elif mode == 'heat_cool' -%} Heat/Cool{{\"\\n\"|e}} {%- elif mode == 'dry' -%} Drying{{\"\\n\"|e}} {%- elif mode == 'fan_only' -%} Fan only{{\"\\n\"|e}} {%- else -%} On{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {{loop.index -1 if mode == states('climate.thermostat_1') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_hvac_mode target : entity_id : climate.thermostat_1 data : hvac_mode : > {% if text == \"Off\" -%} off {% elif text == 'Heating' -%} heat {% elif text == 'Cooling' -%} cool {% elif text == 'Heat/Cool' -%} heat_cool {% elif text == 'Drying' -%} dry {% elif text == 'Fan only' -%} fan_only {% endif -%} 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 {target= blank} (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: light theme dark theme 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 { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"WEATHER\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"img\" , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 2 , \"auto_size\" : 1 , \"w\" : 128 , \"offset_x\" : -6 , \"offset_y\" : -10 } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"label\" , \"x\" : 100 , \"y\" : 10 , \"w\" : 130 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"date current\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 34 , \"w\" : 95 , \"h\" : 40 , \"align\" : \"center\" , \"text\" : \"00.0\u00b0C\" , \"parentid\" : 2 , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 17 , \"obj\" : \"label\" , \"x\" : 110 , \"y\" : 78 , \"w\" : 120 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"condition\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 19 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 95 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#000000 \\u2022# #909090 \\u2022#\" , \"parentid\" : 2 , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" } { \"page\" : 5 , \"id\" : 10 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 260 , \"parentid\" : 2 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 21 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 123 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+2\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 123 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 31 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 154 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+3\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 32 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 154 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 33 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 41 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 186 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+4\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 42 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 186 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 43 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 51 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 218 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+5\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 52 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 218 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 53 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 61 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 123 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+1\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 62 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 63 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 64 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 71 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 154 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+2\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 72 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 73 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 74 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 81 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 186 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+3\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 82 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 83 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 84 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 91 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 218 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+4\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 92 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 93 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 94 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } 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 - obj : \"p5b14\" # Icon properties : \"src\" : \"{{ 'L:/w-128-' + states('weather.openweathermap') + '.png' if not is_state('weather.openweathermap','unavailable') }}\" - obj : \"p5b15\" # Current date (adjust format to your needs) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set day = (states.weather.openweathermap.last_changed).strftime('%w') %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{- days[ day | int -1 ] }} {{ (states.weather.openweathermap.last_changed).strftime('%m. %d. ') }} {% endif -%} - obj : \"p5b16\" # Current temp (you can use your own outdoor temp sensor if you have one) properties : \"text\" : \"{{ state_attr('weather.openweathermap','temperature') |string + '\u00b0C' if not is_state('weather.openweathermap','unavailable') }}\" # or \"{{ states('sensor.your_own_temp_sensor') if not is_state('sensor.your_own_temp_sensor','unavailable') else '--' }}\u00b0C\" - obj : \"p5b17\" # Current weather condition properties : \"text\" : > {% if is_state('weather.openweathermap','clear-night') -%} Clear night {% elif is_state('weather.openweathermap','cloudy') -%} Cloudy {% elif is_state('weather.openweathermap','fog') -%} Fog {% elif is_state('weather.openweathermap','hail') -%} Hail {% elif is_state('weather.openweathermap','lightning') -%} Lightning {% elif is_state('weather.openweathermap','lightning-rainy') -%} Thunderstorms {% elif is_state('weather.openweathermap','partlycloudy') -%} Partly cloudy {% elif is_state('weather.openweathermap','pouring') -%} Pouring rain {% elif is_state('weather.openweathermap','rainy') -%} Rainy {% elif is_state('weather.openweathermap','snowy') -%} Snowy {% elif is_state('weather.openweathermap','snowy-rainy') -%} Snowy-rainy {% elif is_state('weather.openweathermap','sunny') -%} Sunny {% elif is_state('weather.openweathermap','windy') -%} Windy {% elif is_state('weather.openweathermap','windy-variant') -%} Windy {% elif is_state('weather.openweathermap','exceptional') -%} Exceptional {% elif is_state('weather.openweathermap','unavailable') -%} (not available) {% else -%} {{ states('weather.openweathermap') }} {% endif -%} - obj : \"p5b10\" # tab dots - MAKE SURE YOU UPDATE THIS ONE!! event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p5b19.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p5b21\" # Forecast time +1h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b22\" # Forecast temp +1h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[1]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b23\" # Forecast condition +1h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b31\" # Forecast time +2h (using Dawn/Morn etc instead of Today/Tomorrow) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set hour = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) | timestamp_custom(\"%-H\") | int %} {%- if 4 <= hour < 6 %} Dawning {%- elif 6 <= hour < 9 %} Morning {%- elif 9 <= hour < 12 %} Forenoon {%- elif 12 <= hour < 18 %} Afternoon {%- elif 18 <= hour < 23 %} Evening {%- elif 23 <= hour or hour < 4 %} Night {%- endif %} {{- \" \" + hour |string + \" o'clock\" }} {%- endif %} - obj : \"p5b32\" # Forecast temp +2h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[3]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b33\" # Forecast condition +2h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[3]['condition'] }}.png {%- endif %} - obj : \"p5b41\" # Forecast time +4h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[6]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b42\" # Forecast temp +4h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[6]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b43\" # Forecast condition +4h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[6]['condition'] }}.png {%- endif %} - obj : \"p5b51\" # Forecast time +8h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[12]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b52\" # Forecast temp +8h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[12]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b53\" # Forecast condition +8h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[12]['condition'] }}.png {%- endif %} - obj : \"p5b61\" # Forecast date +1d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[0]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b62\" # Forecast temp min +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b63\" # Forecast temp max +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b64\" # Forecast condition +1d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[0]['condition'] }}.png {%- endif %} - obj : \"p5b71\" # Forecast date +2d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b72\" # Forecast temp min +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b73\" # Forecast temp max +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b74\" # Forecast condition +2d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b81\" # Forecast date +3d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[2]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b82\" # Forecast temp min +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b83\" # Forecast temp max +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b84\" # Forecast condition +3d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[2]['condition'] }}.png {%- endif %} - obj : \"p5b91\" # Forecast date +4d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b92\" # Forecast temp min +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b93\" # Forecast temp max +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b94\" # Forecast condition +4d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[3]['condition'] }}.png {%- endif %} 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. fan perfume 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_width10\" : 19 , \"line_color10\" : \"#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 state_attr(\"input_select.fan_presets\",\"options\") is not none -%} {% 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 states('input_select.fan_presets') in ['unavailable', 'unknown', 'OFF'] else 255 }}\" \"jsonl\" : > {% if is_state('number.plate_test_page_number', '4') %} {% if is_state('input_select.fan_presets', 'Alap') %} {\"speed\":7000,\"line_color10\":\"#31de70\"} {%-elif is_state('input_select.fan_presets', 'K\u00f6z\u00e9p') %} {\"speed\":1700,\"line_color10\":\"#dede1f\"} {%-elif is_state('input_select.fan_presets', 'Magas') %} {\"speed\":800,\"line_color10\":\"#d6a11a\"} {%-elif is_state('input_select.fan_presets', 'Turb\u00f3') %} {\"speed\":250,\"line_color10\":\"#ff4a4a\"} {% endif %} {% else -%} {\"speed\":0} {% endif %} - obj : \"p4b54\" # Scent Diffuser ON/OFF button properties : \"val\" : '{{ 1 if is_state(\"fan.scent_diffuser_intensity\", \"on\") else 0 }}' \"enabled\" : \"{{ 'false' if states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 . Using tags ~ You can avoid too much code repetition when you have multiple similar objects on a page, doing the same thing with different entities, and you'd like to make accessible some advanced options too. Presenting everyting flat will overwhelm your user interface, so it would be better to just show the most used controls, and only display the advanced options in popups related to unique objects. Tag property was made to ease this task. Colored lights panel ~ In the example below we have four coloured lights. Squeezing the ON/OFF button, the color picker and the brightness selector for all four lights on a single page can be challenging - and the result will likely be useless on a small touch screen. Instead, we'll just place the toggle buttons with descriptive labels on the page, and we'll only display the color picker and the brightness selector on demand, in this case when the user touches the descriptive coloured label. While dynamically drawing these objects we're setting the tag property for the color picker and the slider to the entity_id of the light we want to adjust, so that when we're interacting with them, the Custom Component can know which light it has to send the adjustments to. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"COLOURED LIGHTS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"I.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"II.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"III.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"IV.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p5b11\" # toggle button for ON/OFF switching of light I. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_1\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_1\" - obj : \"p5b12\" # toggle button for ON/OFF switching of light II. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_2\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_2\" - obj : \"p5b13\" # toggle button for ON/OFF switching of light III. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_3\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_3\" - obj : \"p5b14\" # toggle button for ON/OFF switching of light IV. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_4\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_4\" - obj : \"p5b2\" # label showing the current color of light I. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_1','on') %} {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_1 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light I. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light I.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_1\",\"color\": {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_1\",\"val\": {{- state_attr('light.dmx_vbar_1', 'brightness') -}} } - obj : \"p5b3\" # label showing the current color of light II. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_2','on') %} {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_2 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light II. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light II.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_2\",\"color\": {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_2\",\"val\": {{- state_attr('light.dmx_vbar_2', 'brightness') -}} } - obj : \"p5b4\" # label showing the current color of light III. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_3','on') %} {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_3 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light III. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light III.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_3\",\"color\": {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_3\",\"val\": {{- state_attr('light.dmx_vbar_3', 'brightness') -}} } - obj : \"p5b5\" # label showing the current color of light IV. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_4','on') %} {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_4 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light IV. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light IV.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_4\",\"color\": {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_4\",\"val\": {{- state_attr('light.dmx_vbar_4', 'brightness') -}} } - obj : \"p5b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b201\" # set the color of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b202\" # set the brightness of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" brightness : \"{{ val }}\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete Without tags, the last 3 object definitions would have to be added for each light, and also it would be needed to be drawn separately for each light, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. Shutter control panel ~ In the second example, we have five windows with motorized shutters. In addition to the usual UP/STOP/DOWN buttons, the inhabitants want to have three shortcut positions for each shutter, and also a slider for free positioning. Useless to say that it's impossible to put all these on a page, and also it would be a pity to use up 5 pages just for these. We'll just put the most used, UP/STOP/DOWN buttons on the page (this already looks a bit much...) and we'll use a long press event on the middle STOP button to show a pop-up with the extra required settings related to the desired shutter. The tag here will be a JSON object referencing both the entity_id and the position specific to the desired shutter, eg. \"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"} , this will be set for the buttons and the slider appearing in the popup. Since the shutters are different sizes and types, the same intermediate physical position may correspond to different numeric values in Home Assistant. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 2 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"MOTORIZED COVERS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 2 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 7 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"I.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 53 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"II.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 99 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"III.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"IV.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 191 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"V.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 31 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 32 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 33 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 41 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 42 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 43 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 51 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 52 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 53 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p2b11\" # shutter I. up button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b13\" # shutter I. down button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b12\" # shutter I. middle stop button properties : \"text\" : > {% if is_state('cover.bigroom_i', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_i', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_i\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - I.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"54\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_i','current_position') -}} } - obj : \"p2b21\" # shutter II. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b23\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b22\" properties : \"text\" : > {% if is_state('cover.bigroom_ii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_ii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_ii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - II.\",\"align\":\"center\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"18\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_ii','current_position') -}} } - obj : \"p2b31\" # shutter III. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b33\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b32\" properties : \"text\" : > {% if is_state('cover.bigroom_iii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - III.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iii','current_position') -}} } - obj : \"p2b41\" # shutter IV. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b43\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b42\" properties : \"text\" : > {% if is_state('cover.bigroom_iv', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iv', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iv\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - IV.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iv','current_position') -}} } - obj : \"p2b51\" # shutter V. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b53\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b52\" properties : \"text\" : > {% if is_state('cover.bigroom_v', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_v', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_v\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - V.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"55\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"19\"},\"val\": {{- state_attr('cover.bigroom_v','current_position') -}} } - obj : \"p2b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b201\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b202\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b203\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b204\" # set the shutter position from the slider for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"up\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ val | int }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete Again - without tags, the last 5 object definitions would have to be added for each shutter, and also it would be needed to be drawn separately for each one, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. 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.","title":"Example Configurations"},{"location":"integrations/home-assistant/sampl_conf/#display-clock-and-temperature","text":"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 { \"page\" : 0 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 175 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"00.0\" , \"align\" : 2 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 220 , \"y\" : 5 , \"h\" : 30 , \"w\" : 45 , \"text\" : \"\u00b0C\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } { \"page\" : 0 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 3 , \"y\" : 5 , \"h\" : 30 , \"w\" : 62 , \"text\" : \"00:00\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } In component configuration all you need for the objects is: 1 2 3 4 5 6 7 objects : - obj : \"p0b4\" properties : \"text\" : \"{{ states('sensor.my_room_temperature') }}\" - obj : \"p0b6\" properties : \"text\" : \"{{ states('sensor.time') }}\"","title":"Display clock and temperature"},{"location":"integrations/home-assistant/sampl_conf/#some-basic-controls","text":"Jsonl and Home Assistant configuration:","title":"Some basic controls"},{"location":"integrations/home-assistant/sampl_conf/#color-coded-icons","text":"","title":"Color coded icons"},{"location":"integrations/home-assistant/sampl_conf/#variable-sized-icons","text":"Have a fan icon which changes its size depending on the speed of the fan, and goes off the screen when the fan is off. openHASP config: 1 { \"page\" : 0 , \"id\" : 1 , \"obj\" : \"label\" , \"x\" : 1 , \"y\" : 1 , \"h\" : 35 , \"w\" : 35 , \"text\" : \"\\uE210\" , \"align\" : \"left\" , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"yellow\" } relevant openHASP-custom-component config: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - obj : \"p0b1\" properties : \"jsonl\" : > {% if is_state('input_select.fan_speed', 'Low') %} {\"text_font\":12,\"x\":6,\"y\":7} {%-elif is_state('input_select.fan_speed', 'Medium') %} {\"text_font\":16,\"x\":5,\"y\":6} {%-elif is_state('input_select.fan_speed', 'Hign') %} {\"text_font\":24,\"x\":1,\"y\":2} {%-elif is_state('input_select.fan_speed', 'Turbo') %} {\"text_font\":32,\"x\":-2,\"y\":-3} {%-elif is_state('input_select.fan_speed', 'OFF') %} {\"text_font\":12,\"x\":-10,\"y\":-10} {% endif %}","title":"Variable sized icons"},{"location":"integrations/home-assistant/sampl_conf/#light-brightness-and-color","text":"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 { \"page\" : 1 , \"id\" : 31 , \"obj\" : \"slider\" , \"x\" : 6 , \"y\" : 15 , \"w\" : 14 , \"h\" : 180 , \"min\" : 1 , \"max\" : 255 } { \"page\" : 1 , \"id\" : 32 , \"obj\" : \"cpicker\" , \"x\" : 30 , \"y\" : 10 , \"w\" : 180 , \"h\" : 180 } 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 - obj : \"p1b31\" # Light brightness properties : \"val\" : \"{{ state_attr('light.plate_moodlight', 'brightness') if state_attr('light.plate_moodlight', 'brightness') != None else 0 }}\" event : \"changed\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight brightness : \"{{ val }}\" - obj : \"p1b32\" # Light color properties : \"color\" : > {% if is_state('light.plate_moodlight','on') %} {% set rgb = state_attr('light.plate_moodlight','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"up\" : - service : light.turn_on data : entity_id : light.plate_moodlight rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" The brightness slider value gets updated from the 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.","title":"Light brightness and color"},{"location":"integrations/home-assistant/sampl_conf/#cover-with-state-feedback","text":"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 { \"page\" : 1 , \"id\" : 4 , \"obj\" : \"btn\" , \"x\" : 5 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 5 , \"obj\" : \"btn\" , \"x\" : 83 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 1 , \"id\" : 6 , \"obj\" : \"btn\" , \"x\" : 161 , \"y\" : 140 , \"w\" : 73 , \"h\" : 60 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } 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 - obj : \"p1b4\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b5\" properties : \"text\" : > {% if is_state('cover.cover_1', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.cover_1', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.cover_1', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.cover_1\" - obj : \"p1b6\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.cover_1', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.cover_1','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.cover_1\"","title":"Cover with state feedback"},{"location":"integrations/home-assistant/sampl_conf/#cover-with-button-matrix","text":"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 { \"page\" : 4 , \"id\" : 20 , \"obj\" : \"btnmatrix\" , \"x\" : 0 , \"y\" : 20 , \"w\" : 240 , \"h\" : 70 , \"options\" :[ \"\\uE05D\" , \"\\uE4DB\" , \"\\uE045\" ], \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 } 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 - obj : \"p4b20\" properties : \"options\" : > {% if is_state('cover.cover_1', 'closing') %} [\"\\uE05D\",\"\\uE4DB\",\"#FFFF00 \\uE045\"] {%-elif is_state('cover.cover_1', 'opening') %} [\"#FFFF00 \\uE05D\",\"\\uE4DB\",\"\\uE045\"] {%-else %} [\"\\uE05D\",\"\\uE4DB\",\"\\uE045\"] {% endif %} event : \"down\" : - service : > {% if val == 0 %} cover.open_cover {%-elif val == 1 %} cover.stop_cover {%-elif val == 2 %} cover.close_cover {% endif %} target : entity_id : cover.cover_1","title":"Cover with button matrix"},{"location":"integrations/home-assistant/sampl_conf/#covers-like-in-lovelace","text":"The icon behaves like in Lovelace. UI theme set to Hasp Light in plate's web interface. Your browser does not support the video tag. 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 { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 33 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 43 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 1\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 37 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 69 , \"w\" : 35 , \"h\" : 35 , \"text\" : \"\\uF11D\" , \"align\" : 1 , \"text_font\" : 32 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 48 , \"y\" : 79 , \"w\" : 80 , \"h\" : 30 , \"text\" : \"Cover 2\" , \"align\" : 0 , \"text_font\" : 16 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 25 , \"obj\" : \"btn\" , \"x\" : 165 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } { \"page\" : 5 , \"id\" : 26 , \"obj\" : \"btn\" , \"x\" : 205 , \"y\" : 73 , \"w\" : 30 , \"h\" : 30 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 , \"bg_opa\" : 0 , \"border_opa\" : 0 , \"text_color\" : \"#053248\" } 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 - obj : \"p5b12\" properties : \"text\" : > {% if is_state('cover.my_cover', 'closing') %} {{ \"\\uE6C0\" | e }} {%-elif is_state('cover.my_cover', 'opening') %} {{ \"\\uE6C3\" | e }} {%-elif is_state('cover.my_cover', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.my_cover', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} - obj : \"p5b14\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b15\" event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.my_cover\" - obj : \"p5b16\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.my_cover\"","title":"Covers like in Lovelace"},{"location":"integrations/home-assistant/sampl_conf/#media-player","text":"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 { \"page\" : 6 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 , \"bg_opa\" : 0 , \"shadow_opa\" : 140 , \"shadow_color\" : \"black\" , \"shadow_width\" : 20 , \"shadow_spread\" : 0 } { \"page\" : 6 , \"id\" : 11 , \"obj\" : \"obj\" , \"x\" : 8 , \"y\" : 38 , \"w\" : 200 , \"h\" : 84 , \"click\" : 0 } { \"page\" : 6 , \"id\" : 12 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 48 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 13 , \"obj\" : \"label\" , \"x\" : 10 , \"y\" : 83 , \"w\" : 196 , \"h\" : 30 , \"text\" : \"-\" , \"mode\" : \"scroll\" , \"align\" : 1 } { \"page\" : 6 , \"id\" : 14 , \"obj\" : \"bar\" , \"x\" : 8 , \"y\" : 117 , \"w\" : 200 , \"h\" : 5 , \"min\" : 0 , \"max\" : 100 , \"border_opa\" : 0 , \"pad_top\" : 0 , \"pad_bottom\" : 0 , \"pad_left\" : 0 , \"pad_right\" : 0 } { \"page\" : 6 , \"id\" : 15 , \"obj\" : \"dropdown\" , \"x\" : 8 , \"y\" : 129 , \"w\" : 120 , \"h\" : 30 , \"options\" : \"Source1\\nSource2\\nSource3\" , \"direction\" : 3 , \"max_height\" : 300 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 16 , \"obj\" : \"dropdown\" , \"x\" : 133 , \"y\" : 129 , \"w\" : 75 , \"h\" : 30 , \"options\" : \"Jazz\\nPop\\nRock\" , \"direction\" : 2 , \"radius\" : 5 } { \"page\" : 6 , \"id\" : 17 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 166 , \"w\" : 50 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AE\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 18 , \"obj\" : \"btn\" , \"x\" : 66 , \"y\" : 166 , \"w\" : 83 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE40A\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 19 , \"obj\" : \"btn\" , \"x\" : 157 , \"y\" : 166 , \"w\" : 51 , \"h\" : 70 , \"toggle\" : false , \"text\" : \"\\uE4AD\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 20 , \"obj\" : \"slider\" , \"x\" : 212 , \"y\" : 38 , \"w\" : 20 , \"h\" : 244 , \"min\" : 0 , \"max\" : 100 , \"val\" : 85 } { \"page\" : 6 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 8 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE425\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 60 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE457\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 111 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE49E\" , \"text_font\" : 32 } { \"page\" : 6 , \"id\" : 24 , \"obj\" : \"btn\" , \"x\" : 163 , \"y\" : 241 , \"w\" : 45 , \"h\" : 40 , \"toggle\" : false , \"text\" : \"\\uE57E\" , \"text_font\" : 32 } 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 - obj : \"p6b12\" # artist label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_artist') if state_attr('media_player.sound_my_room1','media_artist') else '-' }}\" - obj : \"p6b13\" # title label properties : \"text\" : \"{{ state_attr('media_player.sound_my_room1','media_title') if state_attr('media_player.sound_my_room1','media_title') else '-' }}\" - obj : \"p6b15\" # sources list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','source_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{\"(no source)\\n\"|e}} {%- for source in state_attr('media_player.sound_my_room1','source_list') -%} {{source+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %} {% if state_attr('media_player.sound_my_room1','source') == None %}0{% else %} {%for source in state_attr('media_player.sound_my_room1','source_list')%} {{loop.index if source == state_attr('media_player.sound_my_room1','source') }} {%-endfor%}{%-endif %}{%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_source data : entity_id : media_player.sound_my_room1 source : \"{{ text }}\" - obj : \"p6b16\" # sound modes list properties : \"options\" : > {% if (state_attr('media_player.sound_my_room1','sound_mode_list') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {%-for soundmode in state_attr('media_player.sound_my_room1','sound_mode_list')-%} {{soundmode+\"\\n\"|e}}{%-if not loop.last%}{%-endif%}{%-endfor%}{%-endif %} \"val\" : > {% if states('media_player.sound_my_room1') not in ['unavailable', 'unknown'] %}{%for source in state_attr('media_player.sound_my_room1','sound_mode_list')%} {{loop.index -1 if source == state_attr('media_player.sound_my_room1','sound_mode') }} {%-endfor%}{% endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.select_sound_mode data : entity_id : media_player.sound_my_room1 sound_mode : \"{{ text }}\" - obj : \"p6b14\" # progressbar properties : \"max\" : \"{{ state_attr('media_player.sound_my_room1','media_duration') | int }}\" \"val\" : \"{{ state_attr('media_player.sound_my_room1','media_position') | int }}\" - obj : \"p6b18\" # play/pause/stop properties : \"text\" : > {% if is_state('media_player.sound_my_room1', 'playing') %} {{ \"\\uE3E4\" | e }} {%-else %} {{ \"\\uE40A\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_play_pause target : entity_id : media_player.sound_my_room1 \"long\" : - service : media_player.media_stop target : entity_id : media_player.sound_my_room1 - obj : \"p6b17\" # prev properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_previous_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b19\" # next properties : \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.media_next_track target : entity_id : media_player.sound_my_room1 - obj : \"p6b20\" # volume slider properties : \"val\" : > {% if (state_attr('media_player.sound_my_room1','volume_level') != none and states('media_player.sound_my_room1') not in ['unavailable', 'unknown']) %} {{ state_attr('media_player.sound_my_room1','volume_level') * 100 | int(default=80) }} {%-endif %} \"click\" : \"{{ 'false' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else 'true' }}\" event : \"changed\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" \"up\" : - service : media_player.volume_set data : entity_id : media_player.sound_my_room1 volume_level : \"{{ val | int / 100 }}\" - obj : \"p6b21\" # power properties : \"text_color\" : \"{{ '#B00000' if states('media_player.sound_my_room1') == 'off' else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.toggle data : entity_id : media_player.sound_my_room1 - obj : \"p6b22\" # repeat properties : \"text\" : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} {{ \"\\uE458\" | e }} {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} {{ \"\\uE456\" | e }} {%-else %} {{ \"\\uE457\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.repeat_set data : entity_id : media_player.sound_my_room1 repeat : > {% if is_state_attr('media_player.sound_my_room1', 'repeat', 'one') %} all {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'all') %} off {% elif is_state_attr('media_player.sound_my_room1', 'repeat', 'off') %} one {%-endif %} - obj : \"p6b23\" # shuffle properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} {{ \"\\uE49D\" | e }} {%-else %} {{ \"\\uE49E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.shuffle_set data : entity_id : media_player.sound_my_room1 shuffle : > {% if state_attr('media_player.sound_my_room1', 'shuffle') %} false {% else %} true {%-endif %} - obj : \"p6b24\" # mute properties : \"text\" : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} {{ \"\\uE75F\" | e }} {%-else %} {{ \"\\uE57E\" | e }} {%-endif %} \"text_opa\" : \"{{ '80' if states('media_player.sound_my_room1') in ['unavailable', 'unknown'] else '255' }}\" event : \"down\" : - service : media_player.volume_mute data : entity_id : media_player.sound_my_room1 is_volume_muted : > {% if state_attr('media_player.sound_my_room1', 'is_volume_muted') %} false {% else %} true {%-endif %} Note that the 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.","title":"Media player"},{"location":"integrations/home-assistant/sampl_conf/#generic-thermostatclimate","text":"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. Your browser does not support the video tag. relevant openHASP config: (screen size 240x320) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 10 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 3 , \"id\" : 20 , \"obj\" : \"arc\" , \"x\" : 5 , \"y\" : 37 , \"w\" : 230 , \"h\" : 230 , \"min\" : 170 , \"max\" : 300 , \"val\" : 250 , \"border_side\" : 0 , \"type\" : 0 , \"rotation\" : 0 , \"start_angle\" : 135 , \"end_angle\" : 45 , \"adjustable\" : \"true\" , \"line_width\" : 21 , \"line_width10\" : 21 , \"line_color10\" : \"#34bdeb\" , \"bg_opa\" : 0 , \"pad_top20\" : 5 , \"pad_bottom20\" : 5 , \"pad_left20\" : 5 , \"pad_right20\" : 5 , \"pad_top\" : 5 , \"pad_bottom\" : 5 , \"pad_left\" : 5 , \"pad_right\" : 5 } { \"page\" : 3 , \"id\" : 21 , \"obj\" : \"gauge\" , \"x\" : 28 , \"y\" : 28 , \"w\" : 175 , \"h\" : 175 , \"parentid\" : 20 , \"min\" : 170 , \"max\" : 300 , \"val\" : 224 , \"format\" : 1 , \"critical_value\" : 301 , \"label_count\" : 14 , \"line_count\" : 27 , \"border_width\" : 0 , \"pad_top\" : 2 , \"pad_bottom\" : 2 , \"pad_left\" : 2 , \"pad_right\" : 2 , \"value_str\" : \"\u00b0C\" , \"value_ofs_y\" : 55 , \"value_font\" : 16 , \"bg_opa\" : 0 , \"line_width10\" : 3 , \"line_rounded10\" : 1 , \"line_color\" : \"#348feb\" , \"line_color60\" : \"#348feb\" , \"scale_grad_color\" : \"#eb4934\" , \"scale_grad_color60\" : \"#eb4934\" , \"scale_end_color60\" : \"#eb4934\" } { \"page\" : 3 , \"id\" : 22 , \"obj\" : \"obj\" , \"x\" : 85 , \"y\" : 85 , \"w\" : 60 , \"h\" : 60 , \"parentid\" : 20 , \"click\" : 0 , \"radius\" : 30 , \"border_width\" : 2 , \"border_opa\" : 200 } { \"page\" : 3 , \"id\" : 23 , \"obj\" : \"label\" , \"x\" : 80 , \"y\" : 100 , \"w\" : 70 , \"h\" : 30 , \"parentid\" : 20 , \"text\" : \"22.4\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 24 , \"obj\" : \"obj\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"click\" : 0 , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 25 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 245 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"25\" , \"text_font\" : 24 , \"align\" : \"center\" } { \"page\" : 3 , \"id\" : 26 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 220 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" , \"border_width\" : 0 } { \"page\" : 3 , \"id\" : 30 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 235 , \"w\" : 240 , \"h\" : 80 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 , \"radius\" : 0 } { \"page\" : 3 , \"id\" : 31 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 32 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 33 , \"obj\" : \"tab\" , \"parentid\" : 30 } { \"page\" : 3 , \"id\" : 41 , \"obj\" : \"switch\" , \"x\" : 35 , \"y\" : 10 , \"w\" : 60 , \"h\" : 30 , \"parentid\" : 31 , \"radius\" : 25 , \"radius20\" : 25 } { \"page\" : 3 , \"id\" : 42 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 32 , \"options\" : \"fan_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } { \"page\" : 3 , \"id\" : 43 , \"obj\" : \"dropdown\" , \"x\" : 15 , \"y\" : 10 , \"w\" : 110 , \"h\" : 30 , \"parentid\" : 33 , \"options\" : \"hvac_modes\" , \"direction\" : \"1\" , \"radius\" : 5 } 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 - obj : \"p3b20\" # arc slider properties : \"val\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') | int * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"line_color1\" : > {% if is_state('climate.thermostat_1', 'cool') %} {{ \"#346beb\" }} {%-elif is_state('climate.thermostat_1', 'heat_cool') %} {{ \"#34bdeb\" }} {%-elif is_state('climate.thermostat_1', 'heat') %} {{ \"#eb3434\" }} {%-elif is_state('climate.thermostat_1', 'dry') %} {{ \"#ebeb34\" }} {%-elif is_state('climate.thermostat_1', 'fan_only') %} {{ \"#34eb77\" }} {%-else %} {{ \"#9f96b0\" }} {% endif %} event : \"changed\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ val | int / 10 }}\" - obj : \"p3b21\" # gauge current temp properties : \"val\" : > {% if not (is_state('sensor.ble_atlaghomerseklet','unavailable') or is_state('sensor.ble_atlaghomerseklet','unknown')) %} {{ states('sensor.ble_atlaghomerseklet') | float (default=0) * 10 }} {%- endif %} \"min\" : > {% if state_attr('climate.thermostat_1','min_temp') is not none %} {{ state_attr('climate.thermostat_1','min_temp') | int * 10 }} {%- endif %} \"max\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 }} {%- endif %} \"critical_value\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int * 10 + 1 }} {%- endif %} \"label_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int + 1 }} {%- endif %} \"line_count\" : > {% if state_attr('climate.thermostat_1','max_temp') is not none %} {{ (state_attr('climate.thermostat_1','max_temp') | int - state_attr('climate.thermostat_1','min_temp') | int) * 2 + 1 }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b23\" # label current temp (and +/- with short/long touch) properties : \"text\" : > {% if (is_state('sensor.temp_room_1','unavailable') or is_state('sensor.temp_room_1','unknown')) %} {{ \"--.-\" }} {%-else %} {{ states('sensor.temp_room_1') | round(1,default=0) }} {%- endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"up\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') + state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" \"long\" : - service : climate.set_temperature target : entity_id : climate.thermostat_1 data : temperature : \"{{ state_attr('climate.thermostat_1','temperature') - state_attr('climate.thermostat_1','target_temp_step') | float(default=1)}}\" - obj : \"p3b25\" # label target temp properties : \"text\" : > {% if state_attr('climate.thermostat_1','temperature') is not none %} {{ state_attr('climate.thermostat_1','temperature') }} {%- endif %} \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" - obj : \"p3b41\" # on/off switch properties : \"val\" : \"{{ 0 if (is_state('climate.thermostat_1', 'off') or is_state('climate.thermostat_1', 'unavailable')) else 1 }}\" \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"opacity\" : \"{{ 60 if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 255 }}\" event : \"down\" : - service_template : > {% if val == 0 -%} climate.turn_on {% else -%} climate.turn_off {% endif -%} entity_id : \"climate.thermostat_1\" - obj : \"p3b30\" # tab dots event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p3b26.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 2 %} {{ \"#909090 \\u2022# #909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p3b42\" # dropdown with fan_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','fan_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {%- if mode == 'auto' -%} Automatic{{\"\\n\"|e}} {%- elif mode == 'low' -%} Low{{\"\\n\"|e}} {%- elif mode == 'medium' -%} Medium{{\"\\n\"|e}} {%- elif mode == 'high' -%} High{{\"\\n\"|e}} {%- elif mode == 'turbo' -%} Turbo{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','fan_modes')%} {{loop.index -1 if mode == state_attr('climate.thermostat_1','fan_mode') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_fan_mode target : entity_id : climate.thermostat_1 data : fan_mode : > {% if text == \"Automatic\" -%} auto {% elif text == 'Low' -%} low {% elif text == 'Medium' -%} medium {% elif text == 'High' -%} high {% elif text == 'Turbo' -%} turbo {% endif -%} - obj : \"p3b43\" # dropdown with hvac_modes properties : \"options\" : > {% if state_attr('climate.thermostat_1','hvac_modes') is not none %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {%- if mode == 'off' -%} Off{{\"\\n\"|e}} {%- elif mode == 'heat' -%} Heating{{\"\\n\"|e}} {%- elif mode == 'cool' -%} Cooling{{\"\\n\"|e}} {%- elif mode == 'heat_cool' -%} Heat/Cool{{\"\\n\"|e}} {%- elif mode == 'dry' -%} Drying{{\"\\n\"|e}} {%- elif mode == 'fan_only' -%} Fan only{{\"\\n\"|e}} {%- else -%} On{{\"\\n\"|e}} {%- endif -%} {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %} \"click\" : \"{{ 'false' if (is_state('climate.thermostat_1','unavailable') or is_state('climate.thermostat_1','unknown')) else 'true' }}\" \"val\" : > {% if not (is_state('climate.thermostat_1','unavailable')) %}{%for mode in state_attr('climate.thermostat_1','hvac_modes')%} {{loop.index -1 if mode == states('climate.thermostat_1') }} {%-endfor%}{% endif %} event : \"changed\" : - service : climate.set_hvac_mode target : entity_id : climate.thermostat_1 data : hvac_mode : > {% if text == \"Off\" -%} off {% elif text == 'Heating' -%} heat {% elif text == 'Cooling' -%} cool {% elif text == 'Heat/Cool' -%} heat_cool {% elif text == 'Drying' -%} dry {% elif text == 'Fan only' -%} fan_only {% endif -%}","title":"Generic thermostat/climate"},{"location":"integrations/home-assistant/sampl_conf/#current-weather-and-forecasts","text":"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 {target= blank} (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: light theme dark theme 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 { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"WEATHER\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"obj\" , \"x\" : 5 , \"y\" : 35 , \"w\" : 230 , \"h\" : 250 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"img\" , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 2 , \"auto_size\" : 1 , \"w\" : 128 , \"offset_x\" : -6 , \"offset_y\" : -10 } { \"page\" : 5 , \"id\" : 15 , \"obj\" : \"label\" , \"x\" : 100 , \"y\" : 10 , \"w\" : 130 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"date current\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 16 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 34 , \"w\" : 95 , \"h\" : 40 , \"align\" : \"center\" , \"text\" : \"00.0\u00b0C\" , \"parentid\" : 2 , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 17 , \"obj\" : \"label\" , \"x\" : 110 , \"y\" : 78 , \"w\" : 120 , \"h\" : 25 , \"align\" : \"center\" , \"text\" : \"condition\" , \"parentid\" : 2 } { \"page\" : 5 , \"id\" : 19 , \"obj\" : \"label\" , \"x\" : 90 , \"y\" : 95 , \"w\" : 60 , \"h\" : 30 , \"text\" : \"#000000 \\u2022# #909090 \\u2022#\" , \"parentid\" : 2 , \"text_font\" : 24 , \"align\" : \"center\" , \"text_color\" : \"grey\" } { \"page\" : 5 , \"id\" : 10 , \"obj\" : \"tabview\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 260 , \"parentid\" : 2 , \"btn_pos\" : 0 , \"bg_opa\" : 0 , \"border_width\" : 0 } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"tab\" , \"parentid\" : 10 } { \"page\" : 5 , \"id\" : 21 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 123 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+2\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 22 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 123 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 23 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 31 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 154 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+3\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 32 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 154 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 33 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 41 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 186 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+4\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 42 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 186 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 43 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 51 , \"obj\" : \"label\" , \"x\" : 8 , \"y\" : 218 , \"w\" : 130 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"hour+5\" , \"parentid\" : 11 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 52 , \"obj\" : \"label\" , \"x\" : 124 , \"y\" : 218 , \"w\" : 50 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 11 , \"pad_top\" : -2 , \"text_font\" : 24 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 53 , \"obj\" : \"img\" , \"x\" : 182 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 11 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 61 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 123 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+1\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 62 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 63 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 123 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 64 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 118 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 71 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 154 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+2\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 72 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 73 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 154 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 74 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 150 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 81 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 186 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+3\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 82 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 83 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 186 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 84 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 182 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 91 , \"obj\" : \"label\" , \"x\" : 6 , \"y\" : 218 , \"w\" : 100 , \"h\" : 22 , \"align\" : \"left\" , \"text\" : \"date+4\" , \"parentid\" : 12 , \"pad_top\" : 3 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 92 , \"obj\" : \"label\" , \"x\" : 102 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Navy\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 93 , \"obj\" : \"label\" , \"x\" : 150 , \"y\" : 218 , \"w\" : 40 , \"h\" : 22 , \"align\" : \"center\" , \"text\" : \"00.0\" , \"parentid\" : 12 , \"pad_top\" : -2 , \"text_font\" : 24 , \"text_color\" : \"Blush\" , \"click\" : 0 } { \"page\" : 5 , \"id\" : 94 , \"obj\" : \"img\" , \"x\" : 194 , \"y\" : 214 , \"w\" : 32 , \"h\" : 32 , \"src\" : \"L:/openhasp_dummy_img.png\" , \"parentid\" : 12 , \"click\" : 0 } 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 - obj : \"p5b14\" # Icon properties : \"src\" : \"{{ 'L:/w-128-' + states('weather.openweathermap') + '.png' if not is_state('weather.openweathermap','unavailable') }}\" - obj : \"p5b15\" # Current date (adjust format to your needs) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set day = (states.weather.openweathermap.last_changed).strftime('%w') %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{- days[ day | int -1 ] }} {{ (states.weather.openweathermap.last_changed).strftime('%m. %d. ') }} {% endif -%} - obj : \"p5b16\" # Current temp (you can use your own outdoor temp sensor if you have one) properties : \"text\" : \"{{ state_attr('weather.openweathermap','temperature') |string + '\u00b0C' if not is_state('weather.openweathermap','unavailable') }}\" # or \"{{ states('sensor.your_own_temp_sensor') if not is_state('sensor.your_own_temp_sensor','unavailable') else '--' }}\u00b0C\" - obj : \"p5b17\" # Current weather condition properties : \"text\" : > {% if is_state('weather.openweathermap','clear-night') -%} Clear night {% elif is_state('weather.openweathermap','cloudy') -%} Cloudy {% elif is_state('weather.openweathermap','fog') -%} Fog {% elif is_state('weather.openweathermap','hail') -%} Hail {% elif is_state('weather.openweathermap','lightning') -%} Lightning {% elif is_state('weather.openweathermap','lightning-rainy') -%} Thunderstorms {% elif is_state('weather.openweathermap','partlycloudy') -%} Partly cloudy {% elif is_state('weather.openweathermap','pouring') -%} Pouring rain {% elif is_state('weather.openweathermap','rainy') -%} Rainy {% elif is_state('weather.openweathermap','snowy') -%} Snowy {% elif is_state('weather.openweathermap','snowy-rainy') -%} Snowy-rainy {% elif is_state('weather.openweathermap','sunny') -%} Sunny {% elif is_state('weather.openweathermap','windy') -%} Windy {% elif is_state('weather.openweathermap','windy-variant') -%} Windy {% elif is_state('weather.openweathermap','exceptional') -%} Exceptional {% elif is_state('weather.openweathermap','unavailable') -%} (not available) {% else -%} {{ states('weather.openweathermap') }} {% endif -%} - obj : \"p5b10\" # tab dots - MAKE SURE YOU UPDATE THIS ONE!! event : \"changed\" : - service : openhasp.command target : entity_id : openhasp.your_plate data : keyword : p5b19.text parameters : > {% if val == 0 %} {{ \"#000000 \\u2022# #909090 \\u2022#\" | e }} {%-elif val == 1 %} {{ \"#909090 \\u2022# #000000 \\u2022#\" | e }} {% endif %} - obj : \"p5b21\" # Forecast time +1h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b22\" # Forecast temp +1h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[1]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b23\" # Forecast condition +1h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b31\" # Forecast time +2h (using Dawn/Morn etc instead of Today/Tomorrow) properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set hour = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) | timestamp_custom(\"%-H\") | int %} {%- if 4 <= hour < 6 %} Dawning {%- elif 6 <= hour < 9 %} Morning {%- elif 9 <= hour < 12 %} Forenoon {%- elif 12 <= hour < 18 %} Afternoon {%- elif 18 <= hour < 23 %} Evening {%- elif 23 <= hour or hour < 4 %} Night {%- endif %} {{- \" \" + hour |string + \" o'clock\" }} {%- endif %} - obj : \"p5b32\" # Forecast temp +2h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[3]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b33\" # Forecast condition +2h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[3]['condition'] }}.png {%- endif %} - obj : \"p5b41\" # Forecast time +4h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[6]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b42\" # Forecast temp +4h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[6]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b43\" # Forecast condition +4h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[6]['condition'] }}.png {%- endif %} - obj : \"p5b51\" # Forecast time +8h properties : \"text\" : > {%- if not is_state('weather.openweathermap','unavailable') %} {%- set update = states('sensor.date') %} {%- set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() %} {%- set event = as_timestamp(strptime(state_attr('weather.openweathermap','forecast')[12]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set delta = ((event - midnight) // 86400) | int %} {%- if delta == 0 %} Today {%- elif delta == 1 %} Tomorrow {%- endif %} {{ event | timestamp_custom(\" %-I %p\") }} {%- endif %} - obj : \"p5b52\" # Forecast temp +8h properties : \"text\" : \"{{ state_attr('weather.openweathermap','forecast')[12]['temperature'] if not is_state('weather.openweathermap','unavailable') else '-' }}\" - obj : \"p5b53\" # Forecast condition +8h properties : \"src\" : > {%- if not is_state('weather.openweathermap','unavailable') %} L:/w-32-{{ state_attr('weather.openweathermap','forecast')[12]['condition'] }}.png {%- endif %} - obj : \"p5b61\" # Forecast date +1d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[0]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b62\" # Forecast temp min +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b63\" # Forecast temp max +1d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[0]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b64\" # Forecast condition +1d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[0]['condition'] }}.png {%- endif %} - obj : \"p5b71\" # Forecast date +2d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[1]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b72\" # Forecast temp min +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b73\" # Forecast temp max +2d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[1]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b74\" # Forecast condition +2d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[1]['condition'] }}.png {%- endif %} - obj : \"p5b81\" # Forecast date +3d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[2]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b82\" # Forecast temp min +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b83\" # Forecast temp max +3d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[2]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b84\" # Forecast condition +3d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[2]['condition'] }}.png {%- endif %} - obj : \"p5b91\" # Forecast date +4d properties : \"text\" : > {%- if not is_state('weather.your_homename','unavailable') %} {%- set now1 = as_timestamp(strptime(state_attr('weather.your_homename','forecast')[3]['datetime'], '%Y-%m-%dT%H:%M:%S%z', default='2020-01-01T00:00:00+00:00')) %} {%- set day = now1 | timestamp_custom(\"%w\") %} {%- set days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"] %} {{ days[ day | int -1 ] }}{{ now1 | timestamp_custom(\" %d\") }} {%- endif %} - obj : \"p5b92\" # Forecast temp min +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['templow'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b93\" # Forecast temp max +4d properties : \"text\" : \"{{ state_attr('weather.your_homename','forecast')[3]['temperature'] if not is_state('weather.your_homename','unavailable') else '-' }}\" - obj : \"p5b94\" # Forecast condition +4d properties : \"src\" : > {%- if not is_state('weather.your_homename','unavailable') %} L:/w-32-{{ state_attr('weather.your_homename','forecast')[3]['condition'] }}.png {%- endif %} Attribution Icons are copyright from manifestinteractive and merlinthered .","title":"Current weather and forecasts"},{"location":"integrations/home-assistant/sampl_conf/#fan-and-scent-diffuser","text":"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. fan perfume 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_width10\" : 19 , \"line_color10\" : \"#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 state_attr(\"input_select.fan_presets\",\"options\") is not none -%} {% 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 states('input_select.fan_presets') in ['unavailable', 'unknown', 'OFF'] else 255 }}\" \"jsonl\" : > {% if is_state('number.plate_test_page_number', '4') %} {% if is_state('input_select.fan_presets', 'Alap') %} {\"speed\":7000,\"line_color10\":\"#31de70\"} {%-elif is_state('input_select.fan_presets', 'K\u00f6z\u00e9p') %} {\"speed\":1700,\"line_color10\":\"#dede1f\"} {%-elif is_state('input_select.fan_presets', 'Magas') %} {\"speed\":800,\"line_color10\":\"#d6a11a\"} {%-elif is_state('input_select.fan_presets', 'Turb\u00f3') %} {\"speed\":250,\"line_color10\":\"#ff4a4a\"} {% endif %} {% else -%} {\"speed\":0} {% endif %} - obj : \"p4b54\" # Scent Diffuser ON/OFF button properties : \"val\" : '{{ 1 if is_state(\"fan.scent_diffuser_intensity\", \"on\") else 0 }}' \"enabled\" : \"{{ 'false' if states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 states('input_select.fan_presets') in ['unavailable', '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 .","title":"Fan and scent diffuser"},{"location":"integrations/home-assistant/sampl_conf/#using-tags","text":"You can avoid too much code repetition when you have multiple similar objects on a page, doing the same thing with different entities, and you'd like to make accessible some advanced options too. Presenting everyting flat will overwhelm your user interface, so it would be better to just show the most used controls, and only display the advanced options in popups related to unique objects. Tag property was made to ease this task.","title":"Using tags"},{"location":"integrations/home-assistant/sampl_conf/#colored-lights-panel","text":"In the example below we have four coloured lights. Squeezing the ON/OFF button, the color picker and the brightness selector for all four lights on a single page can be challenging - and the result will likely be useless on a small touch screen. Instead, we'll just place the toggle buttons with descriptive labels on the page, and we'll only display the color picker and the brightness selector on demand, in this case when the user touches the descriptive coloured label. While dynamically drawing these objects we're setting the tag property for the color picker and the slider to the entity_id of the light we want to adjust, so that when we're interacting with them, the Custom Component can know which light it has to send the adjustments to. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 5 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"COLOURED LIGHTS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 5 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"I.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 40 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"II.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 15 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"III.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 125 , \"y\" : 165 , \"w\" : 100 , \"h\" : 60 , \"text\" : \"IV.\" , \"align\" : \"center\" , \"border_width\" : 1 , \"radius\" : 8 , \"border_color\" : \"#bdbdbd\" , \"bg_opa\" : 255 , \"click\" : true } { \"page\" : 5 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 90 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 15 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } { \"page\" : 5 , \"id\" : 14 , \"obj\" : \"btn\" , \"x\" : 125 , \"y\" : 220 , \"w\" : 100 , \"h\" : 60 , \"toggle\" : true , \"text\" : \"\\uE335\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p5b11\" # toggle button for ON/OFF switching of light I. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_1\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_1\" - obj : \"p5b12\" # toggle button for ON/OFF switching of light II. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_2\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_2\" - obj : \"p5b13\" # toggle button for ON/OFF switching of light III. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_3\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_3\" - obj : \"p5b14\" # toggle button for ON/OFF switching of light IV. properties : \"val\" : '{{ 1 if is_state(\"light.dmx_vbar_4\", \"on\") else 0 }}' event : \"down\" : - service : homeassistant.toggle entity_id : \"light.dmx_vbar_4\" - obj : \"p5b2\" # label showing the current color of light I. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_1','on') %} {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_1 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light I. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light I.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_1\",\"color\": {% set rgb = state_attr('light.dmx_vbar_1','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_1\",\"val\": {{- state_attr('light.dmx_vbar_1', 'brightness') -}} } - obj : \"p5b3\" # label showing the current color of light II. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_2','on') %} {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_2 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light II. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light II.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_2\",\"color\": {% set rgb = state_attr('light.dmx_vbar_2','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_2\",\"val\": {{- state_attr('light.dmx_vbar_2', 'brightness') -}} } - obj : \"p5b4\" # label showing the current color of light III. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_3','on') %} {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_3 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light III. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light III.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_3\",\"color\": {% set rgb = state_attr('light.dmx_vbar_3','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_3\",\"val\": {{- state_attr('light.dmx_vbar_3', 'brightness') -}} } - obj : \"p5b5\" # label showing the current color of light IV. properties : \"bg_color\" : > {% if is_state('light.dmx_vbar_4','on') %} {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') %} {{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }} {% endif %} event : \"down\" : - service : light.turn_on data : entity_id : light.dmx_vbar_4 - service : openhasp.command # display the on-demand pop-up with color picker and brightness slider, tagged with the entity_id of light IV. target : entity_id : openhasp.plate_test data : keyword : jsonl parameters : >- {\"page\":5,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":5,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":10,\"y\":15,\"w\":220,\"h\":270,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":5,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":0,\"y\":8,\"w\":220,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Color settings for light IV.\"} {\"page\":5,\"id\":201,\"obj\":\"cpicker\",\"parentid\":210,\"x\":20,\"y\":35,\"w\":180,\"h\":180,\"tag\":\"light.dmx_vbar_4\",\"color\": {% set rgb = state_attr('light.dmx_vbar_4','rgb_color') -%} \"{{ \"#%02x%02x%02x\" | format(rgb[0],rgb[1],rgb[2]) }}\" } {\"page\":5,\"id\":202,\"obj\":\"slider\",\"parentid\":210,\"x\":20,\"y\":225,\"w\":180,\"h\":30,\"min\":1,\"max\":255,\"tag\":\"light.dmx_vbar_4\",\"val\": {{- state_attr('light.dmx_vbar_4', 'brightness') -}} } - obj : \"p5b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b201\" # set the color of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" rgb_color : \"[{{ r }},{{ g }},{{ b }}]\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete - obj : \"p5b202\" # set the brightness of the light entity_id extracted from the tag set previously, when displayed, then delete the popup objects event : \"changed\" : - service : light.turn_on data : entity_id : \"{{ tag }}\" brightness : \"{{ val }}\" \"up\" : - service : openhasp.command target : entity_id : openhasp.plate_test data : keyword : p5b200.delete Without tags, the last 3 object definitions would have to be added for each light, and also it would be needed to be drawn separately for each light, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design.","title":"Colored lights panel"},{"location":"integrations/home-assistant/sampl_conf/#shutter-control-panel","text":"In the second example, we have five windows with motorized shutters. In addition to the usual UP/STOP/DOWN buttons, the inhabitants want to have three shortcut positions for each shutter, and also a slider for free positioning. Useless to say that it's impossible to put all these on a page, and also it would be a pity to use up 5 pages just for these. We'll just put the most used, UP/STOP/DOWN buttons on the page (this already looks a bit much...) and we'll use a long press event on the middle STOP button to show a pop-up with the extra required settings related to the desired shutter. The tag here will be a JSON object referencing both the entity_id and the position specific to the desired shutter, eg. \"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"} , this will be set for the buttons and the slider appearing in the popup. Since the shutters are different sizes and types, the same intermediate physical position may correspond to different numeric values in Home Assistant. relevant openHASP config: (screen size 240x320, UI Theme: Hasp Light) { \"page\" : 2 , \"id\" : 1 , \"obj\" : \"btn\" , \"x\" : 0 , \"y\" : 0 , \"w\" : 240 , \"h\" : 30 , \"text\" : \"MOTORIZED COVERS\" , \"text_font\" : 16 , \"bg_color\" : \"#2C3E50\" , \"text_color\" : \"#FFFFFF\" , \"radius\" : 0 , \"border_side\" : 0 , \"click\" : 0 } { \"page\" : 2 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 7 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"I.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 3 , \"obj\" : \"label\" , \"x\" : 53 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"II.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 4 , \"obj\" : \"label\" , \"x\" : 99 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"III.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 5 , \"obj\" : \"label\" , \"x\" : 145 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"IV.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 6 , \"obj\" : \"label\" , \"x\" : 191 , \"y\" : 36 , \"w\" : 42 , \"h\" : 20 , \"text\" : \"V.\" , \"align\" : \"center\" } { \"page\" : 2 , \"id\" : 11 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 12 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 13 , \"obj\" : \"btn\" , \"x\" : 7 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 21 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 22 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 23 , \"obj\" : \"btn\" , \"x\" : 53 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 31 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 32 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 33 , \"obj\" : \"btn\" , \"x\" : 99 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 41 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 42 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 43 , \"obj\" : \"btn\" , \"x\" : 145 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 51 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 60 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE05D\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 52 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 136 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE4DB\" , \"text_font\" : 32 } { \"page\" : 2 , \"id\" : 53 , \"obj\" : \"btn\" , \"x\" : 191 , \"y\" : 212 , \"w\" : 42 , \"h\" : 68 , \"toggle\" : false , \"text\" : \"\\uE045\" , \"text_font\" : 32 } relevant openHASP-custom-component config: (read comments) - obj : \"p2b11\" # shutter I. up button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b13\" # shutter I. down button properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_i', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_i','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_i\" - obj : \"p2b12\" # shutter I. middle stop button properties : \"text\" : > {% if is_state('cover.bigroom_i', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_i', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_i', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_i\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - I.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"54\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_i\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_i','current_position') -}} } - obj : \"p2b21\" # shutter II. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b23\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_ii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_ii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_ii\" - obj : \"p2b22\" properties : \"text\" : > {% if is_state('cover.bigroom_ii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_ii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_ii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_ii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - II.\",\"align\":\"center\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"18\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_ii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_ii','current_position') -}} } - obj : \"p2b31\" # shutter III. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b33\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iii', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iii','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iii\" - obj : \"p2b32\" properties : \"text\" : > {% if is_state('cover.bigroom_iii', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iii', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iii', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iii\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - III.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iii\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iii','current_position') -}} } - obj : \"p2b41\" # shutter IV. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b43\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_iv', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_iv','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_iv\" - obj : \"p2b42\" properties : \"text\" : > {% if is_state('cover.bigroom_iv', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_iv', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_iv', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_iv\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - IV.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"15\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"53\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_iv\",\"position\":\"50\"},\"val\": {{- state_attr('cover.bigroom_iv','current_position') -}} } - obj : \"p2b51\" # shutter V. properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'opening') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 100) else '255' }}\" event : \"down\" : - service : cover.open_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b53\" properties : \"text_color\" : \"{{ '#FFFF00' if is_state('cover.bigroom_v', 'closing') else '#FFFFFF' }}\" \"text_opa\" : \"{{ '80' if is_state_attr('cover.bigroom_v','current_position', 0) else '255' }}\" event : \"down\" : - service : cover.close_cover target : entity_id : \"cover.bigroom_v\" - obj : \"p2b52\" properties : \"text\" : > {% if is_state('cover.bigroom_v', 'closing') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'opening') %} {{ \"\\uE4DB\" | e }} {%-elif is_state('cover.bigroom_v', 'closed') %} {{ \"\\uF11C\" | e }} {%-elif is_state('cover.bigroom_v', 'open') %} {{ \"\\uF11E\" | e }} {% endif %} event : \"down\" : - service : cover.stop_cover target : entity_id : \"cover.bigroom_v\" \"long\" : - service : openhasp.command # display the on-demand pop-up with extra setting objects, tagged with the entity_id and specific positions in JSON objects target : entity_id : openhasp.plate_bigroom data : keyword : jsonl parameters : >- {\"page\":2,\"id\":200,\"obj\":\"obj\",\"x\":0,\"y\":0,\"w\":240,\"h\":320,\"radius\":0,\"bg_grad_dir\":0,\"opacity\":150,\"bg_color\":\"black\"} {\"page\":2,\"id\":210,\"obj\":\"obj\",\"parentid\":200,\"x\":5,\"y\":55,\"w\":230,\"h\":190,\"opacity\":255,\"click\":0,\"radius\":10,\"shadow_opa\":255,\"shadow_color\":\"black\",\"shadow_width\":20,\"shadow_spread\":0} {\"page\":2,\"id\":211,\"obj\":\"label\",\"parentid\":210,\"x\":10,\"y\":10,\"w\":210,\"h\":20,\"click\":0,\"align\":\"center\",\"text\":\"Position preset - V.\"} {\"page\":2,\"id\":201,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":110,\"w\":150,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"Middle\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"17\"}} {\"page\":2,\"id\":202,\"obj\":\"btn\",\"parentid\":210,\"x\":10,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"2/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"90\"}} {\"page\":2,\"id\":203,\"obj\":\"btn\",\"parentid\":210,\"x\":90,\"y\":40,\"w\":70,\"h\":60,\"toggle\":false,\"text_font\":24,\"text\":\"1/3\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"55\"}} {\"page\":2,\"id\":204,\"obj\":\"slider\",\"parentid\":210,\"x\":180,\"y\":40,\"w\":30,\"h\":130,\"min\":1,\"max\":100,\"pad_left20\":\"13\",\"pad_right20\":\"13\",\"tag\":{\"cover\":\"cover.bigroom_v\",\"position\":\"19\"},\"val\": {{- state_attr('cover.bigroom_v','current_position') -}} } - obj : \"p2b200\" # the background of the popup. when touched directly, will close the popup by deleting its objects event : \"down\" : - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b201\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b202\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b203\" # set the shutter position for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"down\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ tag.position }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete - obj : \"p2b204\" # set the shutter position from the slider for entity_id extracted from the JSON oject in tag set when displayed, then delete the popup objects event : \"up\" : - service : cover.set_cover_position data : entity_id : \"{{ tag.cover }}\" position : \"{{ val | int }}\" - service : openhasp.command target : entity_id : openhasp.plate_bigroom data : keyword : p2b200.delete Again - without tags, the last 5 object definitions would have to be added for each shutter, and also it would be needed to be drawn separately for each one, initially invisible, then toggle visibility at each one. That would have resulted in a much bigger Custom Component configuration, and also plate design. 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.","title":"Shutter control panel"},{"location":"integrations/node-red/","text":"Node-RED ~ You can integrate an openHASP plate in Node-RED by subscribing and publishing to its MQTT topics. The following is an example of how to use Node-RED to read PIN numbers from an alarm button matrix on page 12, and display those numbers back to the screen on p12b2. First we define p12b1 as the matrix, and p12b2 as the area where to re-display the PIN. Add the following to pages_online.jsonl { \"comment\" : \" ----------- Page 12 layout ------------\" } { \"page\" : 12 , \"id\" : 1 , \"obj\" : \"btnmatrix\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 220 , \"h\" : 220 , \"options\" :[ \"1\" , \"2\" , \"3\" , \"\\n\" , \"4\" , \"5\" , \"6\" , \"\\n\" , \"7\" , \"8\" , \"9\" , \"\\n\" , \"Home\" , \"0\" , \"Away\" ], \"toggle\" : false , \"one_check\" : false } { \"page\" : 12 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 104 , \"y\" : 22 , \"h\" : 30 , \"w\" : 40 , \"text\" : \" \" , \"text_color\" : \"white\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } The following jsonl is for 13 Lanbon L8 panels and can be imported [ { \"id\" : \"0b80aa53cbe8e6e2\" , \"type\" : \"tab\" , \"label\" : \"Lanbon Security Panel\" , \"disabled\" : false , \"info\" : \"\" , \"env\" : [] }, { \"id\" : \"e7faec55927cd35a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/livingroom/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 80 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"99cabcc7d52bfc9b\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"active\" : true , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"payload\" , \"targetType\" : \"msg\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 1290 , \"y\" : 200 , \"wires\" : [] }, { \"id\" : \"ac7b661dc1513061\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MakeNums\" , \"rules\" : [ { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":0,\\\"text\\\":\\\"1\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"1\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":1,\\\"text\\\":\\\"2\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"2\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":2,\\\"text\\\":\\\"3\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"3\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":3,\\\"text\\\":\\\"4\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"4\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":4,\\\"text\\\":\\\"5\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"5\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":5,\\\"text\\\":\\\"6\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"6\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":6,\\\"text\\\":\\\"7\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"7\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":7,\\\"text\\\":\\\"8\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"8\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":8,\\\"text\\\":\\\"9\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"9\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":10,\\\"text\\\":\\\"0\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"0\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 450 , \"y\" : 160 , \"wires\" : [ [ \"9739abb6f93766f6\" ] ] }, { \"id\" : \"d23a2c349910face\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"BuildPIN\" , \"func\" : \"var pin=global.get('pin') || \\\"\\\";\\n\\nvar count=global.get('count') || 0;\\ncount +=1;\\nglobal.set('count',count)\\n\\npin = pin+msg.payload;\\nglobal.set('pin',pin)\\n\\n\\nif (count >= 4) {\\n msg.payload=pin;\\n global.set('count',undefined)\\n global.set('pin',undefined)\\n return msg;\\n}\\n\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 680 , \"y\" : 180 , \"wires\" : [ [ \"194eed57a4506f13\" , \"eaa539f1f670e8ea\" , \"978adaf5813fc4c9\" , \"421fb70f969f4c42\" , \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"8ac3fdee648284fe\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"OnDown\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"cont\" , \"v\" : \"{\\\"event\\\":\\\"down\\\"\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 1 , \"x\" : 420 , \"y\" : 80 , \"wires\" : [ [ \"5249d096ebe1aab7\" , \"ac7b661dc1513061\" ] ] }, { \"id\" : \"978adaf5813fc4c9\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Disarm Alarm\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_disarm\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":msg.payload}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 920 , \"y\" : 200 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"8b34728627566066\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mainhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 140 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"da5ff263f7265cee\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/ensuite/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 200 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"16c2241ebfe6d928\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mbr/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 160 , \"y\" : 260 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9152a3b91fa4ce8a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/porch/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 320 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"df2df457211af7fa\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/dining/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 380 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"ef006a2ad5f4033f\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 440 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"6dc9dabe1edb7af5\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/kitchen/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 500 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"fb8196aa68104765\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/garage/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 560 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"a416144df4052b42\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 620 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9305a215bd8a3a87\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishMood\" , \"topic\" : \"hasp/plates/command\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 40 , \"wires\" : [] }, { \"id\" : \"5249d096ebe1aab7\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"White\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 255, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 650 , \"y\" : 40 , \"wires\" : [ [ \"1c99afe47fe6da11\" , \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"3a59fcd31e572bb0\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 810 , \"y\" : 80 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"197cb8bad0ea98a3\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmAway\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_away\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 320 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"eaa539f1f670e8ea\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Purple\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 0, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 950 , \"y\" : 380 , \"wires\" : [ [ \"9305a215bd8a3a87\" , \"cae42e223294ce38\" ] ] }, { \"id\" : \"194eed57a4506f13\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Reset\" , \"func\" : \" global.set('count',undefined)\\n global.set('pin',undefined)\\n msg.payload = \\\"\\\"\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 670 , \"y\" : 240 , \"wires\" : [ [ \"421fb70f969f4c42\" ] ] }, { \"id\" : \"9739abb6f93766f6\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"0-9HomeAway\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"btwn\" , \"v\" : \"0\" , \"vt\" : \"num\" , \"v2\" : \"9\" , \"v2t\" : \"num\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":9,\\\"text\\\":\\\"Home\\\"}\" , \"vt\" : \"str\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":11,\\\"text\\\":\\\"Away\\\"}\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 3 , \"x\" : 440 , \"y\" : 240 , \"wires\" : [ [ \"d23a2c349910face\" , \"f9f85bc88ea6f404\" ], [ \"194eed57a4506f13\" ], [ \"194eed57a4506f13\" , \"c861944aac699e3e\" , \"206a424a07c9fb22\" ] ] }, { \"id\" : \"11dad534fd1a944e\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1010 , \"y\" : 440 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"cae42e223294ce38\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"1\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 880 , \"y\" : 440 , \"wires\" : [ [ \"11dad534fd1a944e\" ] ] }, { \"id\" : \"4b8a2bd06dcf1342\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishPIN\" , \"topic\" : \"hasp/plates/command/p12b2.text\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 120 , \"wires\" : [] }, { \"id\" : \"f9f85bc88ea6f404\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"DisplayPIN\" , \"func\" : \"var pin=global.get('pin')\\n// pin = pin+msg.payload;\\nmsg.payload = pin;\\nreturn msg;\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 690 , \"y\" : 140 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"149782424f319147\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"****\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 500 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" , \"88031b2f0bea8fef\" ] ] }, { \"id\" : \"421fb70f969f4c42\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 500 , \"wires\" : [ [ \"149782424f319147\" ] ] }, { \"id\" : \"88031b2f0bea8fef\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 560 , \"wires\" : [ [ \"bf47160c100015ca\" ] ] }, { \"id\" : \"bf47160c100015ca\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \" \" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 560 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"c861944aac699e3e\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"15\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 300 , \"wires\" : [ [ \"371b17d0dd9918dc\" , \"24f9431e18e5d5f2\" ] ] }, { \"id\" : \"1c99afe47fe6da11\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"300\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 670 , \"y\" : 80 , \"wires\" : [ [ \"3a59fcd31e572bb0\" ] ] }, { \"id\" : \"206a424a07c9fb22\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"30 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"Alarm will arm away in 30 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 300 , \"wires\" : [ [] ] }, { \"id\" : \"24f9431e18e5d5f2\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"15 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"15 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 360 , \"wires\" : [ [] ] }, { \"id\" : \"371b17d0dd9918dc\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"10\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 360 , \"wires\" : [ [ \"b8098924ec49405c\" , \"56b96ab40a26daeb\" ] ] }, { \"id\" : \"b8098924ec49405c\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"5\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 420 , \"wires\" : [ [ \"197cb8bad0ea98a3\" ] ] }, { \"id\" : \"56b96ab40a26daeb\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"5 Secs\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"5 Seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 420 , \"wires\" : [ [] ] }, { \"id\" : \"0b8f9dbd664953e2\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmHome\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_home\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 260 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"0bf633ce2d98dd79\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/upbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 680 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"e3bf26032c55a701\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"debug 1\" , \"active\" : false , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"false\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 640 , \"y\" : 580 , \"wires\" : [] }, { \"id\" : \"9a8d3eea339efbdc\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/allys_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 740 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"7aac330a4bb67fe8\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/victorias_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 130 , \"y\" : 800 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"441d674c9c4a7f07\" , \"type\" : \"mqtt-broker\" , \"name\" : \"192.168.0.21\" , \"broker\" : \"192.168.0.21\" , \"port\" : \"1883\" , \"clientid\" : \"\" , \"autoConnect\" : true , \"usetls\" : false , \"protocolVersion\" : \"4\" , \"keepalive\" : \"60\" , \"cleansession\" : true , \"birthTopic\" : \"\" , \"birthQos\" : \"0\" , \"birthPayload\" : \"\" , \"birthMsg\" : {}, \"closeTopic\" : \"\" , \"closeQos\" : \"0\" , \"closePayload\" : \"\" , \"closeMsg\" : {}, \"willTopic\" : \"\" , \"willQos\" : \"0\" , \"willPayload\" : \"\" , \"willMsg\" : {}, \"sessionExpiry\" : \"\" }, { \"id\" : \"669eed80.4f9844\" , \"type\" : \"server\" , \"name\" : \"Home Assistant\" , \"version\" : 5 , \"addon\" : true , \"rejectUnauthorizedCerts\" : true , \"ha_boolean\" : \"y|yes|true|on|home|open\" , \"connectionDelay\" : false , \"cacheJson\" : false , \"heartbeat\" : false , \"heartbeatInterval\" : 30 , \"areaSelector\" : \"friendlyName\" , \"deviceSelector\" : \"friendlyName\" , \"entitySelector\" : \"friendlyName\" , \"statusSeparator\" : \"at: \" , \"statusYear\" : \"hidden\" , \"statusMonth\" : \"short\" , \"statusDay\" : \"numeric\" , \"statusHourCycle\" : \"h23\" , \"statusTimeFormat\" : \"h:m\" , \"enableGlobalContextStore\" : true } ]","title":"Node-RED"},{"location":"integrations/node-red/#node-red","text":"You can integrate an openHASP plate in Node-RED by subscribing and publishing to its MQTT topics. The following is an example of how to use Node-RED to read PIN numbers from an alarm button matrix on page 12, and display those numbers back to the screen on p12b2. First we define p12b1 as the matrix, and p12b2 as the area where to re-display the PIN. Add the following to pages_online.jsonl { \"comment\" : \" ----------- Page 12 layout ------------\" } { \"page\" : 12 , \"id\" : 1 , \"obj\" : \"btnmatrix\" , \"x\" : 10 , \"y\" : 40 , \"w\" : 220 , \"h\" : 220 , \"options\" :[ \"1\" , \"2\" , \"3\" , \"\\n\" , \"4\" , \"5\" , \"6\" , \"\\n\" , \"7\" , \"8\" , \"9\" , \"\\n\" , \"Home\" , \"0\" , \"Away\" ], \"toggle\" : false , \"one_check\" : false } { \"page\" : 12 , \"id\" : 2 , \"obj\" : \"label\" , \"x\" : 104 , \"y\" : 22 , \"h\" : 30 , \"w\" : 40 , \"text\" : \" \" , \"text_color\" : \"white\" , \"align\" : 0 , \"bg_color\" : \"#2C3E50\" } The following jsonl is for 13 Lanbon L8 panels and can be imported [ { \"id\" : \"0b80aa53cbe8e6e2\" , \"type\" : \"tab\" , \"label\" : \"Lanbon Security Panel\" , \"disabled\" : false , \"info\" : \"\" , \"env\" : [] }, { \"id\" : \"e7faec55927cd35a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/livingroom/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 80 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"99cabcc7d52bfc9b\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"active\" : true , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"payload\" , \"targetType\" : \"msg\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 1290 , \"y\" : 200 , \"wires\" : [] }, { \"id\" : \"ac7b661dc1513061\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MakeNums\" , \"rules\" : [ { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":0,\\\"text\\\":\\\"1\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"1\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":1,\\\"text\\\":\\\"2\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"2\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":2,\\\"text\\\":\\\"3\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"3\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":3,\\\"text\\\":\\\"4\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"4\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":4,\\\"text\\\":\\\"5\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"5\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":5,\\\"text\\\":\\\"6\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"6\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":6,\\\"text\\\":\\\"7\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"7\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":7,\\\"text\\\":\\\"8\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"8\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":8,\\\"text\\\":\\\"9\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"9\" , \"tot\" : \"str\" }, { \"t\" : \"change\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"from\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":10,\\\"text\\\":\\\"0\\\"}\" , \"fromt\" : \"str\" , \"to\" : \"0\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 450 , \"y\" : 160 , \"wires\" : [ [ \"9739abb6f93766f6\" ] ] }, { \"id\" : \"d23a2c349910face\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"BuildPIN\" , \"func\" : \"var pin=global.get('pin') || \\\"\\\";\\n\\nvar count=global.get('count') || 0;\\ncount +=1;\\nglobal.set('count',count)\\n\\npin = pin+msg.payload;\\nglobal.set('pin',pin)\\n\\n\\nif (count >= 4) {\\n msg.payload=pin;\\n global.set('count',undefined)\\n global.set('pin',undefined)\\n return msg;\\n}\\n\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 680 , \"y\" : 180 , \"wires\" : [ [ \"194eed57a4506f13\" , \"eaa539f1f670e8ea\" , \"978adaf5813fc4c9\" , \"421fb70f969f4c42\" , \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"8ac3fdee648284fe\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"OnDown\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"cont\" , \"v\" : \"{\\\"event\\\":\\\"down\\\"\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 1 , \"x\" : 420 , \"y\" : 80 , \"wires\" : [ [ \"5249d096ebe1aab7\" , \"ac7b661dc1513061\" ] ] }, { \"id\" : \"978adaf5813fc4c9\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Disarm Alarm\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_disarm\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":msg.payload}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 920 , \"y\" : 200 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"8b34728627566066\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mainhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 140 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"da5ff263f7265cee\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/ensuite/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 200 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"16c2241ebfe6d928\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/mbr/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 160 , \"y\" : 260 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9152a3b91fa4ce8a\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/porch/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 320 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"df2df457211af7fa\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/dining/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 380 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"ef006a2ad5f4033f\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 440 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"6dc9dabe1edb7af5\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/kitchen/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 500 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"fb8196aa68104765\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/garage/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 560 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"a416144df4052b42\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/downhall/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 620 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"9305a215bd8a3a87\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishMood\" , \"topic\" : \"hasp/plates/command\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 40 , \"wires\" : [] }, { \"id\" : \"5249d096ebe1aab7\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"White\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 255, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 650 , \"y\" : 40 , \"wires\" : [ [ \"1c99afe47fe6da11\" , \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"3a59fcd31e572bb0\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 810 , \"y\" : 80 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"197cb8bad0ea98a3\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmAway\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_away\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 320 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"eaa539f1f670e8ea\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Purple\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 255, \\\"g\\\": 0, \\\"b\\\": 255, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 950 , \"y\" : 380 , \"wires\" : [ [ \"9305a215bd8a3a87\" , \"cae42e223294ce38\" ] ] }, { \"id\" : \"194eed57a4506f13\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Reset\" , \"func\" : \" global.set('count',undefined)\\n global.set('pin',undefined)\\n msg.payload = \\\"\\\"\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 670 , \"y\" : 240 , \"wires\" : [ [ \"421fb70f969f4c42\" ] ] }, { \"id\" : \"9739abb6f93766f6\" , \"type\" : \"switch\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"0-9HomeAway\" , \"property\" : \"payload\" , \"propertyType\" : \"msg\" , \"rules\" : [ { \"t\" : \"btwn\" , \"v\" : \"0\" , \"vt\" : \"num\" , \"v2\" : \"9\" , \"v2t\" : \"num\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":9,\\\"text\\\":\\\"Home\\\"}\" , \"vt\" : \"str\" }, { \"t\" : \"eq\" , \"v\" : \"{\\\"event\\\":\\\"down\\\",\\\"val\\\":11,\\\"text\\\":\\\"Away\\\"}\" , \"vt\" : \"str\" } ], \"checkall\" : \"true\" , \"repair\" : false , \"outputs\" : 3 , \"x\" : 440 , \"y\" : 240 , \"wires\" : [ [ \"d23a2c349910face\" , \"f9f85bc88ea6f404\" ], [ \"194eed57a4506f13\" ], [ \"194eed57a4506f13\" , \"c861944aac699e3e\" , \"206a424a07c9fb22\" ] ] }, { \"id\" : \"11dad534fd1a944e\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"Black\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"moodlight {\\\"state\\\": true, \\\"r\\\": 0, \\\"g\\\": 0, \\\"b\\\": 0, \\\"brightness\\\": 255}\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1010 , \"y\" : 440 , \"wires\" : [ [ \"9305a215bd8a3a87\" ] ] }, { \"id\" : \"cae42e223294ce38\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"1\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 880 , \"y\" : 440 , \"wires\" : [ [ \"11dad534fd1a944e\" ] ] }, { \"id\" : \"4b8a2bd06dcf1342\" , \"type\" : \"mqtt out\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"MQTTPublishPIN\" , \"topic\" : \"hasp/plates/command/p12b2.text\" , \"qos\" : \"0\" , \"retain\" : \"\" , \"respTopic\" : \"\" , \"contentType\" : \"\" , \"userProps\" : \"\" , \"correl\" : \"\" , \"expiry\" : \"\" , \"broker\" : \"441d674c9c4a7f07\" , \"x\" : 1310 , \"y\" : 120 , \"wires\" : [] }, { \"id\" : \"f9f85bc88ea6f404\" , \"type\" : \"function\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"DisplayPIN\" , \"func\" : \"var pin=global.get('pin')\\n// pin = pin+msg.payload;\\nmsg.payload = pin;\\nreturn msg;\" , \"outputs\" : 1 , \"noerr\" : 0 , \"initialize\" : \"\" , \"finalize\" : \"\" , \"libs\" : [], \"x\" : 690 , \"y\" : 140 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"149782424f319147\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"****\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 500 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" , \"88031b2f0bea8fef\" ] ] }, { \"id\" : \"421fb70f969f4c42\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 500 , \"wires\" : [ [ \"149782424f319147\" ] ] }, { \"id\" : \"88031b2f0bea8fef\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"500\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 870 , \"y\" : 560 , \"wires\" : [ [ \"bf47160c100015ca\" ] ] }, { \"id\" : \"bf47160c100015ca\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \" \" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 1040 , \"y\" : 560 , \"wires\" : [ [ \"4b8a2bd06dcf1342\" ] ] }, { \"id\" : \"c861944aac699e3e\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"15\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 300 , \"wires\" : [ [ \"371b17d0dd9918dc\" , \"24f9431e18e5d5f2\" ] ] }, { \"id\" : \"1c99afe47fe6da11\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"300\" , \"timeoutUnits\" : \"milliseconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 670 , \"y\" : 80 , \"wires\" : [ [ \"3a59fcd31e572bb0\" ] ] }, { \"id\" : \"206a424a07c9fb22\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"30 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"Alarm will arm away in 30 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 300 , \"wires\" : [ [] ] }, { \"id\" : \"24f9431e18e5d5f2\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"15 sec\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"15 seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 360 , \"wires\" : [ [] ] }, { \"id\" : \"371b17d0dd9918dc\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"10\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 360 , \"wires\" : [ [ \"b8098924ec49405c\" , \"56b96ab40a26daeb\" ] ] }, { \"id\" : \"b8098924ec49405c\" , \"type\" : \"delay\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"pauseType\" : \"delay\" , \"timeout\" : \"5\" , \"timeoutUnits\" : \"seconds\" , \"rate\" : \"1\" , \"nbRateUnits\" : \"1\" , \"rateUnits\" : \"second\" , \"randomFirst\" : \"1\" , \"randomLast\" : \"5\" , \"randomUnits\" : \"seconds\" , \"drop\" : false , \"allowrate\" : false , \"outputs\" : 1 , \"x\" : 660 , \"y\" : 420 , \"wires\" : [ [ \"197cb8bad0ea98a3\" ] ] }, { \"id\" : \"56b96ab40a26daeb\" , \"type\" : \"change\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"5 Secs\" , \"rules\" : [ { \"t\" : \"set\" , \"p\" : \"payload\" , \"pt\" : \"msg\" , \"to\" : \"5 Seconds\" , \"tot\" : \"str\" } ], \"action\" : \"\" , \"property\" : \"\" , \"from\" : \"\" , \"to\" : \"\" , \"reg\" : false , \"x\" : 410 , \"y\" : 420 , \"wires\" : [ [] ] }, { \"id\" : \"0b8f9dbd664953e2\" , \"type\" : \"api-call-service\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"ArmHome\" , \"server\" : \"669eed80.4f9844\" , \"version\" : 5 , \"debugenabled\" : false , \"domain\" : \"alarm_control_panel\" , \"service\" : \"alarm_arm_home\" , \"areaId\" : [], \"deviceId\" : [], \"entityId\" : [ \"alarm_control_panel.alarm\" ], \"data\" : \"{\\\"code\\\":\\\"1776\\\"}\" , \"dataType\" : \"jsonata\" , \"mergeContext\" : \"\" , \"mustacheAltTags\" : false , \"outputProperties\" : [], \"queue\" : \"none\" , \"x\" : 940 , \"y\" : 260 , \"wires\" : [ [ \"99cabcc7d52bfc9b\" ] ] }, { \"id\" : \"0bf633ce2d98dd79\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/upbath/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 150 , \"y\" : 680 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"e3bf26032c55a701\" , \"type\" : \"debug\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"debug 1\" , \"active\" : false , \"tosidebar\" : true , \"console\" : false , \"tostatus\" : false , \"complete\" : \"false\" , \"statusVal\" : \"\" , \"statusType\" : \"auto\" , \"x\" : 640 , \"y\" : 580 , \"wires\" : [] }, { \"id\" : \"9a8d3eea339efbdc\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/allys_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 140 , \"y\" : 740 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"7aac330a4bb67fe8\" , \"type\" : \"mqtt in\" , \"z\" : \"0b80aa53cbe8e6e2\" , \"name\" : \"\" , \"topic\" : \"hasp/victorias_room/state/p12b1\" , \"qos\" : \"0\" , \"datatype\" : \"utf8\" , \"broker\" : \"441d674c9c4a7f07\" , \"nl\" : false , \"rap\" : true , \"rh\" : 0 , \"inputs\" : 0 , \"x\" : 130 , \"y\" : 800 , \"wires\" : [ [ \"8ac3fdee648284fe\" ] ] }, { \"id\" : \"441d674c9c4a7f07\" , \"type\" : \"mqtt-broker\" , \"name\" : \"192.168.0.21\" , \"broker\" : \"192.168.0.21\" , \"port\" : \"1883\" , \"clientid\" : \"\" , \"autoConnect\" : true , \"usetls\" : false , \"protocolVersion\" : \"4\" , \"keepalive\" : \"60\" , \"cleansession\" : true , \"birthTopic\" : \"\" , \"birthQos\" : \"0\" , \"birthPayload\" : \"\" , \"birthMsg\" : {}, \"closeTopic\" : \"\" , \"closeQos\" : \"0\" , \"closePayload\" : \"\" , \"closeMsg\" : {}, \"willTopic\" : \"\" , \"willQos\" : \"0\" , \"willPayload\" : \"\" , \"willMsg\" : {}, \"sessionExpiry\" : \"\" }, { \"id\" : \"669eed80.4f9844\" , \"type\" : \"server\" , \"name\" : \"Home Assistant\" , \"version\" : 5 , \"addon\" : true , \"rejectUnauthorizedCerts\" : true , \"ha_boolean\" : \"y|yes|true|on|home|open\" , \"connectionDelay\" : false , \"cacheJson\" : false , \"heartbeat\" : false , \"heartbeatInterval\" : 30 , \"areaSelector\" : \"friendlyName\" , \"deviceSelector\" : \"friendlyName\" , \"entitySelector\" : \"friendlyName\" , \"statusSeparator\" : \"at: \" , \"statusYear\" : \"hidden\" , \"statusMonth\" : \"short\" , \"statusDay\" : \"numeric\" , \"statusHourCycle\" : \"h23\" , \"statusTimeFormat\" : \"h:m\" , \"enableGlobalContextStore\" : true } ]","title":"Node-RED"},{"location":"integrations/openhab/integration_openhab/","text":"openHAB Integration ~ Page Layout ~ We call plate any device running openHASP in your system. Installation ~ The openHAB configuration files to have this demo load automatically can be found here . Update the IP-address for your MQTT-broker in the haspLVGL_demo.things file. Make sure you have your plate connected to the network and to your MQTT boker, and your topic is set to demo_plate . Code ~ To add an openHASP plate to your installation with Jaffa Sunrise sample configuration, upload a pages.jsonl file with the folowing content to your plate: in the plate's web UI select Mono UI theme and reboot, upload a pages.jsonl file with the folowing content to your plate and reboot: 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 { \"page\" : 1 , \"comment\" : \"---------- Page 1 ----------\" } { \"obj\" : \"btn\" , \"id\" : 4 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights On\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE6E8\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 5 , \"x\" : 5 , \"y\" : 68 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Daylight\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE599\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 6 , \"x\" : 5 , \"y\" : 131 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Night\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE594\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 7 , \"x\" : 5 , \"y\" : 194 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights Off\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE335\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"page\" : 2 , \"comment\" : \"---------- Page 2 ----------\" } { \"obj\" : \"label\" , \"id\" : 8 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Kitchen Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 9 , \"x\" : 5 , \"y\" : 80 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Dining Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 10 , \"x\" : 5 , \"y\" : 165 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Front Blinds\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"slider\" , \"id\" : 11 , \"x\" : 20 , \"y\" : 40 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 80 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 12 , \"x\" : 20 , \"y\" : 120 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 13 , \"x\" : 20 , \"y\" : 205 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 25 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"page\" : 3 , \"comment\" : \"---------- Page 3 ----------\" } { \"obj\" : \"label\" , \"id\" : 14 , \"x\" : 42 , \"y\" : 10 , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Gold\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 15 , \"x\" : 42 , \"y\" : 60 , \"mode\" : \"scroll\" , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Chet Faker\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 16 , \"x\" : 2 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AE\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 17 , \"x\" : 82 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE3E4\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 18 , \"x\" : 162 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AD\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"bar\" , \"id\" : 19 , \"x\" : 2 , \"y\" : 105 , \"w\" : 236 , \"h\" : 20 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 15 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" } { \"obj\" : \"slider\" , \"id\" : 20 , \"x\" : 35 , \"y\" : 220 , \"w\" : 170 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 30 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"label\" , \"id\" : 21 , \"x\" : 2 , \"y\" : 10 , \"w\" : 40 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75A\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 22 , \"x\" : 2 , \"y\" : 60 , \"w\" : 36 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE004\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 23 , \"x\" : 5 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75F\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 24 , \"x\" : 210 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE57E\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"page\" : 0 , \"comment\" : \"---------- All pages ----------\" } { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 5 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE04D\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 2 , \"x\" : 83 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE2DC\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 161 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE054\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } Restart the plate and the demo page should load automatically to your device.","title":"openHAB Integration"},{"location":"integrations/openhab/integration_openhab/#openhab-integration","text":"","title":"openHAB Integration"},{"location":"integrations/openhab/integration_openhab/#page-layout","text":"We call plate any device running openHASP in your system.","title":"Page Layout"},{"location":"integrations/openhab/integration_openhab/#installation","text":"The openHAB configuration files to have this demo load automatically can be found here . Update the IP-address for your MQTT-broker in the haspLVGL_demo.things file. Make sure you have your plate connected to the network and to your MQTT boker, and your topic is set to demo_plate .","title":"Installation"},{"location":"integrations/openhab/integration_openhab/#code","text":"To add an openHASP plate to your installation with Jaffa Sunrise sample configuration, upload a pages.jsonl file with the folowing content to your plate: in the plate's web UI select Mono UI theme and reboot, upload a pages.jsonl file with the folowing content to your plate and reboot: 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 { \"page\" : 1 , \"comment\" : \"---------- Page 1 ----------\" } { \"obj\" : \"btn\" , \"id\" : 4 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights On\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE6E8\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 5 , \"x\" : 5 , \"y\" : 68 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Daylight\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE599\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 6 , \"x\" : 5 , \"y\" : 131 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Night\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE594\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 7 , \"x\" : 5 , \"y\" : 194 , \"w\" : 230 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius01\" : 10 , \"radius02\" : 10 , \"text\" : \"Lights Off\" , \"value_ofs_x\" : -85 , \"value_font\" : 32 , \"value_str\" : \"\\uE335\" , \"value_color\" : \"#B6B6B6\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"page\" : 2 , \"comment\" : \"---------- Page 2 ----------\" } { \"obj\" : \"label\" , \"id\" : 8 , \"x\" : 5 , \"y\" : 5 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Kitchen Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 9 , \"x\" : 5 , \"y\" : 80 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Dining Dimmer\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 10 , \"x\" : 5 , \"y\" : 165 , \"w\" : 230 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"text\" : \"Front Blinds\" , \"text_color\" : \"#B6B6B6\" , \"text_font\" : 24 } { \"obj\" : \"slider\" , \"id\" : 11 , \"x\" : 20 , \"y\" : 40 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 80 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 12 , \"x\" : 20 , \"y\" : 120 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"slider\" , \"id\" : 13 , \"x\" : 20 , \"y\" : 205 , \"w\" : 200 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 25 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"page\" : 3 , \"comment\" : \"---------- Page 3 ----------\" } { \"obj\" : \"label\" , \"id\" : 14 , \"x\" : 42 , \"y\" : 10 , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Gold\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 15 , \"x\" : 42 , \"y\" : 60 , \"mode\" : \"scroll\" , \"w\" : 236 , \"h\" : 30 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"Chet Faker\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"btn\" , \"id\" : 16 , \"x\" : 2 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AE\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 17 , \"x\" : 82 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE3E4\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 18 , \"x\" : 162 , \"y\" : 140 , \"w\" : 76 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#FFAC00\" , \"border_width\" : 2 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE4AD\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 32 } { \"obj\" : \"bar\" , \"id\" : 19 , \"x\" : 2 , \"y\" : 105 , \"w\" : 236 , \"h\" : 20 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 15 , \"text_font\" : 1 , \"val\" : 65 , \"bg_color10\" : \"#FFAC00\" } { \"obj\" : \"slider\" , \"id\" : 20 , \"x\" : 35 , \"y\" : 220 , \"w\" : 170 , \"h\" : 30 , \"bg_color\" : \"#C7BAA7\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 15 , \"radius10\" : 15 , \"radius20\" : 20 , \"text_font\" : 1 , \"val\" : 30 , \"bg_color10\" : \"#FFAC00\" , \"bg_color20\" : \"#DC5C05\" } { \"obj\" : \"label\" , \"id\" : 21 , \"x\" : 2 , \"y\" : 10 , \"w\" : 40 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75A\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 22 , \"x\" : 2 , \"y\" : 60 , \"w\" : 36 , \"h\" : 61 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE004\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 23 , \"x\" : 5 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE75F\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"obj\" : \"label\" , \"id\" : 24 , \"x\" : 210 , \"y\" : 224 , \"w\" : 25 , \"h\" : 40 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"text\" : \"\\uE57E\" , \"text_color\" : \"#C7BAA7\" , \"text_font\" : 24 } { \"page\" : 0 , \"comment\" : \"---------- All pages ----------\" } { \"obj\" : \"btn\" , \"id\" : 1 , \"x\" : 5 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE04D\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 2 , \"x\" : 83 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE2DC\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } { \"obj\" : \"btn\" , \"id\" : 3 , \"x\" : 161 , \"y\" : 257 , \"w\" : 73 , \"h\" : 58 , \"bg_color\" : \"#000000\" , \"border_color\" : \"#C7BAA7\" , \"border_width\" : 0 , \"radius\" : 10 , \"radius10\" : 10 , \"radius20\" : 10 , \"text\" : \"\\uE054\" , \"text_color\" : \"#978B7D\" , \"text_font\" : 32 } Restart the plate and the demo page should load automatically to your device.","title":"Code"}]}
\ No newline at end of file
diff --git a/0.7.0/sitemap.xml.gz b/0.7.0/sitemap.xml.gz
index 3eddc0b58..705145c5a 100644
Binary files a/0.7.0/sitemap.xml.gz and b/0.7.0/sitemap.xml.gz differ