HA SwitchPlate HASPone: DIY In-Wall Touchscreen Home Assistant Controller

Nice project but I’d design the screen a bit more colored .

Good news - you can! I’ve stuck with a simple black-on-white theme just to match the white wall plates I’ve been printing, but you can change every color you see in the pictures above from Home Assistant by sending MQTT commands. Further, you can add your own custom graphics by modifying the provided pages (or starting from scratch with your own) using the Nextion editor.

To demonstrate, I can make a Hot Dog Stand theme (the best Windows 3.1 theme) that looks like this:

To do that I issued the following commands to set the page background color to black, and each of the 4 scene buttons to red on yellow:

mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[4].pco" -m "63488"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[4].bco" -m "65504"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[5].pco" -m "63488"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[5].bco" -m "65504"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[6].pco" -m "63488"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[6].bco" -m "65504"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[7].pco" -m "63488"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].b[7].bco" -m "65504"
mosquitto_pub -t "homeassistant/haswitchplate/HASwitchPlate/command/p[1].bco" -m "0"

I’ve been working on some substantial changes to allow better two-way communication with the LCD to enable things like sliders. Along the way I’ve discovered that SoftwareSerial presents problems when doing a lot of communications back and forth. The common wisdom (which I had been ignoring up until this point) is that the Nextion panel really should be connected to a hardware UART. Fortunately, the WeMos has two hardware UARTs. Unfortunately, the assigned pins are heavily overloaded for other functions, resulting in issues with flashing the ESP8266 when the panel is connected.

I’ve worked out a solution which allows the device to send startup information over the normal serial port so the developer can see information like the IP address when the device starts up. It then changes the pin assignment for TX to the panel on UART1 (Serial) and RX from the panel on UART2 (Serial1) without interfering with boot modes or USB programming. This does prevent the user from being able to monitor serial debug output after bootup, but that function can be restored by either hooking up an additional serial interface or by running a jumper from D8 to TX (but that will need to be removed again to flash). This is only going to impact folks working on development of the Arduino code, but as I’m a folk that’s working on the Arduino code it’s an issue I’ve spent a lot of time on :slight_smile:

My next task is to enable Telnet debug output without consuming a bunch of resources which I think will also be helpful. With these changes in place it may lead me to a position where I can enable over-the-air updating of the LCD panel which is a huge milestone for this project. If I can get that working reliably it’ll allow development of the LCD interface while the device is mounted in the wall without a screwdriver and a trip to the breaker panel.

While adding the slider capability I ran into another couple of problems with my existing code that will once again result in namespace-breaking changes. First, I made the rookie mistake of using one topic for both command and state messages which causes all sorts of issues. As a result, the namespace is now going to be broken down into commands which are sent to the panel, and changes coming from the panel (button presses, slider value changes, return values from lookup requests, etc) will be sent out on state. This is in keeping with Home Assistant convention used on other MQTT devices and now I understand why that’s a thing. Yay learning!

Second, I’ve encountered an issue with my nomenclature that had been masked by how I named the objects in the HMI file I’m using. For details on this issue you can read through a question I’ve posted on the Nextion forums. The long and short of it is that another change to the namespace is going to happen. Currently, events coming from the panel (like a button press) are sent out on an MQTT subtopic like nextionattr/p1b2, meaning page 1 object 2. That is going to change to state/p[1]b[2].

Commands sent to the panel will use the same convention, so you can set the text label on that button by sending a message on command/p[1].b[2].txt with the text to assign in the payload (don’t forget the double quotes!). This will provide a consistent mapping between object references coming into and originating from the panel. It also means that the object names used in the Nextion editor become irrelevant, everything will happen by objectID.

However - I may revert to the original behavior of using the object names if someone can answer the question I posted on the Nextion forums, but at this point it’s looking like object IDs are going to be required. Update: one word respone from the Nextion folks was all I needed, which was… “no”. Looks like Object IDs are how we need to proceed!

This thread excites me greatly

3 Likes

Do you have links to the blue wire connector you mounted to the protoboard?

Any idea what the difference is between the NX3224T024 and NX3224K024. I got the K model because that is all they had in stock on amazon.

