Pi-Plates and HA

I have been using Node-Red on a stand alone RPI and have a Pi-PLate (https://pi-plates.com/daqc2r1/) coming for it. It will be a stand alone unit but feeds data back to HA via MQTT.

I started to think about putting one of these plates on my HA RPI. My question is can Node-Red see the GPIO pins of the RPI? Also you have to add Pythong libraries etc as in https://pi-plates.com/getting_started/ to make it work. I gather these would have to be in the Node-Red container?

What are your thoughts? I have a working and very stable HA and Node-Red working now. Debating if I should try it.

NodeRed supports rPI GPIOs right out of the box. If you don’t have it installed: https://flows.nodered.org/node/node-red-node-pi-gpio

image

I’ve never used a piPlate, but as long as it uses the standard GPIO naming/use, it should be fine.

Thanks for that. No the PI plate using the python library and has the ability to read analog values. There is a node-red node set already but you still need the python stuff. I might load up one of my spare rpi’s with a HA and give it a go.

1 Like

I used this tutorial to create a local “add on” for a pi-plates relay board (RELAYplate – Pi-Plates).

My solution uses a tiny python web server running in an “add on” container. The piplates python library is used to drive the relays.

To control the relays from Home Assistant I use rest_command to send messages to the web server. e.g. In configuration.yaml I have something like this to implement Window Covers controlled by the relays.

rest_command:
  open_sheer:
    url: "http://localhost:8492/press/0/1"
  close_sheer:
    url: "http://localhost:8492/press/0/2"
  open_east_curtian:
    url: "http://localhost:8492/press/0/3"
  close_east_curtian:
    url: "http://localhost:8492/press/0/4"
  open_north_curtian:
    url: "http://localhost:8492/press/0/5"
  close_north_curtian:
    url: "http://localhost:8492/press/0/6"

cover:
  - platform: template
    covers:
      sheer:
        device_class: curtain
        unique_id: bedroom.sheer
        friendly_name: "Sheer"
        open_cover:
          service: rest_command.open_sheer
        close_cover:
          service: rest_command.close_sheer
      east_curtian:
        device_class: curtain
        unique_id: bedroom.east_curtian
        friendly_name: "West Curtian"
        open_cover:
          service: rest_command.open_east_curtian
        close_cover:
          service: rest_command.close_east_curtian
      north_curtian:
        device_class: curtain
        unique_id: bedroom.north_curtian
        friendly_name: "North Curtian"
        open_cover:
          service: rest_command.open_north_curtian
        close_cover:
          service: rest_command.close_north_curtian

I ended up with the following files under addons/pi_plates…

Dockerfile:

This installs the python pi-plates library and its dependencies.

ARG BUILD_FROM
FROM $BUILD_FROM

ENV LANG C.UTF-8

RUN apk add --no-cache --virtual .build-deps \
    python3-dev \
    gcc \
    make \
    linux-headers \
    musl \
    musl-dev \
    libc-dev \
    py3-pip \
 && apk add --no-cache \
    py3-six \
    python3 \
 && pip install wheel \
 && CFLAGS="-fcommon" pip install RPi.GPIO \
 && CFLAGS="-fcommon" pip install spidev \
 && pip install pi-plates \
 && apk del .build-deps

COPY relay_server.py http_server.py /
COPY run.sh /
RUN chmod a+x /run.sh

CMD [ "/run.sh" ]

config.json

This tells Home Assistant to open TCP port 8492 and enable access to the SPI and GPIO hardware devices.

{
  "name": "Pi Plates",
  "version": "10",
  "slug": "pi_plates",
  "description": "Interace with Relay Boards from pi-plates.com",
  "arch": ["aarch64"],
  "startup": "application",
  "boot": "auto",
  "options": {},
  "schema": {},
  "ports": {
    "8492/tcp": 8492
  },
  "devices": ["/dev/spidev0.1", "/dev/gpiomem"]
}

run.sh:

This starts two python servers, one to control the relay board and one to communicate with Home Assistant via HTTP.

#!/usr/bin/with-contenv bashio

/relay_server.py &
/http_server.py

relay_server.py:

This server waits for commands to be written to /var/run/relay_server then calls the piplates relayOFF() and relayON() functions

#!/usr/bin/python3

import piplates.RELAYplate as RELAY
import sys
import os
import errno
import time

FIFO = "/var/run/relay_server"

try:
    os.mkfifo(FIFO)
except OSError as oe:
    if oe.errno != errno.EEXIST:
        raise

os.chmod(FIFO, 0o0666)

RELAY.relayALL(0, 0)
RELAY.relayALL(1, 0)

print("FIFO Server on /var/run/relay_server")
while True:
    with open(FIFO) as fifo:
        while True:
            data = fifo.readline()
            print(data)
            if len(data) == 0:
                break
            f, a, b = data.rstrip().split(",")
            a = int(a)
            b = int(b)
            if f == "press":
                RELAY.relayOFF(a, b)
                time.sleep(0.1)
                RELAY.relayON(a, b)
                time.sleep(0.2)
                RELAY.relayOFF(a, b)
            else:
                getattr(RELAY, f)(a, b)

http_server.py:

This server listens for HTTP requests and writes commands to /var/run/relay_server.

#!/usr/bin/python3

from http.server import BaseHTTPRequestHandler, HTTPServer

class RelayServer(BaseHTTPRequestHandler):
    def do_GET(self):
        x, a, b, c = self.path.split("/")
        with open('/var/run/relay_server', 'w') as f:
            f.write(a + ',' + b + ',' + c + '\n')
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write("ok".encode("utf8"))

print("HTTP Server listening on port 8492")
HTTPServer(("0.0.0.0", 8492), RelayServer).serve_forever()

The following two scripts were useful for building and running the docker image outside Home Assistant for debugging.

build.sh:

#!/bin/bash

docker build \
    --build-arg BUILD_FROM="homeassistant/aarch64-base:latest" \
    -t local/pi_plates .

debug.sh:

#!/bin/bash

docker run --rm \
    -p 8492:8492 \
    --device /dev/spidev0.1:/dev/spidev0.1 \
    --device /dev/gpiomem:/dev/gpiomem \
    -it local/pi_plates \
    /bin/bash