Strategy for Remote RPi integration?

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:

  1. 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

  2. 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;

  3. 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?

Any ideas or tips would be great.

1 Like

You could also use SSH to send that CLI command to the garage pi :slight_smile:

~Cheers

1 Like

For fun I have 4 RPis running HA. One of which is in my detached garage. I use CMD line sensors and switches and the Restful API.

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 think I’ll go with writing a script per option 1, based on some other code I have found.

Thanks for your post.

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.

~Cheers

2 Likes

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.

~Cheers

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).

1 Like

Thanks I will probably go the mqtt route. Thanks for your offer of help @ATROX. I have a few projects on at the moment, keep getting distracted.

1 Like

I did this previously.

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

1 Like

Thank you, excellent information.

Can anyone suggest best strategies for retrieving an image of a remote pi?
Ideas I have are:

  1. Setup Apache on the remote pi and save images in a folder that can be accessed by HASS
  2. A command line approach to retrieve the image(?)
  3. MQTT camera (??) https://home-assistant.io/components/camera.mqtt/

Cheers

I use HA built in webserver to transfer TTS wave files to different HA instances. http://localhost:8123/local

1 Like

If you just fetching an existing file, using scp in a command line is going to be the easiest approach.

1 Like

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:

#!/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("#")

def on_message_gpio1(mosq, userdata, msg):
	if msg.payload.decode() == "on":
		os.system("gpio write [pin_number] [0/1]")
	elif msg.payload.decode() == "off":
		os.system("gpio write [pin_number] [0/1]")
	else:
		print("Command not recognized")

def on_message_gpio2(mosq, userdata, msg):
	if msg.payload.decode() == "ON":
		os.system("gpio write [pin_number] [0/1]")
	elif msg.payload.decode() == "OFF":
		os.system("gpio write [pin_number] [0/1]")
	else:
		print("Command not recognized")

def on_message(mosq, userdata, msg):
    print("Topic: "+msg.topic+" | QOS: "+str(msg.qos)+" | Payload: "+str(msg.payload.decode()))

mqttc.message_callback_add('home/raspberrypi/gpio1', on_message_gpio1)
mqttc.message_callback_add('home/raspberrypi/gpio2', on_message_gpio2)

mqttc.on_message = on_message
mqttc.on_connect = on_connect

mqttc.username_pw_set("mqtt_username","mqtt_password")
mqttc.connect("mqtt_server_ip",1883,60)

mqttc.loop_forever()

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.

Have fun!

1 Like

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”)

def on_message_gpio1(mosq, userdata, msg):
if msg.payload.decode() == “on”:
os.system(“gpio write 0 0”)
elif msg.payload.decode() == “off”:
os.system(“gpio write 0 1”)
else:
print(“Command not recognized”)

def on_message_gpio2(mosq, userdata, msg):
if msg.payload.decode() == “ON”:
os.system(“gpio write 0 0”)
elif msg.payload.decode() == “OFF”:
os.system(“gpio write 0 1”)
else:
print(“Command not recognized”)

def on_message(mosq, userdata, msg):
print("Topic: “+msg.topic+” | QOS: “+str(msg.qos)+” | Payload: "+str(msg.payload.decode()))

mqttc.message_callback_add(‘home/raspberrypi/gpio1’, on_message_gpio1)
mqttc.message_callback_add(‘home/raspberrypi/gpio2’, on_message_gpio2)

mqttc.on_message = on_message
mqttc.on_connect = on_connect

mqttc.username_pw_set(“xxxx”,”xxxx”)
mqttc.connect(“x.x.x.x”,1883,60)

mqttc.loop_forever()

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

Initialize MQTT

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

host = “x.x.x.x”
print("Connecting to " + host)
client.connect(host, port=1883, keepalive=60)

client.loop_forever()

1 Like