M-Bus Gateway
← Tilbage til blog
· Raspberry Pi· IoT· gateway· hardware· SIM7080G· systemd· watchdog· edge computing

Raspberry Pi som IoT gateway — hvorfor Pi 4 og hvad der begrænser valget

Teknisk begrundelse for Raspberry Pi 4 som wM-Bus gateway: compute-krav, strøm, SD-kort holdbarhed, watchdog, systemd, SIM7080G HAT og alternativer overvejet.

Af M-Bus Gateway

Raspberry Pi 4 er valgt som gateway-hardware — ikke af vane, men som resultat af en konkret vurdering. Her er begrundelsen og hvad der begrænsede alternativerne.


Kravspecifikation for gateway-hardware

Minimumskrav:
✅ USB 2.0 til wM-Bus dongle (Würth 2605056083001)
✅ UART eller GPIO til SIM7080G modem-HAT
✅ 64-bit OS (Debian-kompatibelt)
✅ Hardware watchdog (/dev/watchdog)
✅ Python 3.11+ runtime
✅ Passiv køling (kælder-installation)
✅ Industrial temperature range (-10°C til 60°C)
✅ UPS/power-recovery (RPi genopstarter automatisk ved strømsvigt)

Ønskede:
⭐ GPIO-pins til LED-status og tryk-knap
⭐ PoE-mulighed (fremtid)
⭐ >2GB RAM til fremtidig edge-ML

Alternativer overvejet

HardwarePrisUSBGPIOWatchdogProblem
Raspberry Pi 4 (1GB)650 kr.Valgt
Raspberry Pi Zero 2W180 kr.❌ USB-A mangler (micro USB)Kræver USB-hub
Orange Pi Zero 3280 kr.⚠️ BegrænsetDårlig driver-support
NanoPi R4S780 kr.❌ Ingen GPIOIngen GPIO til HAT
Industrial PC (x86)3.000+ kr.Unødvendig overkill, pris
Arduino/ESP3250–200 kr.⚠️ Begr.Ikke Linux — ingen wmbusmeters

Konklusion: Pi 4 er det billigste hardware der opfylder ALLE krav.


Raspberry Pi 4 konfiguration

# Vores specifikke konfiguration:
# Model: Raspberry Pi 4 Model B 1GB RAM
# OS: Raspberry Pi OS Lite 64-bit (Debian Trixie-baseret)
# SD: Samsung Pro Endurance 32GB (designet til kontinuerlig skrivning)

# /boot/firmware/config.txt — optimeret til gateway:
# Deaktiver ubrugte interfaces (spare strøm + reducere angrebsflade):
dtoverlay=disable-bt         # Bluetooth deaktiveret (bruger ikke BT)
dtoverlay=disable-wifi       # WiFi deaktiveret (bruger 4G/SIM)

# GPU-hukommelse minimeret (headless):
gpu_mem=16

# UART til SIM7080G HAT:
enable_uart=1
dtparam=uart0=on

# Hardware watchdog:
dtparam=watchdog=on

Hardware Watchdog

BCM2835 hardware watchdog reboots Pi uanset kernestatus — to-lags strategi:

# gateway/src/system/watchdog.py
import fcntl
import struct
import threading
import time

WATCHDOG_DEVICE = "/dev/watchdog"
WATCHDOG_TIMEOUT = 15  # Sekunder → reboot hvis ikke opdateret

class HardwareWatchdog:
    def __init__(self):
        self._fd = open(WATCHDOG_DEVICE, "wb", buffering=0)
        self._stop = threading.Event()
        self._thread = threading.Thread(target=self._feed_loop, daemon=True)

    def start(self):
        # Sæt timeout til 15 sekunder:
        fcntl.ioctl(self._fd, 0x40045706, struct.pack("I", WATCHDOG_TIMEOUT))
        self._thread.start()

    def _feed_loop(self):
        """Fod watchdog hvert 10. sekund."""
        while not self._stop.is_set():
            self._fd.write(b'\x01')  # Keep-alive byte
            self._stop.wait(10)

    def stop(self):
        self._fd.write(b'V')  # Magic stop byte
        self._stop.set()
        self._fd.close()

Systemd service-konfiguration

# /etc/systemd/system/mbus-gateway.service
[Unit]
Description=M-Bus Gateway
After=network-online.target mosquitto.service
Wants=network-online.target

