I have been thinking this over for a while and wondering my best strategy.
I have a number of raspberry pi’s - probably more than I will ever need. One is set up running home assistant in my study, near the network switch and other server gear.
I have another pi with a 4 port relay shield on it. My garage has three doors, each will be attached to a relay on the pi, I have trialled that and it works well with a simple commandline program to switch the relay on momentarily and that works like the button remote.
My problem is connecting the garage pi to homeassistant. The raspberry pi cover component is clearly for a garage door connected directly to the pi running home assistant, as the only config is setting which GPIO pin does what.
My thoughts are either:
develop a script on the garage pi that pubs and subs to MQTT cover topics on the HA pi. Possibly beyond any scripting I have done to date; or
Use any of the web server based pi scripts that are all over the net on the garage pi, and use a commandline cover component on the HA pi;
I saw somewhere (and can’t find it again) that you can have two linked HA installations, then I could put HA on the garage pi and use the RPi cover, link it back to the HA server in the study. Is this even feasible?
I think this is an excellent summary of your options.
Option 3, having a second version of HA, always seems to me the wrong tool. You are essentially using the second version of HA as an MQTT client. Since it has so may components, many things can go wrong.
Any of the other options, including using SSH seem sensible to me, and which option you pick I think depends on how comfortable you are with each.
I suggest going with MQTT as it’s much, MUCH faster than SSH (speaking from experience). It also limits what the main system can do to the other system (because if you’re using SSH you’ll have to store the password for the other system somewhere).
Install mosquitto broker on your main system where you run HASS, set it up (make sure you use authentication) and add it to HomeAssistant.
Add mqtt_switch switches to HomeAssistant.
Now, on the system that’s in the garage, install mosquitto and use mosquitto_sub to subscribe to the topic that the main system will sent the commands to.
I’m not sure how experienced you are with all of this, but in case you need help or an in-depth explaination and steps for what I’ve just written, or even the code for this, just say and I’ll be glad to help!
I have to disagree here. SSH does not require passwords. In fact if you are using passwords for ssh that makes it more unsecure then using public/private keys.
Still goes the same way. If you’re planning to leave your main system running headless, without you needing to enter any credentials when it boots, the other (garage door) system is unsecured as well if an attacker gains access to the main system. I mean, it’s a bad thing if it happens either way, but when using MQTT you can at least do some damage control, because:
The only thing the main system has access to on the garage door system are the MQTT topics the garage door system is subscribed to, and the commands it reacts to, while if you were using SSH, the attacker could do anything on the garage door system too.
In case you’re using SSH (Password or Private/Public Keys):
The private key to access the garage door system will be located on the main system. The attacker can copy it, just like he would copy the password if it’s stored.
So basically you are saying that the reason you would prefer MQTT is because in case his main raspberry pi gets hacked the attacker is not able to fully control the other raspberry pi which controls the garage door. Sorry but I don’t see any possible real value here. All this does add a layer of security that is totally theoretical. It would be different if this would allow access to another PC that is actually used. But if I understood correctly, that pi only is used for HA things. If the attacker got access to his main pi there is absolutely no way he would need to access a pi in the garage as he already has pretty much everything. Secrets.yaml etc. I don’t think an attacker would even care about that thing in the garage. Everything that that thing does he is now able to control anyways.
As for speed I did not test this myself but I can’t imagine ssh being slower then mqtt. As I don’t see any reason for it to be. Mqtt also adds overhead imho (installing/config client etc. vs openssh which comes preinstalled with most distributions).
One thing that’s a pro of mqtt is the added abstraction in case you ever want to replace the pi with another system. You don’t have to touch your ha setup then just the system that controls the garage door.
You’re right, the added “security” is pointless in his case, but still is a pro of using MQTT.
Regarding speed, it most definitely is faster. I’ve been using the SSH method for about a year before discovering MQTT Protocol, and I used to wait for 1-2 seconds before a command was executed (although the client was Raspberry Pi “1”).
Now, when I switched to MQTT, it’s so fast it almost seems like all the systems are connected with wires. The difference is huge, even if you were using RPi3 for SSH (tested).
Install HA on garage pi and just publish to MQTT topic.
This allows you to use GPIO component or other component to easily input output
HA has eventstream component that will publish all events to MQTT.
No need to make script or create automation
You can subscribe to topic on main pi and display sensors or send command to garage pi.
You only require a single mosquito server. You can run this on main Pi.
I run in seperate server because if restarting both pi simultaneously they may fail to connect and create issues for you
So i’ve got my remote Raspi sucessfully receiving publish messages from my HA server. Can you shed any light on how to actually write the changes to my value file on the gpio on my remote Raspi? For example using MQTT on my HA I want to change /sys/class/gpio/gpio17/value from “0” to “1”?
Alrighty, I don’t have much time but I’ve modified some of my scripts to able to work in your case.
The code below should work, if you insert the correct information:
Note that you will need to install WiringPi to your Raspberry Pi that you’re trying to control. You’ll also need Python3, and probably Paho.mqtt
Change the “gpio write [pin_number] [0/1]” to what you have. For example “gpio write 17 1”. The pin number is based on WiringPi’s GPIO numbering system, not the BCM one.
Fill out your topics in the code, the username and password and the mqtt server IP address and you should be good to go.
Hey ATROX thanks for the quick response! Based on your willingness to share your python code, i feel like i’ve made some serious progress. I’m getting the MQTT messages to my remote pi just fine but for some reason the “gpio write” command doesn’t seem to be working in the script. If I run the command from the actual pi “gpio write 0 0” it sucessfully changes my GPIO 17 to value 0 as expected. Can you see anything in my code that would be preventing me from making a sucessful GPIO WRITE?
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import os
mqttc = mqtt.Client()
def on_connect(mosq, userdata, flags, rc):
print("Connected with result code "+str(rc))
mqttc.subscribe(“home/outdoor/heattape”)
After banging my head and trying different things, i was finally able to get MQTT from HA working with this code on my remote RASPI for anyone interested.
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("home/outdoor/heattape")
The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
s = str(msg.payload, encoding=“ascii”)
print("retrieved message: " + s)
if s == “on”:
GPIO.output(LedPin, GPIO.LOW)
elif s == “off”:
GPIO.output(LedPin, GPIO.HIGH)
Initialize GPIO
LedPin = 11 # pin GPIO 17, change if you connect to other pin!
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LedPin, GPIO.OUT)
GPIO.output(LedPin, GPIO.HIGH) # turn off led