Hardware orientation for home automation project

Topics about the Hardware of Revolution Pi
Post Reply
mdingena
Posts: 6
Joined: 15 Aug 2018, 12:47

Hardware orientation for home automation project

Post by mdingena »

Hello,

I'm doing research on home automation, and I've stumbled across Revolution Pi. I'm trying to see if this matches my intentions. Can you please help me put together the correct setup?

I'm a software developer by trade. I'm not very familiar with electrical engineering, but I have friends who are much more familiar with it than I am. I want to automate equipment in and around my home. It will go beyond the basic on/off switching of lights; the intention is to be able to create "scenes" to change multiple devices simultaneously for a given situation. The situation can be based on multiple factors, like geofencing, weather, time of day, and other inputs.

I'm comfortable programming in JavaScript and PHP, and so naturally I'm looking at Node.js solutions. I understand that real PLCs are programmed using Ladder Logic, but if I can avoid learning a new language, that'd be great. I've read here that with your latest RevPi image, you are including Node-RED out of the box. But I've had a hard time finding information on the forum newer than 5 months old about whether or not the community or KUNBUS has succeeded in developing a driver to let Node-RED talk directly with the process image on the RevPi Core. The most recent solution I've read here was to use the "piTest" program that comes with RevPi in a Node-RED node to read the state of the process image. A video tutorial on this would be much appreciated.

There are still some parts of the puzzle that aren't very clear to me. Some of these are general concepts which were unfamiliar to me until last week, such as ModBus. When I'm researching domotics and PLCs, ModBus is something I stumble across a lot, but I don't actually know if I really need ModBus functionality. I'm very familiar with MQTT, and I can easily see a home automation network working purely with MQTT. I believe I've read here that RevPi support MQTT as well. Actually, I'm not sure if that is only the RevPi Connect, or if all of them support it, which is another question I have: is there a comparison chart that compares Core, Core 3 and Connect modules? That'd be great.

All of this is still theoretical, and it's getting a bit crowded in my head :lol:

This is how I think my setup would work:
  • Using a RevPi Core or Connect, a program runs every x milliseconds.
  • A connected DIO module would allow me to control some equipment in the house. For example, the DIO module could control 14 relays, which turn on or off 14 different things in the house.
  • All of the DIO module changes would be saved in the Core's process image. This is, I believe, the "source of truth" about the RevPi state, which I can use to read values from or write new values to.
  • Every time the Core program runs (cyclically, every x milliseconds), I believe the process image should have the latest state of the RevPi.
  • When the process image is updated, Node-RED would update its nodes which use the process image. This would be the starting point for many automations built with Node-RED.
  • When anything (manual input, or automated process) causes Node-RED to change one of its outputs, it has to somehow (?) write the new state back into the RevPi's process image.
  • The DIO module would receive this change from the core, I guess? Then it would change its outputs according to the new process image state.
  • At no point would Node-RED try to read or write directly to the DIO module. This part is slightly confusing because there are some resources online that seem to imply to do that. From what I've read on this forum, that is anti-pattern; everything should go through the process image.
When I need to exchange more complex IO than low/high signal, the concensus seems to be to use ModBus. In your video tutorial you show how to send the data from a temperature sensor to the RevPi over ModBus. I can see the same thing being possible using MQTT. I believe ModBus master is included with the Core (or Connect??), but there are no tutorials on MQTT, although I think I've read you also support that.

Basically, to automate my home in JavaScript, I think I'd need (to prototype):
  • RevPi Core 3 (or Connect??)
  • DIO module
  • ... and nothing else, assuming Node-RED and MQTT are supported out of the box.
If that is really the case, I think I'll give Revolution Pi a go! :)
User avatar
dirk
KUNBUS
Posts: 2174
Joined: 15 Dec 2016, 13:19

Re: Hardware orientation for home automation project

Post by dirk »

Hello, I'll try to cover your questions from bottom to top:
The RevPi Connect is like a RevPi Core 3 but with additional features like hardware watchdog, RS485, 2 separate RJ45 ethernet interfaces, etc... Have a look here for the details.
So if you want to use two independent ethernet interfaces (wan and lan) or you want to use a RS485 interface i.e. for ModbusRTU you better use the RevPi Connect as you don't need additional hardware like a USB RS485 converter.

The DIO modules are available for the RevPi Connect (up to 5 DIO modules) and for the RevPi Core 1 and 3 (up to 10 modules).

