YC

Building an offline-first IoT edge controller with Raspberry Pi and MQTT

Managing physical appliance relays, systemd daemons, and MQTT state synchronization.

System: IoT Smart Home & MQTT Controller
Category: Hardware & Edge · Linux & MQTT
Reading Time: 6 min read
Worked through: Raspberry Pi · Mosquitto MQTT · Python Daemon · Linux systemd · Optocoupled Relays
01. WHY I BUILT IT

The Trigger & Underlying Problem

The Trigger: Commercial smart home systems are locked into proprietary cloud subscriptions that stop working whenever internet access drops.

The Core Problem: I wanted local, low-latency control of physical high-voltage appliances that functions reliably on the local network regardless of cloud availability.

Why Standard Solutions Were Insufficient: Hands-on edge computing project to explore Linux daemon management, GPIO electrical isolation, and lightweight pub/sub protocols.

02. PRACTICAL IMPACT

What It Solves in Practice

PRACTICAL PROBLEM

Switches physical appliances securely with sub-50ms latency over a local Mosquitto MQTT broker, syncing true physical state to a web dashboard.

BENEFICIARIES

Provides an open, private home automation hub with zero monthly cloud dependencies.

BEFORE THIS SYSTEM

Proprietary smart switches with 2-second cloud round-trip latencies.

03. IMPLEMENTATION

Architecture & Key Engineering Decisions

A Raspberry Pi wired to multi-channel optocoupled relay modules. A Python daemon running under `systemd` subscribes to MQTT topics and drives GPIO pins. A local Mosquitto broker coordinates messages.

Key Decisions:
  • Used optocoupled relay modules to electrically isolate the 3.3V Raspberry Pi logic from 220V appliance loads.
  • Managed the Python daemon via a Linux `systemd` unit with `Restart=always` to ensure automatic recovery after power outages.
  • Designed hierarchical topic structure (`home/room/device/command` and `.../state`) with MQTT Last Will and Testament (LWT) for offline detection.
04. CHALLENGES & SOLUTIONS

What Failed in Practice & How It Was Addressed

WHAT WENT WRONG
  • Floating GPIO pin states on boot caused relays to cycle briefly during Raspberry Pi startup.
  • When network connections dropped, UI switches reflected toggled states even though the physical relay had never switched.
HOW I SOLVED IT
  • Wired hardware pull-down resistors to keep GPIO pins cleanly low during boot before software initialization.
  • Enforced strict two-phase state synchronization: the dashboard UI only updates when it receives a message on the `/state` topic confirmed by the GPIO daemon, never on button click alone.
05. REFLECTION & LESSONS

Takeaways & Future Iterations

What I Learned:
  • Software must reflect physical reality, not optimistic user assumptions. True state feedback is mandatory in edge and hardware systems.
  • MQTT's pub/sub model with Last Will and Testament is unmatched for low-bandwidth, unreliable networks.
WHAT I WOULD CHANGE NOW:

I would replace the single Raspberry Pi controller with low-cost ESP32 microcontrollers communicating over ESP-NOW or MQTT, keeping the Pi purely as the central broker and dashboard host.