1 Like

In the Electronics Assembly docs you can find a BOM along with a link to these guys I picked up from the big river.

Thanks for asking about this, questions of this sort help me identify areas where my documentation isn’t clear. In this case I have two BOMs in the docs, one for prototyping and one for the remaining parts needed for the actual build. I’ll work on clarifying the language.

The “K” model is the “Enhanced” model. It adds some features that I’m not making use of in this project and for the moment you’ll have to compile the provided HMI file using the Nextion editor to generate a compatible .TFT binary image for the panel. The process is straightforward but I’ll start running builds for that device in upcoming releases to save that step as it seems like a common issue folks are going to have.

I’ve been away for a while but still following this thread. Very impressive with the level of detail and development happening. I’ll admit that some of the more abstract concepts of the HMI and MQTT are still foreign to me and I struggle with understanding them, but I get the general idea of how it all interacts.

If I might make a couple suggestions on the prototype. The high voltage terminals (blue connector) required the whole box to be disassembled, or at least the enclosure be removed to insert and secure the wires. Do they make a right angle style connecter where you could insert wires from one side and have access to the screw terminals around the corner? In industrial controls, they use a lot of phoenix connectors (L1, N, GND) with securing screws so that might be an option. Also, having the wires enter from the top could make it difficult in some installations where wires have to be bent at 90 degrees to fit into the electrical box, so adding a different connector that allows connection on the back would alleviate that issue.

The connectors I used were selected on account of being on-hand from a previous build :smiley: My intention is to use a pigtail arrangement, where you’d attach short leads during assembly and just leave them connected to the board at all times, then use lever nuts (wire nuts, etc) to connect the unit to AC mains.

Still, these are all good suggestions and I might spend some time sourcing a more suitable connector arrangement. I really appreciate the helpful feedback!

Allright I’ve just pushed some pretty major changes to the GitHub repo which include some namespace-breaking changes to the MQTT command structure. These changes will allow full two-way communication with the panel in a manner which should be flexible enough to handle most future use cases. I’ve also made changes to the pin connections to allow for hardware serial UARTs which should prevent any data corruption in longer messages sent to and from the panel.

I’ve updated the documentation to make the BOM easier to find and have included a compiled version of the Nextion UI for Enhanced model panels in response to user input above.

Finally, I’ve added remote debug capabilities so you can telnet to the device to receive debug messages while working on your automations or code (this can be enabled/disabled at compile time). A bunch of code cleanup has been done as the size of the Arduino codebase is exploding (and I still have work to do). The result is a very fast experience, and I think I should be done with breaking namespaces.

I get Wifi connected and mqtt connected with IP addresses. How do I get the button to load? I uploaded the HMI via the nextion editor

By default the device is going to stay on “page 0” which is that initialization screen until told to do something else. You need to tell it to switch pages via an automation or some other action.

For testing you can switch pages by sending the device MQTT messages like this:
mosquitto_pub -h <mqttbroker> -t "homeassistant/haswitchplate/HASwitchPlate/command/page" -m "1"

The example automation scripts provide a mechanism to switch pages using the 3 buttons along the bottom of the page. If you use the configuration.yaml and automations/HASwitchPlatePages.yaml files in the repo, you’ll find a series of input_slider and input_text objects that look like this in the UI:


In the top set of input_text objects (you need to be running .53 for these) you can enter the text that appears on each of the 3 buttons. The sliders “HASwitchPlate Page Button [1-3]” allow you to select which page number each button will switch to. Finally, the “HASwitchPlate Active Page” slider allows you to manually select a page from the web UI, and will be updated if the user changes pages on the panel.

In this example I have the left-most page button (button 1) labeled as “Scenes” and set to page 1. The slider doesn’t show the numbers until you click on it, so it’s not super clear but I have button 2 (“Status”) set to page 2 and button 3 (“Media”) set to page 8 which I assigned just by dragging back and forth. The page text and actions will update in realtime with the included automations, so you simply type in the text you want to appear on each button and then drag the slider to the desired page and Hass will remember that value for you (if you have “history” enabled anyway).