So yes just use a RevPi Connect or Core and a DIO Module and you are ready to use MQTT i.e. by Node Red with JavaScript as control logic.

As you are familiar with JavaScript then Node Red is perfect for you. We here also use Node Red to access the process image with a command block that calls "piTest ...", why not?
There are also RevPi-Blocks available for Node Red but unfortunately without the possibility to use variable names for the I/O access. And that is possible by i.e. "piTest -1 -q -r RevPiStatus".

Unfortunately I do not know domotics so I cannot help in this topic.
Modbus TCP or RTU are lightweight protocols that may also be easily implemented by small microcontrollers like Arduino. So for home automation it could be of interest for you maybe in the future.

So like you already said the process image acts like a central store of the the I/O data.
It is cyclic updated thus your control logic has also to run cyclic. And yes if you write a 1 to a digital output in the process image the data is applied on the DIO module with a maximum delay of 2 update cycles i.e. 5-10 ms.

We also think about providing a tutorial in the form of text and / or video but this will take time.
mdingena
Posts: 6
Joined: 15 Aug 2018, 12:47

Re: Hardware orientation for home automation project

Post by mdingena »

dirk wrote: 17 Aug 2018, 17:18We here also use Node Red to access the process image with a command block that calls "piTest ...", why not?
Let's assume I've got a house with 70 buttons and 70 relay switches. I'd use Connect + 5 * DIO. Now, every cycle, Node-RED would have 70 command blocks that check for the state of the inputs. I can imagine it's not very efficient to run that piTest command 70 times. Is there a way to run it once for all inputs, and logically separate them in Node-RED?
User avatar
dirk
KUNBUS
Posts: 2174
Joined: 15 Dec 2016, 13:19

Re: Hardware orientation for home automation project

Post by dirk »

Yes I agree with you that this is not a performant way to build an application. An alternative way is to read two bytes and you get all inputs of one DIO at once.
For example you have a DIO on input offset 0 you can get a decimal, hexadecimal or binary value representation of all inputs by:

Code: Select all

pi@RevPi:~ $ piTest -1 -r 0,2
  0   0
pi@RevPi:~ $ piTest -1 -r 0,2,h
00 00
pi@RevPi:~ $ piTest -1 -r 0,2,b
00000000 00000000


Then you can to parse this value in order to get the status of each input channel. Maybe you can use the Node Red String-Contrib package for that.
So if you have N DIOs you have to read two bytes N times on each offset.

Or you can read the entire process image with one singe command:

Code: Select all

pi@RevPi:~ $ piTest -1 -r 0,4096
255 255   0   0   0   0   0   0   0   0
...

All in all this is also not the user friendliest way, I know. We here see that better Node Red RevPi support is necessary.
Currently we are also experimenting with Node Red in order to provide some RevPi Node Red enhancements for the community.
But you have to be patient because this is a prio 2 thing and therefor will take time... :roll:
User avatar
RevPiModIO
KUNBUS
Posts: 335
Joined: 20 Jan 2017, 08:44
Contact:

Re: Hardware orientation for home automation project

Post by RevPiModIO »

We do node.red + RevPi with MQTT and RevPiModIO (fast and low cpu usage).


We just install mosquitto on the RevPi

Code: Select all

pi@RevPi0000:~ $ sudo apt-get install mosquitto mosquitto-clients

If you are using node-red on the RevPi you can restrict access to mosquitto to localhost only (if not you can access the IO-Data from every were on your network)

Code: Select all

pi@RevPi0000:~ $ sudo nano /etc/mosquitto/conf.d/localhost.conf

# And insert this line
bind_address 127.0.0.1

We need RevPiModIO2 for our Python Program (and we use revpipyload to run our python program on the RevPi):

Code: Select all

pi@RevPi0000:~ $ sudo apt-get install python3-revpimodio2 revpipyload


And configure RevPiPyLoad MQTT settings to your needs! It is all integrated in in that!

https://revpimodio.org/en/revpipyplc-2/ ... ad/#config


################ STOP! #############
#
# This part is now integrated in RevPiPyLoad
# and you do not have to write own code!
#

For MQTT and Python we need the paho-mqtt library which we have to install via pip3

Code: Select all

pi@RevPi0000:~ $ sudo pip3 install paho-mqtt

And this is the Python Program which we have in /var/lib/revpipyload/pythonmqtt.py and let RevPiPyLoad execute it.
https://revpimodio.org/en/revpipyplc-2/revpipyload/

Code: Select all

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""MQTT2REVPI for Node-Red MQTT-Nodes."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "GPLv3"

