4G IoT

From RevSpace
Jump to: navigation, search
Project 4G IoT
Status Completed
Contact Juerd
Last Update 2018-10-28

Projectbeschrijving

  • Thuisnetwerk gebaseerd op een Raspberry Pi met een draadloze internetverbinding. Geen vaste lijn, geen losse router.
  • Bediening op afstand via SSH (want de S in IoT staat voor security!)
  • Verwarming instellen per vertrek
  • Remote de verwarming aanzetten, want een klokthermostaat werkt niet als je niet vooraf weet wanneer je naar huis gaat
  • Extreme energiebesparing: slaapkamer kunnen verwarmen zonder verplicht ook de woonkamer te moeten verwarmen
  • Raspberry Pi met 4G-module gekregen, dus ik heb niet hoeven zoeken naar geschikte onderdelen :)
  • Geen IPv6 want te veel onderdelen die dat niet ondersteunen

Deze pagina heb ik gemaakt omdat er mensen waren die geïnteresseerd waren in hoe je zoiets doet. Aangezien ik alles al werkend heb, kan het zijn dat ik dingen vergeten ben hier te documenteren. Deze pagina is dus niet bedoeld als complete howto of tutorial, maar meer een verzameling losse stukjes configuratie ter inspiratie.

Raspberry Pi met 4G

4G/LTE

Een USB-4G-module (SIM7100E) met een simkaart (simpel.nl, 2 GB/maand voor 7,50 €/maand) voor de internetverbinding. Ik heb eerst de pincode van de simkaart af gehaald om eindeloos drama te voorkomen.

Het makkelijkst is om de module gewoon altijd zelf de verbinding te laten maken:

   qmicli -d /dev/cdc-wdm0 --wds-set-autoconnect-settings=enabled

Verder gewoon een interface configureren en een NAT-router van het doosje maken:

   # ergens in /etc/network/interfaces
   auto wwan0
   iface wwan0 inet dhcp
       pre-up /usr/local/bin/wacht-op-data
       post-up iptables -t nat -A POSTROUTING -o $IFACE -j MASQUERADE
       post-up echo 1 > /proc/sys/net/ipv4/ip_forward

Bij het booten is de dataverbinding nog niet klaar. Vandaar dit scriptje dat daar op wacht:

   #!/bin/sh
   # /usr/local/bin/wacht-op-data
   while ! (qmicli -d /dev/cdc-wdm0 --wds-get-packet-service-status | grep connected); do
       echo "Wacht op gprs/umts/lte..."
       sleep 1
   done

SSH-toegang