Add the content (all 500 lines!) of HASwitchPlatePages.yaml to your configuration along with the input_text and input_slider objects defined in the example configuration.yaml and you should have what you need to switch between pages using UI elements to control the interaction.

Now might be a good time to learn how to use configuration splitting to make this easier to manage. The provided configuration.yaml uses this approach as an example to work from.

1 Like

Question: are you still able to send device level commands to the HMI panel through MQTT? In a previous version of the code, there was a separate “nextioncmd” topic that would push a command straight to the HMI over serial. This was separate from the “nextionattr” topic which was for the page/button elements. Things like display sleep on no touch input (“thup=1”) or the display sleep timeout (“thsp=300”). Was this rolled into the single “command” topic?

Raw instructions can now be sent on the /command topic (no subtopic) with the command to execute in the message. If the command returns data that the sketch understands (currently only button presses, page “sendme” responses, get responses for strings or numbers, and touch x,y), then the return data will show up as a message published to the /state topic. I’ve updated the MQTT docs a bit to lay some of this out but it’s probably not as clear as it should be.

Ok so it’s all rolled into one command topic. Thanks. Also with the return data on the state topic we can incorporate local display dimming with an automation based on touch x,y input increase the display brightness, then after x minutes, dim back down. That’s an idea I had from the beginning and was using HMI commands for display timeout, but while the display was sleeping, it wasn’t getting updated.

EDIT: The answer to my question was probably in the documentation you have, I probably just didn’t look hard enough.

It would be nice to integrate the MQTT alarm component into this project. Also maybe throw a little battery internally like a little built in UPS.

1 Like

There are keyboard and numeric input components in the HMI software that can be added along with internal variables for storing the numeric entry. I haven’t played around with it much but all one would have to do is add the numeric entry that calls a keypad, then if the variable/number entered is available over serial it can be sent over MQTT to HA.

1 Like

When I started this project my major goal was to be able to modify how this device works without pulling it out of the wall. That desire informed a lot of the original decisions being made, and is why I’ve kept most of the automation and interaction code on Home Assistant because making configuration changes to Hass doesn’t involve a trip to the breaker panel.

After a whole lot of work, I’ve finally put together a working approach for OTA updates for both the ESP8266 (easy) and the Nextion LCD (NOT EASY!).

I am extremely proud to announce that both goals are accomplished and I am currently printing out an enclosure for what will be the first version that I intend to mount in my wall and leave there.

LCD updating works by issuing an MQTT command like this:
mosquitto_pub -t homeassistant/haswitchplate/HASwitchPlate/command/update -m 'http://192.168.0.10:8123/local/HASwitchPlate.tft'

I’ve copied the compiled HASwitchPlate.tft to the ~/.homeassistant/www folder on my Home Assistant installation and with that MQTT command I have instructed my device to download the tft file from the Home Assistant web server.

Note that this process is not bulletproof - there isn’t room on the panel to run a failback A/B firmware image, and there are several ways this can go sideways when wireless is involved. Throughout this process I have yet to brick the panel across dozens (hundreds?) of failed attempts, but you do have to pull power on the panel and re-flash to get it back in shape. So… exercise caution here and there may still be a trip to the breaker in it if things go sideways. Still - this is good enough for me to start installing around the house as I’m now confident that I’ll be able to manage these devices in a reasonable way.

6 Likes

More new features! Adding the ability to query a value on the panel opens up a lot of possibilities, like sliders!
Media player with volume slider Dimmer controls

The example automations show how to react to a slider. When the user releases a slider you can respond with a request for the new value, and then set things like a dimmer, cover, or volume control in response.

I’ve made some minor modifications to the enclosure to make it easier to print and more rigid all around. Here’s a recent version monitoring the status of the print job that will replace it:

2 Likes

typo in your dimmers HA automation script. line 95 should be light.light_3 not light.light_1. Otherwise, this is great.

Also I tried downloading the 3D printed enclosure. The front plate downloads from GitHub just fine. However, I am unable to download the rear enclosure. Can you set it as downloadable? Thanks.

1 Like

Awesome project! Great job! I will definitely try and build one myself (parts are ordered! :slight_smile: ).