OPENHASP
openHASP is a complete binary that you flash to the switch plate then requires two configuration files: a JSON file for the design that gets uploaded to the device, and a YAML file located in /config/openhasp for the HA integration:
{"page":0,"id":1,"obj":"label","x":10,"y":5,"h":30,"w":62,"text":"00:00","text_color":"white","align":0,"bg_color":"#2C3E50"}
{"page":0,"id":3,"obj":"label","x":180,"y":5,"h":30,"w":45,"text":"00.0°F","text_color":"white","align":2,"bg_color":"#2C3E50"}
{"page":1,"id":1,"obj":"btn","x":10,"y":30,"w":105,"h":90,"toggle":true,"text":"\uE335\nB'way","text_font":32,"align":1,"text_color01":"orange"}
{"page":1,"id":2,"obj":"btn","x":125,"y":30,"w":105,"h":90,"toggle":true,"text":"\uE335\nGate","text_font":32,"align":1,"text_color01":"orange"}
{"page":1,"id":21,"obj":"btn","x":198,"y":30,"w":32,"h":32,"toggle":false,"text":"\uE493","text_font":24,"align":1}
{"page":1,"id":3,"obj":"btn","x":10,"y":125,"w":105,"h":90,"toggle":true,"text":"\uE335\nPatio","text_font":32,"align":1,"text_color01":"orange"}
{"page":1,"id":31,"obj":"btn","x":83,"y":125,"w":32,"h":32,"toggle":false,"text":"\uE493","text_font":24,"align":1}
{"page":1,"id":4,"obj":"btn","x":125,"y":125,"w":105,"h":90,"toggle":true,"text":"\uE769\nWall","text_font":32,"align":1,"text_color01":"orange"}
{"page":1,"id":5,"obj":"btn","x":10,"y":220,"w":105,"h":90,"toggle":true,"text":"\uF2BA\nParty","text_font":32,"align":1,"text_color01":"orange"}
{"page":1,"id":51,"obj":"btn","x":83,"y":220,"w":32,"h":32,"toggle":false,"text":"\uE493","text_font":24,"align":1}
{"page":1,"id":6,"obj":"btn","x":125,"y":220,"w":105,"h":90,"toggle":true,"text":"\uEAAC\nW'Wall","text_font":32,"align":1,"text_color01":"orange"}
{"page":2,"id":0,"back":1}
{"page":2,"id":1,"obj":"label","x":20,"y":50,"w":105,"h":90,"text":"Party\nLights","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32,"align":1}
{"page":2,"id":2,"obj":"btn","action":"back","x":0,"y":270,"w":240,"h":50,"bg_color":"#2C3E50","text":"\uE2DC","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32}
{"page":2,"id":3,"obj":"btn","x":10,"y":160,"w":105,"h":90,"toggle":true,"text":"\uE425","text_font":32,"align":1}
{"page":2,"id":4,"obj":"slider","x":180,"y":50,"w":30,"h":200,"max":255}
{"page":3,"id":0,"back":1}
{"page":3,"id":1,"obj":"label","x":20,"y":50,"w":105,"h":90,"text":"Gate\nSconces","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32,"align":1}
{"page":3,"id":2,"obj":"btn","action":"back","x":0,"y":270,"w":240,"h":50,"bg_color":"#2C3E50","text":"\uE2DC","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32}
{"page":3,"id":3,"obj":"btn","x":10,"y":160,"w":105,"h":90,"toggle":true,"text":"\uE425","text_font":32,"align":1}
{"page":3,"id":4,"obj":"slider","x":180,"y":50,"w":30,"h":200,"max":255}
{"page":4,"id":0,"back":1}
{"page":4,"id":1,"obj":"label","x":20,"y":50,"w":105,"h":90,"text":"Patio\nEaves","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32,"align":1}
{"page":4,"id":2,"obj":"btn","action":"back","x":0,"y":270,"w":240,"h":50,"bg_color":"#2C3E50","text":"\uE2DC","text_color":"#FFFFFF","radius":0,"border_side":0,"text_font":32}
{"page":4,"id":3,"obj":"btn","x":10,"y":160,"w":105,"h":90,"toggle":true,"text":"\uE425","text_font":32,"align":1}
{"page":4,"id":4,"obj":"slider","x":180,"y":50,"w":30,"h":200,"max":255}
breezewayplate:
objects:
- obj: "p0b1" # temperature label on all pages
properties:
"text": '{{ states("sensor.time") }}'
- obj: "p0b3" # temperature label on all pages
properties:
"text": '{{ states("sensor.rounded_exterior_temp") }}°F'
- obj: "p1b1"
properties:
"val": '{{ 1 if is_state("light.breezeway_sconce", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.breezeway_sconce"
- obj: "p1b2"
properties:
"val": '{{ 1 if is_state("light.gate_sconces", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.gate_sconces"
- obj: "p1b21"
properties:
"val": 0
event:
"down":
- service: openhasp.command
target:
entity_id: openhasp.breezewayplate
data:
keyword: page
parameters: '3'
- obj: "p1b3"
properties:
"val": '{{ 1 if is_state("light.eaves_downlights_patio", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.eaves_downlights_patio"
- obj: "p1b31"
properties:
"val": 0
event:
"down":
- service: openhasp.command
target:
entity_id: openhasp.breezewayplate
data:
keyword: page
parameters: '4'
- obj: "p1b4"
properties:
"val": '{{ 1 if is_state("light.retaining_wall_lights", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.retaining_wall_lights"
- obj: "p1b5"
properties:
"val": '{{ 1 if is_state("light.patio_party_lights", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.patio_party_lights"
- obj: "p1b51"
properties:
"val": 0
event:
"down":
- service: openhasp.command
target:
entity_id: openhasp.breezewayplate
data:
keyword: page
parameters: '2'
- obj: "p1b6"
properties:
"val": '{{ 1 if is_state("light.water_wall_pump", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.water_wall_pump"
- obj: "p2b3"
properties:
"val": '{{ 1 if is_state("light.patio_party_lights", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.patio_party_lights"
- obj: "p2b4"
properties:
"val": '{{ state_attr("light.patio_party_lights", "brightness") if state_attr("light.patio_party_lights", "brightness") != None else 0}}'
event:
"changed":
- service: light.turn_on
data:
entity_id: "light.patio_party_lights"
brightness: '{{ val }}'
"up":
- service: light.turn_on
data:
entity_id: "light.patio_party_lights"
brightness: '{{ val }}'
- obj: "p3b3"
properties:
"val": '{{ 1 if is_state("light.gate_sconces", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.gate_sconces"
- obj: "p3b4"
properties:
"val": '{{ state_attr("light.gate_sconces", "brightness") if state_attr("light.gate_sconces", "brightness") != None else 0}}'
event:
"changed":
- service: light.turn_on
data:
entity_id: "light.gate_sconces"
brightness: '{{ val }}'
"up":
- service: light.turn_on
data:
entity_id: "light.gate_sconces"
brightness: '{{ val }}'
- obj: "p4b3"
properties:
"val": '{{ 1 if is_state("light.eaves_downlights_patio", "on") else 0 }}'
event:
"down":
- service: homeassistant.toggle
entity_id: "light.eaves_downlights_patio"
- obj: "p4b4"
properties:
"val": '{{ state_attr("light.eaves_downlights_patio", "brightness") if state_attr("light.eaves_downlights_patio", "brightness") != None else 0}}'
event:
"changed":
- service: light.turn_on
data:
entity_id: "light.eaves_downlights_patio"
brightness: '{{ val }}'
"up":
- service: light.turn_on
data:
entity_id: "light.eaves_downlights_patio"
brightness: '{{ val }}'
There are several configurations that have to be done at many different places (MQTT broker add-on, configuring the plate WiFi then MQTT broker access, uploading the GUI design file, editing the integration file) which can make it challenging with a lot of ducks to line up.
Final design configuration and integration with HA go hand-in-hand. It is straight forward if somewhat cryptic. It offers pretty much all the predefined LVGL widgets and decoration attributes but with only absolute X/Y/H/W layout and a limited font. The predefined font does come with a good selection of MDI icons.
The product is very stable and I don’t remember encountering major issues. That OTA update was not available when upgrading from 0.6.0 to 0.7.0 is what prompted me to investigate ESPHome LVGL.