Home Automation Switch Plate (HASP) - DIY touch controller

Tags: #<Tag:0x00007f51df288f88>

(B K) #1

As mentioned in my What did you build/automated today (with pictures)? post recently, I’ve been able to adapt the Home Automation Switch Plate (HASP) project to work with openHAB. I’m posting a write-up here, in case anyone else is interested in using it.

What is it?

The HASP is a touch screen controller designed by aderusha (project page on Github), which fits into a spare “gang” in US-style electrical outlets (no design for the rest of the world yet, sorry). It uses a Nextion HMI (2.4") touchscreen, with a user interface designed by aderusha (9 total screens of different layouts with pushbuttons, sliders and a chart), and a Wemos D1 to drive the screen and interface with the control system (via MQTT). The finished product looks like this:

How does it work?

The Wemos D1 Arduino code and the Nextion HMI code are very nicely designed, made to be modular and generic, exposing all configuration to the home automation system incorporating the HASP. Every button text, background/foreground color, and font size are configurable via MQTT topics. Every button press is captured and sent to the home automation system via MQTT, as well.

Once flashed with code, the HASP allows easy configuration via Wifi (it creates an access point for connection and initial configuration). The initial load of the HMI code is via an SD card with the Github .tft file provided. After that, the HASP can be accessed via a webpage, to change its MQTT settings, Wifi settings, or even update the Wemos (ESP) and LCD (TFT) firmware via HTTP! This is a very cool feature to keep the display up to date!

How to build one?

The GitHub repo has excellent build documentation available, but I also created a short series of build and setup videos. Part 1 (Hardware build and software configuration):

Part 2 (Install and openHAB configuration):

How to use it with openHAB?

The initial project was designed specifically for Home Assistant, with the yaml configuration files included in the GitHub. But after looking at it for a while, I was able to mimic the automation rules for openHAB and I created a set of configuration files for OH. I’ve submitted a PR to aderusha and it’s been approved/merged to the HASP repository, under the /contrib/openHAB folder.

I won’t post the .items or .rules files here due to their length, but the files are available at the Github repo, and I’ve included a sample .sitemap file stub to be able to control/monitor status of the HASP via the Basic UI.

I’ve included a lot of comments in the items and rules files, a readme file on the GitHub repo, and sectioned off the rules file to make it clearer where the end user is able to modify their HASP, but the gist of configuration is as follows:

  1. Before you start, make sure you have the JSONPath transformation installed, the Rules & Items make use of it to decode the data received from the HASP.
  2. Decide which screens of the HMI you want to use. For example, my initial configuration will use screens 1, 2 and 4:
    a. Screen 1 has 4 buttons, which I’ll use to fire off a specific Scene in my openHAB setup
    b. Screen 2 also has 4 buttons, which I’ll use to show a clock, date, indoor and outdoor temperatures
    c. Screen 4 has 3 buttons and 3 sliders, which I’ll use to control my HVAC system and possibly another light depending on which room the HASP is installed.
  3. Depending on the configuration selected above, adjust the variables in the rules file to match the configuration:
    a. In the first part of the .rules file, make the bottom buttons point to the correct screen # and label them.
    b. Adjust the variables corresponding to the button text and font size on the screens with buttons and sliders.
  4. Fill in the HASP -> openHAB and openHAB -> HASP rule sections with the appropriate handler rules for your configuration.
    a. The HASP -> openHAB rules section has stub rules written for every button/slider on every screen. You’ll only need to fill in your code into the appropriate if statement to handle the button press/slider move (I’ve put in commented out example code for some of the cases).
    b. The openHAB -> HASP rules section has some sample rules I’ve written to move the sliders to an appropriate position based on openHAB item state (e.g. to match the brightness slider of a light if it’s changed from some other interface than the HASP) and to put values on the chart of page 9 (e.g. to monitor the signal strength of the HASP Wifi signal, or to show a chart of the room temperature over time).
  5. Enjoy using the HASP!

Conclusion / Notes

My rules and items files should make it easier to incorporate the HASP into our openHAB setups, but there’s still work to be done by the end user to make the buttons and sliders actually “do things”. I’ve also not included some of the finer configuration items (background colors), since I was mostly concerned with getting the main functionality to work. I may add those items/rules in the future, if needed.

Let me know if you have any questions or issues with using this :slight_smile:

NodeMCU based MQTT multi-sensor with OLED display
openHAB livestream today
3 different methods to use scenes with Google Home & openHAB
(Pankaj) #2

Great Work! But unfortunately this is not working on my setup… I am using Openhab 2.4 MQTT bindings and I guess your codes are for legacy MQTT… Can anyone help in converting it to 2.4 MQTT Binding?

(B K) #3

You can still run the MQTTv1 binding alongside MQTTv2.4 to make this work as-is (just enable “Use Legacy Bindings” option in your Paper UI System Configuration page and install/configure the MQTTv1 binding). I haven’t taken on the task of converting this to MQTTv.2 because of the sheer amount of MQTT topics/channels required per unit. Ideally, the HASP Arduino code should be updated to support the Homie 3.0 protocol, so that all the MQTT topics/channels are automatically discovered/configured by the binding. I may take on that task, when I’m done with some of my other concurrent projects :slight_smile:

(Pankaj) #4

Really appreciate your fast reply… :slight_smile:
I am thinking of converting your code for proper latest MQTT2.4. I will be able to convert most of it, just not completely sure about rules… currently cooking Things files and Items files…

(B K) #5

@pkhajanchi - That’d be awesome and I’d appreciate the help! :slight_smile:

Let’s coordinate the changes a bit, though, so you don’t end up doing unnecessary work. Basically, here’s my thoughts:

  1. (DONE) The latest HASP firmware from luma (aderusha) allows the use of JSON arrays to string multiple commands together (up to 4Kb strings, if I remember correctly). I’m already using that in the page command button and page button color rules, and it means I can eliminate all the “formatting” (font, background color, etc…) items with dedicated MQTT topics related to those buttons (can still access those settings via JSON commands). As an added bonus, the JSON command strings are parsed by the HASP a lot faster than individual MQTT messages, making for a smoother/more responsive HASP. So, I’d like to convert all the openHAB->HASP rules to use JSON commands, and eliminate all of the formatting items (keeping only the Page/Button items for the HASP -> openHAB callback rules). I can (hopefully) take care of this tomorrow.

  2. With this limited set of Items, it should be much simpler to convert them to MQTTv2, just adding channels for each specific button on every page.

I also reached out to luma about supporting the Homie (v4!) protocol. That way, we wouldn’t have to manually create MQTTv2 channels at all, they would be automatically created by the binding, with auto discovery…Whether this happens or not, step 1 above should still be the first thing we do to reduce the overall item/topic count!

(B K) #6

@pkhajanchi - I just uploaded my changes to the .items/.rules files to convert to using the JSON command topic for all formatting (text, font, background color) items. With this, I was able to delete all of those individual dedicated items, leaving only the button/dimmer value and general HASP status items (cut the .items files down by half!). Updated files are in my Github repo (https://github.com/bkpsu/HASwitchPlate/tree/master/contrib/openHAB)

If you’re still willing to work on converting the items to MQTTv2 channels, you should have a (slightly) easier task at this point, though I would still recommend waiting to see if luma will support the Homie convention!

(Pankaj) #7

I saw your message late, already did get 3 pages and others things working. I am attaching the working Things files and Items file. Rules files, was same as all the items name I kept the same…

HASP-Master.items.txt (24.0 KB)
plate01.things.txt (20.3 KB)

Only one small issue was left, Buttons was having problem. But, now mostly I will discard it, and start as per your suggestions…

(B K) #8

Excellent work @pkhajanchi! Sorry you had to do the extra items, I was hoping to complete my task so you’d have less work to go through.

I’m going to send luma a PR for the changes I’ve made today - when you finish your changes, you can either send the files to me (upload them here), or create a new PR to aderusha’s repostiory (https://github.com/aderusha/HASwitchPlate/) yourself.

BTW, I’ve also created a new Issue on aderusha’s repo (https://github.com/aderusha/HASwitchPlate/issues/52), for him to add a single JSON “status” topic with events for every button press/dimmer value change. I think that would streamline the interface even more, and allow us to really reduce the number of items/MQTT channels. Then, adding Homie support would be trivial…

Thanks again!

(Pankaj) #9

I pin pointed the button issue, but unable to resolve it…
It seems Openhab MQTT is not able to read topic with brackets…
Example: “hasp/plate01/state/p[1].b[1]”
Even MQTT.fx fails to receive messages. Both Openhab & MQTT.fx is able to send messages correctly.

Looks like, if this solves, the rest are pretty much ready…

(B K) #10

@pkhajanchi - try MQTT-Explorer (I seem to be getting topic updates for buttons through it just fine).

Also, I’m currently working on adding the JSON state topic, if that works well, we won’t need these dedicated button state topics, anyway :slight_smile:

(Pankaj) #11

I will wait for you to add JSON state topic. Then will do for 2.4.

It’s very strange, only Openhab and MQTT.fx is not able to read on topics with brackets[]. I tried few other tools and even tried on commandline mqtt-client tool, all are working…

I heard new MQTT2.4 is buggy. But MQTT.fx it’s strange. Same topic, it’s able to send, but nothing on receive…

(Pankaj) #12

btw, I tried your code with legacy binding… It’s working perfectly…

(B K) #13

@pkhajanchi - All set! I’ve added the JSON state topic to my fork of the project:

You can download the .bin file and update your HASP with it to get the additional JSON topic. It will post JSON payloads to the topic when buttons are pressed and dimmers changed.

Topic: hasp/plate01/state/JSON

Button Press:

{"event":"p[2].b[5]", "value":"ON"}

Button Release:

{"event":"p[2].b[5]", "value":"OFF"}

Dimmer Change:

{"event":"p[4].b[7].val", "value":162}

With this, I should be able to replace ALL button/dimmer state items with a single JSON MQTT item, and process the payload in a rule (with a JSONPATH) to figure out what event occurred.

(Pankaj) #14

Great! It’s seems to be very easy now… With very few channels and items… Most works required in rules files… I have following suggestion for making this project even better:

  1. Using variables on header for Colors. So that, It can be easily customized.
  2. Rules to change the color or text of the button depending upon its state. Like if Morning Scene is on, then its highlighted, or if an Item is on it’s shown like “Light ON”.

Getting a deterministic item state from postUpdate (equivalent to "receivedCommand")
(Pankaj) #15

Thing mqtt:topic:plate01 “Plate 01” @ “Living Room”
Type string : bstate “Plate01 Button State” [ stateTopic=“hasp/plate01/state/JSON” ]


String plate01_button_press “Plate01 Button State” {channel=“mqtt:topic:plate01:bstate”}


rule “Button Press”
var event = transform(“JSONPATH”,"$.event",button_press.state)
var value = transform(“JSONPATH”,"$.value",button_press.state)

item button_press received command
if (event==p[2].b[5])
// command goes here
else if (event==p[2].b[6])

(B K) #16

I’ve got the rules set up now - let me clean them up and I’ll post it all to Gothub - the latest firmware is already up, with some minor changes, including the topic name (json vs JSON)…

EDIT: Added .items and .rules files (HASP-Office) for testing the new json state topic - https://github.com/bkpsu/HASwitchPlate/tree/master/contrib/openHAB

(B K) #17

Great ideas! I can definitely look into implementing them (#2 would be very simple to add to the event handlers, but only useful for toggle states). I was also thinking of having a method for long-press actions (heating/volume controls for example), but I had to remove the OFF event for now (updates too fast on quick button presses and screws up my rules).

(James Bowler) #18

Thanks guys this is awesome work. I got It all working with little trouble. Here are some thing I learnt along the way which may help someone.

Mqtt Broker https://mosquitto.org/
Openhabian on PI

Screen not having text after boot

The screen test was not being refreshed straight after boot so in HASP-Master.rules (master stands for the room/screen)

I Changed

/* Restore saved page and rebuild config on reconnect */
rule "HASP Master Restore page on connect"
    Item HASP_Plate01_Plate_Sensor_Status changed to "available" or
    Item HASP_Plate01_Plate_Refresh received command ON
    HASP_Plate01_Page.sendCommand(HASP_Plate01_Page_Current.state as Number) // Send HASP to previous page


/* Restore saved page and rebuild config on reconnect */
rule "HASP Master Restore page on connect"
    Item HASP_Plate01_Plate_Status changed to "ON" or
    Item HASP_Plate01_Plate_Refresh received command ON
    HASP_Plate01_Page.sendCommand(HASP_Plate01_Page_Current.state as Number) // Send HASP to previous page

When the 8266 loses power it sends nothing to mqtt but when it is restared it turns the plate_status to OFF then back ON again. It now works instantly.

JSONPath Transformation

If you get the error

[.core.transform.TransformationHelper] - Cannot get service reference for transformation service of type JSONPATH

You need to install JSONPath Transformation to get the data like HASP Plate 01 Sensor - ESP Version. In the PaperUI, choose Configuration -> Extensions -> Transformation (it’s the Headline) LINK

The Nextion editor is what you can use to edit the screen directly it is a very powerful little screen that you can execute code on.

Nextron also have an enhanced version of the screen which has 8 IO on-board. I was thinking of using one of those boards in each room to control some items directly so if openhab stops working or the pi dies it won’t effect the ability to be able to turn the lights off. I think I will need this to get WIFE approval.

Things I am Currently working on

  • Backlight rules to dim backlight when lights are off
  • Turn screen backlight off after time and back on when press detected
  • Change background colour of buttons to show state

(James Bowler) #19
  • Backlight rules to dim backlight when lights are off

Missed it until now but they use the expire binding to turn off back light.

If you install the expire1 the backlight turns of and when you press the screen it turns on and also unfortunately you also trigger the button.

(B K) #20

Good change! I didn’t think of using the Plate_Status, and had a hard time with the rule sending that entire batch of init data to the plate constantly, so I went with something more manual (i.e. the “Refresh” switch). I’ll try your way to see if that works without the constant resends.

Yes - sorry for not making that obvious in the first post - I’ll update it so others don’t come across the same issue.

luma has done a lot of work to make that HMI flexible and useful for many different applications. I haven’t seen the need to make any updates to the HMI layout, but you’re right, it’s very powerful. Just be aware that Nextion is basically re-branding TJC display hardware and software (half the price, more functionality on the TJC side). You can get the TJC displays cheaper on eBay, and use the firmware/HMI firmware luma made available on his GitHub, to save on the cost.

I already do this in my rules, using the expire binding. Just set the value in the expire=“30s,command=OFF” clause in the HASP_Plate02_Light_Power item definition to what you want.

The other two things you’re working on are specific to personal setups, but very cool, too! The button background color change is something @pkhajanchi also suggested, and I’ve been thinking about how to do that. The colors are currently hardcoded into rules, and Pankaj suggested I use variables at the top of the rule. But, I’d like to take that a step further, and have Color items in the main configuration, which would be used to send the background/foreground color to the HASP. The biggest issue is the HMI uses a non-standard color code (integer value between 0 and 65536), so there has to be a translation rule that will take the HSB type from the Color item, and translate it to the Nextion value).

Fortunately, the conversion has already been figured out, and there’s even a converter site on Github (https://nodtem66.github.io/nextion-hmi-color-convert/index.html) so we can use the formula in our transcoding rule.