Unipi neuron home assistant setup
Martijn Hemeryck last edited by Martijn Hemeryck
I recently tried out a setup with my unipi neuron L303 with home assistant, a python-based open-source framework for integrating various IoT and home automation devices and services. Since it did turn out to be actually quite simple, I figured to share it here.
Unipi neuron modbus server
The picture in this post helped a lot: basically, I had a (headless) raspbian stretch image where I installed evok on, which also installs the unipi neuron modbus server. As I understood it, all I/O on the I/O boards are connected over SPI and are continuously polled. The modbus TCP overlay is just a way to expose this information.
Home assistant setup
Installing home-assistant on the unipi is rather straightforward as it's specifically targeted for platforms such as the raspberry pi. The official hass installation docs now prefer you to use their docker-based installation hass.io. While I do like this idea (and will use this myself on the longer term), for testing purposes I decided to just use the old-style python-pip based installation.
Install pip (python package manager) for python3.
apt-get install python3-pip
Home assistant requires some specific python3-based features (e.g. async handling of events with
asyncio) ... and you should use python3 anyway.
Install home assistant
pip3 install --user homeassistant
--useroption installs it in a folder of your own user.
Start running it:
You can now access it under
$NEURON_IP:8123(default hass port)
When adding an integration (such as modbus), home assistant will automatically install the required dependencies for it (such as pymodbus).
Home assistant configuration
Now, how to glue these two together. Home assistant uses simple .yaml files for configuration. The main config file is
configuration.yaml; see hass configuration.yaml for more details. My config file was under
I did add the following lines to this file specifically for modbus (comments added)
# register the modbus-tcp platform modbus: type: tcp host: 127.0.0.1 # localhost; just check on this machine port: 502 # default port number from modbus tcp neuron overlay switch: platform: modbus slave: 1 # field is required -- but not checked for modbus TCP scan_interval: 0.1 # polling speed coils: - name: User programmable LED X1 coil: 8 # modbus register mapping slave: 1 - name: User programmable LED X2 coil: 9 slave: 1 - name: User programmable LED X3 coil: 10 slave: 1 - name: User programmable LED X4 coil: 11 slave: 1 # reading a digital input binary_sensor: - platform: modbus scan_interval: 0.001 coils: - name: Digital Input 21 coil: 100
This is only just a test setup where I can control the 4 test leds on the neuron and read out one of the digital inputs.
I was actually amazed myself how simple the setup was to integrate both platforms -- so great work on the hardware and the modbus TCP server overlay.
This was just a test setup for me, some more things I'd like to check:
- polling speed: the inputs respond rather slow atm, so I'd like to check how to increase the speed there. I'm curious where the bottleneck is; on the SPI polling or on home assistant polling the modbus server itself. On SPI level, I am curious whether it is possible to have more of a interrupt-based system.
- inputs as actual push buttons: the inputs should really toggle, rather than follow the input value. I know it's possible to manage this simply in home assistant, couldn't find it directly
- outputs: haven't checked driving the outputs yet. Is it actually possible to directly drive e.g. a 24V LED strip from the digital outputs (not relays -- the L303 only has limited outputs)
thanks for sharing with us your experience with UniPi! The guys from Home Assistant really did a great job with simplifying the connection to Modbus slave devices, thus making it easy to integrate with our controllers. Kudos to them as well!
Now to your questions:
1. Polling speed
As you already found out, the polling nature of the Modbus protocol is really something that doesn't make it suitable for time critical applications. The problem doesn't lie in the SPI communication between the RPI and the underlying HW, but rather in the communication between Home Assistant SW and the Neuron ModbusTCP Server. As I can see from your config file, you set the polling interval to 1ms. I don't have any numbers at hand to support my allegations, but I don't think the Home Assistant is able to poll the Neuron ModbusTCP server that fast.
But we do have a solution of sorts to overcome this limitation and it's called the direct switch. This is a built-in functionality in the DIs to directly control a DO or RO. This control is configured via Modbus register and after that, it works without any other software. The direct switch has (so far) 3 modes of operation:
- Copy: The status of the DI is copied to the DO/RO. So when the DI is TRUE, the DO is TRUE and when the DI is FALSE the DO is also FALSE
- Copy (Invert): Same as above but inverted. When the DI is TRUE the DO is FALSE and vice versa.
- Toggle: This mode toggles the DO on the rising edge of the DI. Handy for controlling a light with momentary switch for example
2. Inputs for momentary switches
We don't such functionality right now (e.g. toggling the value of some Modbus register upon DI event), but it can be mimicked by the Toggle function of the direct switch to some extent. See above.
Each DO is able to source up to 750mA continuosly or 1A in pulses and it can switch 5-50V. You can connect a relay to the DO, if higher current or voltage is needed for switching.
Have a nice day,
Martijn Hemeryck last edited by
Thx for your quick reply! I have some more remarks / questions in follow-up; (perhaps I can start some separate topics on some of these).
1. Polling speed
I can see the value of this direct switch functionality, but I would rather have the connection of input-to-output managed at a higher level (e.g. home assistant). Besides, the number of outputs on the L303 is not enough for that. Will have a look at the toggle function though!
Events instead of polling
I was also wondering whether there could be a simpler way to capture events from the SPI-interface. A lot of IoT solutions nowadays use protocols specifically for this, like MQTT; home assistant has a lot of support for it and e.g. arduino also has libraries for it. For my home automation setup, I would like to expand the number of IO and platforms, so something like MQTT has the added advantage to add more neurons that can run independently, but communicate directly with MQTT.
What would the best way to do this translation; I am thinking of:
- SPI polling: rather than having the modbus TCP server expose it, push the events out directly when they are found
- modbus TCP server polling: one layer higher, create an interface that connects the modbus TCP server with an MQTT broker
- PTY polling: on the same level, the SPI devices are also available through a PTY, so I could also have a similar interface between the PTY and an MQTT broker
- home assistant: write my own unipi-to-home-assistant integration -- but this would effectively do the same kind of polling as the hass modbus solution is doing right now
The fastest would probably be the SPI polling solution, directly connecting the polled SPI interface with an MQTT broker. I don't have that much experience with this low-level coding though, so it seems pretty hard. What are your thoughts on this? (perhaps I should move this to a separate topic)
On a related note, currently, the RPI seems to polling the SPI devices, but is there also a way to have the SPI devices directly trigger (interrupt?) the RPI? This seems even harder though and I am not sure whether there is that much advantage to it in practice.
2. Momentary switches
The toggle function is something I could indeed do perfectly at this level; no need to emulate this at a higher level such as home assistant.
I already tried to directly connect a 24VDC LED strip and toggle the DO, but this didn't seem to work. I'll probably need some more time to investigate it.
Lighting: DALI controller
For my lighting solution, I would actually like to build a DALI controller (yet another topic). The shop mentions the axon S605 to be suited for this, but I don't seem to be able to find any further documentation for this. Ideally, I would just have the axon run its own linux distro and have a common DALI library on it to interface with the DALI bus. I would then write my own MQTT client as a bridge between the DALI interface and the other unipi. Not sure how realistic this is though.
FYI, some background:
- I'm a software dev, currently mostly involved with python full-stack web development
- I have a background as an electrical engineer, with some experience in embedded software development and signal (image / audio) processing
- I'm currently in the process of building a house, so anything with respect to home automation is still possible atm. While much of the IoT solutions all focus on wireless solutions, I prefer wired solutions where possible.
thanks for such comprehensive information!
The direct switch indeed is for special cases and I can understand, why you want to deal with this in the software. The limited number of outputs of L303 is one of the many reasons. But that leaves you with emulating momentary switch in the software, for now.
The reason why we picked polling instead of events is that even on the SPI level we use Modbus protocol. Therefor it is less resource consuming to "reshare" the HW values over our ModbusTCP server. The polling of the underlying HW via SPI is not what has the highest impact on the responsivness, because it happens in sub-milisecond intervals. The real slow down happens in applications which use the data - the software PLCs, like Home Assistant. If you are looking for fast and deterministic PLC, you have to look into HW PLCs like Mitsubishi, Omron, Siemens, B&R,... But then you will lose the flexibility.
Replacing the ModbusTCP server with MQTT client would be technically possible, but we don't have any ambitions in this area (yet). But we can support you with neccessary information about the SPI communication we use, if you decide to do it on your own.
Connecting 24V LED strip to DO should definitely work, if you are sure you will not draw more then 750mA. You can check the presence of 24V on the DO turned ON with multimeter. If there is another voltage or no voltage at all, the DO is burned.
DALI. This is a chapter on its own. And since you're not the only one asking about it, I have good news for you. Check this thread: https://forum.unipi.technology/topic/691/evok-dali-support-apis/4
Writing a DALI-MQTT bridge is certainly doable and with python-dali it should be a piece of cake for you, as a seasoned python dev. But the DALI itself is bit complicated, especially in autodetection of unaddressed devices.
Martijn Hemeryck last edited by
Thanks for the reply. In short:
- Modbus TCP - MQTT: I'll probably just start off simple, by polling the Modbus server and exposing any changes as MQTT events. That way, I can get some feel with the setup and I can dig deeper later on. It's nice to know I can come back here for some assistance :)
- the LED strip: tried it the other day, and it just works; I hadn't taken the time before to properly connect them.
- DALI: looking forward to hearing more about it; had already seen the thread / python-dali before. Just good to see I'm on the right track here :)