[Service]
Type=notify
User=mbus
WorkingDirectory=/opt/mbus/gateway
ExecStart=/opt/mbus/venv/bin/python -m gateway.src.main
Restart=always
RestartSec=10

# Systemd watchdog (lag 2):
WatchdogSec=120          # Systemd genstarter service hvis ingen WATCHDOG=1 inden 120s
NotifyAccess=main

# Resource limits:
MemoryMax=512M
CPUQuota=80%

# Security hardening:
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/opt/mbus/data /var/log/mbus

[Install]
WantedBy=multi-user.target
# Notificér systemd watchdog:
import sdnotify
notifier = sdnotify.SystemdNotifier()

async def main():
    notifier.notify("READY=1")
    while True:
        notifier.notify("WATCHDOG=1")  # Hvert ~60. sekund
        await asyncio.sleep(60)

SD-kort holdbarhed

Det største pain-point med Raspberry Pi er SD-kort-nedbrud ved kontinuerlig skrivning:

Strategi for at maksimere levetid

# 1. RAM-disk til temporære filer:
# /etc/fstab:
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=50m 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=20m 0 0
tmpfs /var/log tmpfs defaults,noatime,nosuid,size=30m 0 0

# 2. SQLite WAL-mode + skrivning kun 1x/dag:
PRAGMA journal_mode=WAL;      # Write-Ahead Logging
PRAGMA synchronous=NORMAL;    # Reducer sync-kald
# Batchskriv: Kun ved daglig MQTT-afsendelse (kl. 06:00 UTC)

# 3. Read-only root filesystem:
# /boot/firmware/cmdline.txt: ... ro ...
# Undtaget: /data (separat partition, r/w)

# 4. Samsung Pro Endurance (vs. standard Class 10):
# Designet til 140.160 timer kontinuerlig skrivning vs. ~10.000 timer

SIM7080G HAT integration

# gateway/src/cellular/manager.py
import serial
import time

class SIM7080GManager:
    def __init__(self, port="/dev/ttyS0", baud=115200):
        self.ser = serial.Serial(port, baud, timeout=5)

    def initialize(self):
        """Boot-sekvens og netværkstilslutning."""
        self._send_at("AT")                          # Verificer respons
        self._send_at("AT+CFUN=1")                   # Full functionality
        self._send_at('AT+CGDCONT=1,"IP","iot.1nce.net"')  # APN
        self._send_at("AT+CNACT=0,1")               # Aktiver PDP context
        time.sleep(5)
        self._send_at("AT+CNACT?")                   # Tjek IP-adresse

    def get_signal_strength(self) -> int:
        """Returner RSSI i dBm."""
        response = self._send_at("AT+CSQ")
        # Response: "+CSQ: 18,0" → RSSI = -113 + 2×18 = -77 dBm
        csq = int(response.split(":")[1].split(",")[0].strip())
        return -113 + 2 * csq if csq < 99 else None

    def _send_at(self, cmd: str) -> str:
        self.ser.write(f"{cmd}\r\n".encode())
        time.sleep(0.5)
        return self.ser.read(self.ser.in_waiting).decode(errors="ignore")

Strømforbrug og UPS

Raspberry Pi 4 strømforbrug:
  Idle: 2,7W
  Under last (MQTT send + wM-Bus scan): 4,2W
  Peak (OTA update download): 6,5W

4G SIM7080G HAT:
  Idle: 0,5W
  Data transfer: 1,5W peak

Samlet gennemsnit: ~4W / 24 timer = ~96 Wh/dag = ~35 kWh/år
Elomkostning: 35 kWh × 3 kr./kWh = 105 kr./år (ubetydelig)

UPS-anbefaling: 12V/7Ah blybatteri + DC-converter
→ Backup-tid: ~8 timer ved strømsvigt
→ Pi genstarter automatisk ved genkomst af strøm

Konklusion

Raspberry Pi 4 er valgt for USB, GPIO, 64-bit Linux, hardware watchdog og pris. Holdbarhed maksimeres via RAM-disk til logfiler, SQLite WAL-mode med batched skrivning og Samsung Pro Endurance SD-kort. To-lags watchdog (hardware + systemd) sikrer automatisk recovery uden menneskelig indgriben.

Se gateway arkitektur eller bestil installationspakke.