Page 1 of 1
GPIO with docker
Posted: Tuesday 15 April 2025 16:21
by solarboy
I have been trying to follow the GPIO guide on the wiki, however I tried installing "generic sysfs GPIO" but no devices were created. I tried using the command
echo 11 > /sys/class/gpio/export
but got this error
-bash: echo: write error: Invalid argument
At this point I tried the second method however it appears wiringpi is no longer available.
Unable to locate package wiringPi
Is there any way to get this working ?
Re: GPIO with docker
Posted: Tuesday 15 April 2025 16:42
by waltervl
A quick search on the forum gave me this:
viewtopic.php?p=311392#p311392
Re: GPIO with docker
Posted: Tuesday 15 April 2025 18:44
by solarboy
Thanks walter, I managed to get something working with a python gpio2mqttAD script, still a work in progress but functional.
Code: Select all
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import time
import json
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Define relay GPIO pins (BCM numbering)
RELAY_PINS = [17, 27, 22, 23] # Pin 23 = GPIO23 (Physical 16)
for pin in RELAY_PINS:
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.HIGH) # Inverted logic: HIGH = OFF (for active low relays)
# MQTT settings
MQTT_BROKER = "localhost" # Address of your MQTT broker (e.g., localhost or IP)
MQTT_PORT = 1883
MQTT_TOPIC_PREFIX = "domoticzSolar"
MQTT_DISCOVERY_PREFIX = "homeassistant/switch" # Home Assistant discovery style
# MQTT client setup
mqtt_client = mqtt.Client()
# Function to generate a unique ID based on GPIO pin
def get_unique_id(pin):
return f"gpio-relay-board-{pin}"
def on_connect(client, userdata, flags, rc):
print(f"Connected to MQTT broker with result code {rc}")
# Send discovery message for each relay (only once)
for i, pin in enumerate(RELAY_PINS, start=1):
relay_name = f"Relay {i}"
relay_id = f"relay{i}"
unique_id = get_unique_id(pin) # Static unique ID based on GPIO pin
# Prepare the MQTT discovery payload
discovery_payload = {
"name": relay_name,
"command_topic": f"{MQTT_TOPIC_PREFIX}/{relay_id}/set",
"state_topic": f"{MQTT_TOPIC_PREFIX}/{relay_id}/state",
"payload_on": "ON",
"payload_off": "OFF",
"state_on": "ON",
"state_off": "OFF",
"retain": True, # Ensure the configuration persists after restart
"unique_id": unique_id,
"device": {
"identifiers": [unique_id], # Device identifier as unique_id
"name": "GPIO Relay Board",
"model": "Pi GPIO",
"manufacturer": "YourName"
},
"device_class": "switch"
}
# Send the discovery message to the broker only once
discovery_topic = f"{MQTT_DISCOVERY_PREFIX}/gpio-relay-board-{pin}/config"
mqtt_client.publish(discovery_topic, json.dumps(discovery_payload), retain=True)
print(f"Published MQTT discovery message for {relay_name} with unique_id {unique_id}")
def on_message(client, userdata, msg):
topic_parts = msg.topic.split("/")
if len(topic_parts) < 3:
return
relay_name = topic_parts[1]
if relay_name.startswith("relay"):
try:
relay_num = int(relay_name[5:])
if 1 <= relay_num <= len(RELAY_PINS):
if msg.payload.decode() == "ON":
GPIO.output(RELAY_PINS[relay_num - 1], GPIO.LOW) # Inverted logic
mqtt_client.publish(f"{MQTT_TOPIC_PREFIX}/{relay_name}/state", "ON", retain=True)
elif msg.payload.decode() == "OFF":
GPIO.output(RELAY_PINS[relay_num - 1], GPIO.HIGH) # Inverted logic
mqtt_client.publish(f"{MQTT_TOPIC_PREFIX}/{relay_name}/state", "OFF", retain=True)
except ValueError:
print(f"Invalid relay number: {relay_name}")
def run_gpio_mqtt():
mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
mqtt_client.loop_start()
# Subscribe to relay control topics
for i in range(1, len(RELAY_PINS) + 1):
mqtt_client.subscribe(f"{MQTT_TOPIC_PREFIX}/relay{i}/set")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Shutting down...")
GPIO.cleanup()
mqtt_client.disconnect()
if __name__ == "__main__":
run_gpio_mqtt()
I have to disable device creation as the domoticz creates new devices on each start, but it does work. Need to work on the auto discovery stuff.
Re: GPIO with docker
Posted: Tuesday 15 April 2025 19:51
by solarboy
Is there any reason new devices created on the slave aren't visible on the main Domoticz instance ? I have a previously set up test virtual switch that is working so the basic connection is fine but new devices aren't appearing. I have "allow new devices" enabled and I have tried starting and stopping the "Domoticz Remote Server" hardware.
Re: GPIO with docker
Posted: Tuesday 15 April 2025 20:58
by waltervl
When using remote device sharing you have to open up the sharing port (default 6144) in the docker image configuration.
Re: GPIO with docker
Posted: Tuesday 15 April 2025 23:02
by solarboy
Yeah, did that and it was working before and created a test virtual device which still works.
Code: Select all
services:
domoticz:
image: domoticz/domoticz:stable
container_name: domoticz
restart: unless-stopped
# Pass devices to container
# devices:
# - "/dev/serial/by-id/usb-0658_0200-if00-port0:/dev/ttyACM0"
ports:
- "8080:8080"
- "6144:6144"
volumes:
- ./config:/opt/domoticz/userdata
#- ./config/www/templates:/opt/domoticz/www/templates
environment:
- TZ=Europe/Lisbon
#- LOG_PATH=/opt/domoticz/userdata/domoticz.log
However new devices arent being created, neither another identical virtual switch or some MQTT Discovery Devices I have on the slave.
Re: GPIO with docker
Posted: Wednesday 16 April 2025 10:36
by waltervl
Nothing in the logs about remote sharing?
From the wiki
Data is pushed to the Main from the Remote triggered by device changes. So if a device changes it will be synchronised.
It would be wise to check the "Setup | Log" to double check there are no errors.
Re: GPIO with docker
Posted: Wednesday 16 April 2025 11:27
by solarboy
Nothing in the logs but while I was asleep the solution came to me ; the newer devices needed to be added in "Set Devices" as they didn't exist when I created the remote user.
Thanks for your help Walter.
Re: GPIO with docker
Posted: Wednesday 16 April 2025 21:44
by akamming
You are describing a very difficult solution.
Just google on “docker gpio Access raspberry pi” and you get several articles describing solutions.
The most easy one is running the docker container in privileged mode..