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.
Intel NUC with Ubuntu Server VM (Proxmox),mosquitto(docker),RFXtrx433E,zwavejsUI (docker),Zigbee2mqtt(docker),SMA Hub (docker),Harmony Hub plugin, Kodi plugin,Homebridge(docker)+Google Home,APC UPS,SMA Modbus,Mitsubishi MQTT, Broadlink,Dombus