Bir Raspberry Pi röle MQTT kontrolcüsü, modeminizde port açmadan lambaları, pompaları, fanları veya kontaktörleri bir telefondan, bir panelden ya da bir otomasyon betiğinden anahtarlamanızı sağlar. Bu eğitimde çok kanallı bir röle kartını bağlayacak, MQTT topic'lerini röle kanallarına eşleyen bir Python servisi yazacak ve retained mesajlar kullanarak her rölenin yeniden başlatmadan sonra doğru durumda geri gelmesini sağlayacaksınız.
Neye İhtiyacınız Var
| Parça | Notlar |
|---|---|
| Raspberry Pi (3B+, 4, 5 veya Zero 2 W) | Raspberry Pi OS Bookworm, ağa bağlı |
| 2, 4 veya 8 kanallı röle kartı | Optokuplörlü 5 V bobin, 3,3 V uyumlu girişler |
| Dişi-dişi jumper kablolar | Her kanal için bir tane, artı güç ve toprak |
gpiozero ve paho-mqtt 2.x içeren Python 3 |
Bir sanal ortama kurulu |
| Bir MQTT broker | Test için broker.connectmq.com, üretim için özel kimlik bilgileri |
Her şeyden önce bir güvenlik notu: röle kartları onlara ne bağlarsanız onu anahtarlar. Şebeke gerilimini kontrol ediyorsanız, kablolama yetkin biri tarafından uygun bir muhafaza içinde ve yüke uygun değerde bir röleyle yapılmalıdır. Öğrenmek için bir 12 V LED şeridi veya küçük bir DC fanı anahtarlayın.
Röle Kartının Kablolanması
Çoğu hobi röle modülünde VCC, GND ve IN1 ile IN4 arası etiketli bir başlık bulunur. Bunları şöyle bağlayın:
| Röle pini | Raspberry Pi pini |
|---|---|
| VCC | 5 V (fiziksel pin 2) |
| GND | GND (fiziksel pin 6) |
| IN1 | GPIO17 (fiziksel pin 11) |
| IN2 | GPIO27 (fiziksel pin 13) |
| IN3 | GPIO22 (fiziksel pin 15) |
| IN4 | GPIO23 (fiziksel pin 16) |
Bu kartların çoğu aktif-düşüktür (active-low): bir girişi toprağa çekmek bobini enerjilendirir. Aşağıdaki kodun active_high=False kullanmasının nedeni budur. Kartınız kapalı beklediğinizde açılıyorsa bu bayrağı tersine çevirin.
JD-VCC jumper'ı olan kartlar, tam yalıtım için bobinleri ayrı bir 5 V kaynaktan beslemenize olanak tanır. Jumper'ı çıkarın, JD-VCC'yi harici kaynaktan besleyin, VCC'yi kartın dokümantasyonunun söylediği gibi Pi'nin 3,3 V veya 5 V hattında tutun ve toprağı yalnızca kılavuz gerektiriyorsa ortak yapın.
Güvenilirlik açısından bir donanım ayrıntısı daha önemlidir. Betiğiniz başlamadan önce GPIO pinleri varsayılan pull dirençlerine sahip girişlerdir; bu yüzden aktif-düşük bir kart açılışta kısa bir süre anahtarlanabilir. Bir güç döngüsü sırasında rölelerinizin ne yaptığını test edin. Böyle bir aksaklık zararlı olacaksa, varsayılan pull değeri "kapalı" seviyesine uyan pinleri seçin veya harici pull dirençleri ekleyin.
Topic Sözleşmesini Tasarlamak
Temiz bir topic düzeni, röle kontrolcüsünü Node-RED, Home Assistant veya bir betik olsun, her istemciden kolayca kullanılabilir kılar:
| Topic | Yön | Payload | Retained |
|---|---|---|---|
connectmq/demo/a91c4e/relays/<n>/set |
Kontrolcüden Pi'ye | ON, OFF (veya retained olmayan TOGGLE) |
ON/OFF için evet |
connectmq/demo/a91c4e/relays/<n>/state |
Pi'den herkese | ON veya OFF |
Evet |
connectmq/demo/a91c4e/relays/status |
Pi (ve last will) | online veya offline |
Evet |
a91c4e yerine kendi rastgele dizenizi yazın. Paylaşımlı bir genel broker'da her topic herkes tarafından okunabilir; bu yüzden benzersiz bir önek test trafiğinizi ayrı tutar. Ayrı set ve state topic'lerinin neden iyi bir uygulama olduğunu hatırlamak isterseniz, MQTT üzerinden Raspberry Pi GPIO rehberi komut ve durum desenini ayrıntılı olarak açıklar.
Retained Durumlar Yeniden Başlatmayı Nasıl Atlatır
Retained mesajlar, elektrik kesintisinden sonra düzgün davranan bir röle kontrolcüsünün anahtarıdır. Broker her topic'teki son retained mesajı saklar ve onu her yeni aboneye hemen teslim eder. Bu size iki faydalı davranış kazandırır:
- Paneliniz
relays/1/settopic'ine retain bayrağıylaONyayınladığında broker onu saklar. Pi yeniden başlayıprelays/+/settopic'ine abone olduğunda her kanal için istenen durumu alır ve geri yükler. - Pi
relays/1/statetopic'ini retain ile yayınladığında, sonradan açılan her panel bir sonraki değişikliği beklemek yerine gerçek durumu hemen görür.
Bir tuzak var: TOGGLE komutunu asla retained yapmayın. Retained bir toggle her yeniden bağlantıda tekrar oynatılır ve röleyi her seferinde tersine çevirir. Aşağıdaki betik bu nedenle retained toggle'ları yok sayar. Mekanizmaya daha derinlemesine bakmak için MQTT retained mesajlar açıklamamızı okuyun.
Python ile Raspberry Pi Röle MQTT Betiği
Bir proje klasörü ve sanal ortam oluşturun:
sudo apt update
sudo apt install -y python3-venv python3-lgpio
mkdir -p ~/relay-mqtt && cd ~/relay-mqtt
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" gpiozero
--system-site-packages bayrağı, sanal ortamın gpiozero'nun Raspberry Pi 5'te ihtiyaç duyduğu ve eski modellerde de çalışan lgpio arka ucunu kullanmasını sağlar. Aşağıdakini relay_mqtt.py olarak kaydedin:
#!/usr/bin/env python3
"""Control a multi-channel relay board from MQTT topics."""
import os
import signal
import sys
import uuid
import paho.mqtt.client as mqtt
from gpiozero import OutputDevice
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"rpi-relay-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/a91c4e/relays")
RELAY_PINS = {1: 17, 2: 27, 3: 22, 4: 23}
ACTIVE_HIGH = False # most opto-isolated hobby boards are active-low
relays = {
n: OutputDevice(pin, active_high=ACTIVE_HIGH, initial_value=False)
for n, pin in RELAY_PINS.items()
}
def publish_state(client, n):
state = "ON" if relays[n].value else "OFF"
client.publish(f"{PREFIX}/{n}/state", state, qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print(f"Connection refused: {reason_code}")
return
print(f"Connected as {CLIENT_ID}")
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
client.subscribe(f"{PREFIX}/+/set", qos=1)
for n in relays:
publish_state(client, n)
def on_message(client, userdata, msg):
try:
n = int(msg.topic.split("/")[-2])
except ValueError:
return
if n not in relays:
print(f"Ignoring unknown channel {n}")
return
command = msg.payload.decode(errors="ignore").strip().upper()
if command in ("ON", "1", "TRUE"):
relays[n].on()
elif command in ("OFF", "0", "FALSE"):
relays[n].off()
elif command == "TOGGLE":
if msg.retain:
print(f"Ignoring retained TOGGLE on channel {n}")
return
relays[n].toggle()
else:
print(f"Unknown command {command!r} for channel {n}")
return
print(f"Relay {n} -> {'ON' if relays[n].value else 'OFF'}")
publish_state(client, n)
def on_disconnect(client, userdata, flags, reason_code, properties):
print(f"Disconnected: {reason_code}; paho will reconnect")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
def shutdown(signum, frame):
for relay in relays.values():
relay.off()
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.disconnect()
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
client.connect(BROKER, PORT, keepalive=30)
client.loop_forever(retry_first_connection=True)
python relay_mqtt.py ile çalıştırın. Betik temiz bir kapanışta her röleyi kapatır; servis durduğunda yüklerin çalışmaya devam etmesini tercih ederseniz shutdown içindeki döngüyü kaldırın.
Dizüstü Bilgisayarınızdan Test
Mosquitto istemcilerinin kurulu olduğu herhangi bir makinede ikinci bir terminal açın ve durum topic'lerini izleyin:
mosquitto_sub -h broker.connectmq.com -p 1883 -i laptop-a91c4e \
-t 'connectmq/demo/a91c4e/relays/#' -v
Ardından kanal 1'i retained bir komutla açın ve kanal 2'yi tersine çevirin:
mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-a91c4e \
-t 'connectmq/demo/a91c4e/relays/1/set' -m 'ON' -q 1 -r
mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-a91c4e \
-t 'connectmq/demo/a91c4e/relays/2/set' -m 'TOGGLE' -q 1
Tıklama seslerini duymalı ve relays/1/state ON satırının belirdiğini görmelisiniz. Şimdi Pi'yi yeniden başlatın. Betik yeniden bağlandığında kanal 1 ON durumuna döner, çünkü retained komut hâlâ broker'dadır; kanal 2 ise OFF olarak başlar, çünkü toggle'lar asla retained yapılmaz. Retained bir komutu temizlemek için boş bir retained mesaj yayınlayın: mosquitto_pub ... -t '.../relays/1/set' -r -n.
Servis Olarak Çalıştırın
Bir röle kontrolcüsü açılışta başlamalı ve bir çökmeden sonra yeniden başlamalıdır. /etc/systemd/system/relay-mqtt.service dosyasını oluşturun:
[Unit]
Description=Relay MQTT controller
After=network-online.target
Wants=network-online.target
[Service]
User=pi
WorkingDirectory=/home/pi/relay-mqtt
Environment=MQTT_HOST=broker.connectmq.com
Environment=MQTT_PORT=8883
Environment=MQTT_USERNAME=YOUR_USERNAME
Environment=MQTT_PASSWORD=YOUR_PASSWORD
Environment=MQTT_CLIENT_ID=YOUR_CLIENT_ID
Environment=MQTT_PREFIX=home/garage/relays
ExecStart=/home/pi/relay-mqtt/.venv/bin/python relay_mqtt.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now relay-mqtt ile etkinleştirin. Servis dosyaları, günlükleme ve ortam dosyalarının tam açıklaması Python MQTT betiğini açılışta çalıştırma yazısındadır. Kullanıcı adınız pi değilse onu düzenleyin.
Test Broker'ından Üretime Geçiş
Genel test broker'ı ilk bir saat için mükemmeldir, ancak topic'inizi tahmin eden herkes rölelerinizi anahtarlayabilir. Gerçek ekipmana bağlı her şey için kimlik doğrulamalı ve TLS'li özel bir broker kullanın. ConnectMQ gibi tamamen yönetilen bir MQTT hizmeti ile portalda bir broker oluşturur, oluşturulan kullanıcı adını, parolayı ve client ID'yi yukarıdaki servis dosyasına kopyalar ve portu 8883 olarak ayarlarsınız. Client ID verilen kimlik bilgilerine bağlıdır; böylece başka bir cihaz kontrolcünüzü taklit edemez. Betik hiç değişmez.
ConnectMQ portalı devreye alma sırasında da yardımcı olur: tarayıcı içi MQTT istemcisi her kanala ON ve OFF yayınlayabilir; canlı topic gezgini de retained durum ve status değerlerini bir bakışta gösterir. Aynı iş için Pi'ye donanım alternatifi istiyorsanız, onu MQTT üzerinden ESP32 röle projesiyle karşılaştırın.
Sorun Giderme
- Röleler başlangıçta açılıyor ve açma komutu verildiğinde kapanıyor: kartınız aktif-yüksektir;
ACTIVE_HIGH = Trueolarak ayarlayın. - Karttaki LED'ler yanıyor ama röle tıklamıyor: bobin beslemesi çok zayıf;
JD-VCC'yi ayrı bir 5 V kaynaktan besleyin. Connection refused: Not authorized: kullanıcı adını, parolayı ve client ID'yi kontrol edin veya anonim genel broker'ı kullanırken bunları kaldırın.- Röle yeniden başlatmadan sonra eski bir durumu geri yüklüyor: broker'da eskimiş bir retained komut var; boş bir retained yayınla temizleyin.
GPIO busyhataları: başka bir betik veya servis aynı pinleri kullanıyor; bunu başlatmadan önce onu durdurun.
ConnectMQ ile Başlayın
Gerçek ekipmanı kontrol etmeye hazır mısınız? Kredi kartı gerekmeden ücretsiz Serverless plana kaydolun, bir broker oluşturun ve röle servisinizi TLS üzerinden ona yönlendirin. MQTT 3.1.1 ve 5.0, retained mesajlar ve her anahtarlama olayını izleyebileceğiniz bir portal elde edersiniz. Kavramlara yeni misiniz? Raspberry Pi MQTT eğitimi temelleri anlatır; bulut MQTT broker genel bakışımız da barındırmanın Pi üzerinde Mosquitto çalıştırmaktan ne zaman daha iyi olduğunu açıklar.
Sık Sorulan Sorular
Rölem neden Raspberry Pi yeniden başladıktan sonra durum değiştiriyor?
Broker'dan retained bir komutu tekrar oynatıyordur; bu genellikle istediğiniz şeydir. Durum yanlışsa doğru değeri retain ile yayınlayın veya topic'i boş bir retained mesajla temizleyin.
Röle komutları için QoS 1 kullanabilir miyim?
Evet, kullanmalısınız da. QoS 1 komutun en az bir kez ulaşmasını garanti eder; ON ve OFF idempotent olduğundan yinelenen bir teslim zarar vermez.
Tek bir Raspberry Pi kaç röleyi kontrol edebilir?
Boş GPIO pininiz kadar; bir hobi kartında genellikle sekize kadar. Daha fazla kanal için MCP23017 gibi bir I2C GPIO genişletici kullanın ve aynı topic düzenini koruyun.
Şebeke gerilimli cihazları bu şekilde kontrol etmek güvenli mi?
Yalnızca yüke uygun değerde röleler, uygun bir muhafaza ve yerel elektrik yönetmeliğine göre yapılmış kablolamayla. Gerçek ekipmanı anahtarlayan her şey için her zaman kimliği doğrulanmış TLS bağlantıları kullanın.