Omdat inkomende verbindingen niet kunnen, gebruik ik autossh voor een uitgaande verbinding met een port forward van buiten naar binnen.

   adduser autossh
   su - autossh
   ssh-keygen
   cat .ssh/*pub | ssh tau@mijnvpsje.ergens.example.com 'cat >> .ssh/authorized_keys'

Om dataverkeer te besparen, protocol-niveau keepalives gebruiken omdat je daarvan wel de interval kunt configureren:

   # /home/autossh/.ssh/config
   ServerAliveInterval 180
   TCPKeepAlive no

Systemd unit voor automatisch starten:

   # /etc/systemd/system/autossh.service
   [Unit]
   Description=AutoSSH tunnel service
   After=network.target
   
   [Service]
   Type=simple
   User=autossh
   ExecStart=/usr/bin/autossh tau@mijnvpsje.ergens.example.com -tt -N -R2220:127.0.0.1:22
   Restart=always
   RestartSec=60
   
   # voorkomt dat ie stopt als de eerste verbinding mislukt
   Environment="AUTOSSH_GATETIME=0"
   
   [Install]
   WantedBy=multi-user.target

Systemd schudden tot ie doet wat je wilt:

   systemctl daemon-reload
   systemctl enable autossh
   systemctl start autossh

Handige config om vanaf m'n laptop met 1 commando (ssh tau) via de vps op de raspberry pi in te loggen:

   # ergens in /home/juerd/.ssh/config op mijn laptop
   Host tau
       User root
       Hostname 127.0.0.1
       Port 2220
       ProxyJump mijnvpsje.ergens.example.com

Ja, ik werk als root. Lijkt me niet onzinnig op een device met maar 1 functie :)

DHCP-server

Om rechtstreeks LAN-dingen eraan te hangen zonder nog een router nodig te hebben (immers, deze raspberry pi is nu zelf al een router), is een DHCP-server handig. DNSMasq is meteen ook een DNS-server en enorm makkelijk in gebruik.

Enfin, eerst de netwerkinterface instellen zodat er iets te binden valt:

   # ergens in /etc/network/interfaces
   auto eth0
   iface eth0 inet static
       address 192.168.0.1
       netmask 255.255.255.0

En dan nog even 2 regels uncommenten:

   # ergens in /etc/dnsmasq.conf
   bind-interfaces
   dhcp-range=192.168.0.50,192.168.0.150,12h

eq3-max

Commercieel verkrijgbaar systeem: https://www.eq-3.com/products/max.html

  • In elke ruimte 1 wandthermostaat
  • Elke radiator een automatische thermostaatknop
  • 1x een LAN Cube, die als gateway werkt voor de draadloze communicatie met bovenstaande onderdelen.

Radiatorknoppen

De onderdelen waren bij de Duitse Amazon het goedkoopst. Ik ben gegaan voor radiatorkranen van het type "basic", omdat ik toch alles centraal ga aansturen en dus geen behoefte heb aan alle extra functies. Ik heb wel de "basic pro" gekozen, want die heeft een metalen moer ipv eentje van plastic.

Overigens heb ik irritante radiatoren, herkenbaar aan "MMA" op de radiatorkranen, waar je een adapter voor nodig hebt voordat je algemeen verkrijgbare andere dingen erop kunt draaien. Op de ene radiator werkt https://www.amazon.de/gp/product/B006PG6778/ref=oh_aui_detailpage_o01_s00 beter, op de andere https://www.amazon.de/gp/product/B01LZ2SRXV/ref=oh_aui_detailpage_o02_s00. Bij een van de radiatoren moest ik zelfs een metalen plaatje van 1 cent, ik bedoel letterlijk een 1-cent-munstuk, gebruiken omdat het palletje net iets korter is. Verklaart meteen waarom ik die radiator met de oorspronkelijke knop nooit helemaal dicht kon draaien...

Omdat alle bestaande software gesloten, Windows-only, incompleet of overmatig complex was voor wat ik wilde, heb ik zelf wat gebouwd.

Software

Source en documentatie: https://github.com/Juerd/eq3-max/

Om de ketel aan- en uit te schakelen, heb ik een standaard 5-volt-relaisbordje gebruikt met aparte signaalpin zodat ik 'm vanaf de 3.3 V GPIO van de raspberry pi kon voeden.

Dit scriptje controleert elke 10 seconden of het systeem behoefte heeft aan warm water, en of er wel een radiatorknop open staat (anders kan het water nergens heen gepompt worden).

   #!/bin/bash
   # /usr/local/bin/ketellus
   export MAX_HOST=192.168.0.104
   while :; do
       max summary \; switch /root/eq3-max/contrib/set-gpio
       sleep 10
   done

Wel even chmod +x doen.

En een systemd unit natuurlijk:

   [Unit]
   Description=eq3-max ketelbesturing
   After=network.target
   
   [Service]
   Type=simple
   User=root
   ExecStart=/usr/local/bin/ketellus
   Restart=always
   RestartSec=10
   
   [Install]
   WantedBy=multi-user.target

systemd overtuigen dat ie hier ook iets mee moet doen:

   systemctl daemon-reload
   systemctl enable ketellus
   systemctl start ketellus