import revpimodio2
from logging import getLogger
from os.path import join
from paho.mqtt.client import Client

logger = getLogger()


class RevPiMqtt():

    """Manage IOs with MQTT."""

    def __init__(self):
        u"""Init RevPiMqtt-class."""

        # MQTT Variables - Change for your requirements 
        self.mqtt_base = "revpi01"
        self.mqtt_user = "user"
        self.mqtt_pass = None
        self.mqtt_server = "127.0.0.1"

        # Write Outputs with MQTT with Topic 'mqtt_base/set/outputname'
        self.mqtt_writeio = True

        # ----- Mainsystem -----

        # RevPiModIO for monitor IO-Events
        self.rpi_events = revpimodio2.RevPiModIO(
            autorefresh=True, monitoring=True
        )
        self.rpi_events.handlesignalend()

        # Another RevPiModIO to just write Outputs if you like - With this
        # technique, other programs in the background can control the process
        # image without interfere
        self.rpi_writer = revpimodio2.RevPiModIO()

        # MQTT
        self.mq = Client()
        self.mq.username_pw_set(self.mqtt_user, self.mqtt_pass)
        self.mq.on_connect = self.mqtt_connect
        self.mq.on_message = self.mqtt_message
        self.mq.connect_async(self.mqtt_server)

        # Configure Events to Inputs
        for device in self.rpi_events.device:

            # Use IO Modules only
            if device.type != "LEFT_RIGHT":
                continue

            # Use Inputs with set 'Export' flag in piCtory
            for io in device.get_inputs():
                io.reg_event(self.io_changed)

    def io_changed(self, ioname, iovalue):
        u"""Send IO-Value to MQTT."""
        self.mq.publish(
            join(self.mqtt_base, ioname),
            int(iovalue),
        )

    def mqtt_connect(self, client, userdata, flags, rc):
        u"""MQTT Connected."""
        if rc == 0 and self.mqtt_writeio:
            # Subscribe 'mqtt_base/set/outputname'
            self.mq.subscribe(join(self.mqtt_base, "set", "#"), qos=2)

    def mqtt_message(self, client, userdata, msg):
        u"""MQTT Nachricht empfangen."""
        lst_topic = msg.topic.split("/")
        ioname = lst_topic[-1]

        # Check Output exists and is an Output
        if ioname in self.rpi_writer.io \
                and self.rpi_writer.io[ioname].type == revpimodio2.OUT:

            # Convert MQTT Payload to valid Output-Value
            value = msg.payload.decode("utf8")

            if value.isdecimal():
                value = int(value)
            elif value == "false":
                value = 0
            elif value == "true":
                value = 1
            else:
                logger.error("can not convert value '{0}'".format(value))
                return

            # Write Value to RevPi
            self.rpi_writer.syncoutputs()
            self.rpi_writer.io[ioname].value = value
            self.rpi_writer.writeprocimg()

        else:
            logger.erroer("can not find Output {0}".format(ioname))

    def start(self):
        u"""Start your system."""
        # Start MQTT System
        self.mq.loop_start()

        # Start Mainloop of RevPi Eventdetect
        self.rpi_events.mainloop()

        # After exit the Mainloop disconnect MQTT
        self.mq.loop_stop()
        self.mq.disconnect()


if __name__ == "__main__":
    root = RevPiMqtt()
    root.start()
#################################################
################### CONTINUE HERE! #################

If a value of an Input change than the program will publish that with topic 'revpi01/event/ioname' and the Payload is the new value.
Check with mosquitto_sub:

Code: Select all

pi@RevPi0000:~ $ mosquitto_sub -t '#' -v

revpi01/event/pt2 251
revpi01/event/pt2 250
revpi01/event/pt2 251
revpi01/event/I_1 1
revpi01/event/I_1 0
revpi01/event/I_1 1
revpi01/event/I_1 0
revpi01/event/pt2 250

Than we are using node-red with MQTT nodes.

CAUTION: The topic of mqtt input node must be renamed from "revpi01/I_1" to "revpi01/event/I_1" !!!!!
Screenshot_20180822_123359.png
Screenshot_20180822_123359.png (27.84 KiB) Viewed 14840 times
For set an output we publish the Value 0 / 1 | 'true' / 'false' with topic 'revpi01/set/ioname'.

Regards, Sven
python3-RevPiModIO - https://revpimodio.org/ || Der RevPi ist das Beste, was passieren konnte!
Post Reply