Er zat een bug in de firmware waarbij uitgeschakelde sensoren een alarm konden verzoorzaken. Dit is opgelost vanaf firmwareversie 1130.
Huidige firmwareversie: 1130
isImpossible ? letsTryIt() : letsDoIt();
Er zat een bug in de firmware waarbij uitgeschakelde sensoren een alarm konden verzoorzaken. Dit is opgelost vanaf firmwareversie 1130.
Huidige firmwareversie: 1130
De vernieuwde taakverdeling tussen microprocessor en WiFi-module blijkt een goede zet te zijn geweest. Pond[CTRL] draait vele malen stabieler en heeft de afgelopen 24 uur nog geen enkele ongeplande reset gehad (een ongeplande reset is een reset door bijvoorbeeld een hard- of softwarefout).
Vandaag heb ik de API en de firmware van de WiFi-module aangepast. De API geeft nu een json-resultaat na uploaden van data waarin de meest firmware-versie en de status vermeld staan. Indien de API-call succesvol was, dan zal de programmeerbare LED gaan branden wat vanaf nu aangeeft of er een succesvolle link is met de API. De LED brandt net zo lang tot er een negatieve of geen status ontvangen wordt. Door de versienummers van de huidige firmware en de nieuwste firmware te vergelijken, wordt er nu een automatische update in gang gezet.
Huidige firmwareversie: 1129
Omdat Pond[CTRL] nu naast de vijver hangt in een waterdichte behuizing, is het lastig om software van de microprocessor te updaten. Hierdoor heb ik de beslissing genomen om alle logica en berekeningen te verplaatsen van de software van de microprocessor naar die van de WiFi-module welke op afstand bij te werken is.
De microprocessor doet nu niets anders van sensorgegevens ophalen en luisteren naar opdrachten van de WiFi-module. De WiFi-module kan vanaf nu ook stekkers schakelen, de status-LED besturen en buzzer (de)activeren.
Daarnaast was het geven van opdrachten vanaf de online app te complex. Er moest gewerkt worden met byte-arrays die direct doorgespeeld werden naar de microprocessor. Ik heb opdracht-URLs toegevoegd aan de webserver van de WiFi-module, waarmee aan de hand van simpele opdrachten gecombineerd met POST-data alles op te halen en in te stellen is. Voor test-doeleinden is de ‘query?data=’-URL nog steeds aanwezig maar werkt alleen zodra ingelogd op de module.
De microprocessor crashte, ondanks het toevoegen van varistors, bij het schakelen van meerde apparaten gelijktijdig. Om dit te voorkomen heb ik een kleine vertraging van het schakelen van elk relais toegevoegd waarmee het probleem verholpen lijkt.
Enige probleem op dit moment is nog steeds de foute meetwaarden van de pH-sensor bij een buitentemperatuur van onder de 10 graden Celcius. Het vreemde is dat de meting niet afhankelijk is van de watertemperatuur, terwijl de sensor in het water hangt.
Pond[CTRL] is nu enige tijd actief en door uitgebreid te testen heb ik een en ander aan de hard- en software aangepast.
Software
De belangrijkste wijziging in de software is het afvlakken van de meetwaarden. Er wordt nu bij temperatuur- en pH-sensoren een gemiddelde van de laatste 120 juiste meetwaarden weergegeven, waarbij een juiste meetwaarde een waarde is die maximaal 5% afwijkt van de voorgaande. Bij schakelen van relais bleek er soms een foute meetwaarde tussen te zitten (door een dip in de stroomvoorziening) waardoor meetwaarden een alarm veroorzaakten. De 5% regel zit geprogrammeerd in de microprocessor zelf en de WiFi-module om ook storingen op de I2C-bus op te vangen.
De ingebouwde interface van de WiFi-module werkte alleen juist in standalone-modus (wanneer Pond[CTRL] als access point fungeerde). De interface werkt nu in beide modi.
Hardware
De hardware bleek helaas ook niet helemaal te functioneren zoals gewenst. Veel apparaten kunnen geschakeld worden zonder problemen, echter bij het uitschakelen van een zwaardere pomp ontstond er storing in de stroomvoorziening waardoor de microprocessor zichzelf resette. Dit probleem is gemakkelijk op te lossen door een voldoende zware varistor op de fase en nul van elk relais te zetten. De bedoeling is om deze varistor in het standaardontwerp van de print op te nemen.
Online Dashboard
Het online Dashboard toont nu alleen het bereik van de meetwaarden en niet langer het gehele bereik tussen laag en hoog alarm.
Problemen
Het enige probleem wat ik nog niet opgelost is, is de instabiliteit van de pH sensor bij temperaturen onder de 10 graden Celsius. Omdat ik niet weet of dit aan de sensor of het hardware-ontwerp van Pond[CTRL] ligt, wil ik eerst een tweede sensor testen.
What’s next
De komende tijd zal vooral bestaan uit een duurtest en (tromgeroffel!) het ontwerpen van een iOS-app. De app zal het online dashboard en app combineren in één.
Na wat finetunen werkt alles zoals in eerste instantie bedoeld: er wordt een reeks IP-adressen gescand en indien online wordt het MAC-adres vergeleken met bekende apparaten. Is er een bekend apparaat online, dan zal de thermostaat (geroote Toon) zijn programma vervolgen. Zijn er geen apparaten online, dan wordt de thermostaat ingesteld op programma ‘Weg’ en gaan de opgegeven lampen (Philips Hue) automatisch uit! Naast lampen kan door middel van slimme stekkers natuurlijk ook sluipverbruik (standby apparaten) voorkomen worden.
Toekomstwensen? Mogelijkheid tot opnieuw inschakelen van bijvoorbeeld nachtlampjes op de kinderkamers. Zijn we weg, dan blijft alles uit. Komen we weer thuis, dan zou er bijvoorbeeld ingeschakeld kunnen worden als de zon onder is. De voorbereidingen voor zoninformatie is al in de laatste versie van mijn script verwerkt.
Het script
Je dient variabelen ’toonIP’, ‘hueIP’, ‘locationLat’, ‘locationLon’, ‘ipRange’, ‘ipStart’, ‘ipEnd’, ‘hueAPIKey’ en ‘path’ in te stellen.
#!/bin/bash
# Script door Dennis Bor
# IP van Toon
toonIP="192.168.0.X"
# IP van Hue
hueIP="192.168.0.X"
# jouw locatie
locationLat="XX.XXXXXX"
locationLon="X.XXXXXX"
# te scannen IP range (opgegeven IP .1 - .255
ipRange="192.168.0."
ipStart=130
ipEnd=140
# API-key van Hue
hueAPIKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# pad naar het script
path="/home/dennis/home_automation/"
# pad naar arp
arpPath="/usr/sbin/"
# toon informatie
date
# zonsopkomst en ondergang ophalen aan de hand van de opgegeven longitude en latitude
sunrise=`curl -s "https://api.sunrise-sunset.org/json?lat=$locationLat&lng=$locationLon" | jq -r '.results.sunrise'`
sunset=`curl -s "https://api.sunrise-sunset.org/json?lat=$locationLat&lng=$locationLon" | jq -r '.results.sunset'`
# tijdverschil ten opzichte van UTC ophalen
timeDifferenceUTC=`date +%z`
# substring vanaf index 2 (+0100 wordt bijvoorbeeld 100; 1 uur)
timeOffset=${timeDifferenceUTC:2}
# offset delen door 100 voor het aantal hele uren
timeOffset="$(($timeOffset / 100))"
# timestamps genereren voor zonsopkomst, zonsondergang en huidige tijd, inclusief UTC offset
# voor gegevens van api.sunrise-sunset.org
sunriseTimestamp=`date -d "$sunrise + $timeOffset hours" +%s`
sunsetTimestamp=`date -d "$sunset + $timeOffset hours" +%s`
currentTimestamp=`date +%s`
# huidige tijd tussen zonsopkomst en ondergang
if [ $sunriseTimestamp -lt $currentTimestamp ] && [ $sunsetTimestamp -gt $currentTimestamp ]; then
# ja
# toon informatie
echo "De zon is momenteel op."
# stel de boolean in op true
sunUp=true
# huidige tijd voor zonsopkomst of na zonsondergang
else
# ja
# toon informatie
echo "De zon is momenteel onder."
# stel de boolean in op true
sunUp=false
fi
# Array met mac adressen
# Als geen van deze apparaten gevonden wordt in het lokale
# netwerk, dan zal er geschakeld worden.
deviceArray=()
# itereer door bestand 'devices' waarin
# per regel een mac-adres van een apparaat opgegeven
# kan worden
while read line; do
# geen lege regel?
if [[ $line != "" ]]; then
# voeg het apparaat toe aan de array
deviceArray+=("$line")
fi
done < "$path"devices
# Boolean waarin opgeslagen wordt of er tenminste een
# van de gespecificeerde apparaten online is. Standaard false
deviceFound=false
# Toon informatie
echo "Zoeken naar apparaten, dit duurt een paar minuutjes..."
# itereer door het opgegeven ip bereik
for iterator in $(seq $ipStart $ipEnd)
do
# apparaat gevonden (boolean true)?
if [[ $deviceFound == true ]]; then
# ja, escape deze for-loop
break
fi
# toon informatie
printf "Scannen van $ipRange$iterator"
# itereer van 1 t/m 50 (maximaal aantal pogingen). Het grote aantal iteraties bleek
# nodig omdat de enige open WiFi poort op de iphone tijdens standy (62078) maar
# op bepaalde momenten reageert. 99% van de keren is dit binnen 25 pogingen, maar
# enkele uitschieters tussen de 30 en 40 kwamen voor. 50 is dus echt met een
# ingebouwd veilig marge
for subIterator in {1..50}}
do
# apparaat nog (steeds) niet gevonden?
if [[ $deviceFound == false ]]; then
# toon informatie (puntje, soort progress indicator)
printf "."
# scan poort 62078 met een delay van 250ms op het huidige ip adres
nmapResult=`nmap --scan-delay 250ms -p 62078 "$ipRange$iterator"`
# komt de tekst '1 host up' voor in de uitvoer van nmap? dat
# betekent dat het apparaat gevonden is
if [[ $nmapResult == *"1 host up"* ]]; then
# itereer door alle apparaten in de array
for macIterator in "${deviceArray[@]}"
do
# komt het huidige mac adres voor in de uitvoer van nmap?
if [[ $nmapResult == *"$macIterator"* ]]; then
# ja
# toon informatie (eerste echo zorgt voor een linebreak na de progress
# indicator puntjes)
echo ""
printf "Apparaat met adres $macIterator gevonden"
# stel de boolean in op true (apparaat gevonden!)
deviceFound=true
# verlaat de for-loop
break
fi
done
fi
fi
done
# apparaat nog (steeds) niet gevonden
if [[ $deviceFound == false ]]; then
# nee
# toon progress indicator
printf "."
# als laatste poging pingen we, waarop Android apparaten wel altijd reageren.
# lukt de ping ook niet, dan kunnen we er wel van uit gaan dat het apparaat echot
# niet binnen het bereik van het WiFi-netwerk is.
pingResult=`ping -c 4 "$ipRange$iterator"`
# komt de tekst '100% packet loss' niet voor in de uitvoer van ping?
if [[ $pingResult != *"100% packet loss"* ]]; then
# nee! dat betekent dat het apparaat tenmiste eenmaal gereageerd
# heeft op een ping
# arp informatie ophalen van het apparaat, zodat we het mac adres
# kunnen vergelijken met onze bekende apparaten
arpResult=`"$arpPath"arp -a "$ipRange$iterator"`
# itereer door alle mac adressen in de array
for macIterator in "${deviceArray[@]}"
do
# komt het huidige mac adres voor in de uitvoer van arp?
if [[ ${arpResult^^} == *"$macIterator"* ]]; then
# yep! bekend apparaat gevonden!
# toon informatie (eerste echo is een linebreak na de progress
# indicator
echo ""
printf "Apparaat met adres $macIterator gevonden"
# stel de boolean in op true (apparaat gevonden)
deviceFound=true
# verlaat de for loop
break
fi
done
fi
fi
# toon informatie (linebreak)
echo ""
done
# Geen apparaten online?
if [[ $deviceFound == false ]]; then
# nee
# toon informatie
echo "Geen apparaten online, actie ondernemen..."
# schakel programma Toon in op Weg
# gebruik curl, parse de uitvoer als JSON en sla de waarde van 'result' op
# de waarde wordt bij de tweede call overschreven; als de laatste faalt,
# dan moet de eerste ook gefaald zijn en andersom
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=0"`
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=2&temperatureState=3" | jq -r '.result'`
# waarde van result 'ok'?
# dat betekent dat Toon het gekozen programma geacvtiveerd heeft
if [[ $result == "ok" ]]; then
# toon informatie
echo "Toon ingesteld op 'Weg'"
# waarde van result ongelijk aan 'ok'? dit kan alles zijn, van een ander resultaat tot
# verbindingsproblemen, etc.
else
# toon informatie
echo "Kan toon niet instellen op 'Weg'"
fi
# toon informatie
echo "Hue instellen..."
# haal alle lampen op
result=`curl -s "http://$hueIP/api/$hueAPIKey/lights"`
# array keys uit de json array van Hue halen. helaas gebruikt Hue geen
# array met indices, maar met keys. van lampen die verwijderd worden
# vervalt het id.
arrayKeys=`echo "$result" | jq -r 'keys | .[]'`
# nieuwe array om alle keys in op te slaan
arrayIDs=()
# itereer door alle array keys
for key in ${arrayKeys//\\n/ }
do
# voeg de key toe aan de array
arrayIDs+=("$key")
done
# inhoud van bestand 'lights' opslaan in de variabele. Bij alle lampen van Hue
# wordt gecontroleerd of ze in deze lijst voorkomen, voordat ze uitgeschakeld worden.
# hierdoor blijft het mogelijk om bepaalde verlichting te laten branden (bijvoorbeeld
# tuinverlichting)
lightsToSwitch=`cat "$path"lights`
# itereer door alle IDs
for lightIterator in "${arrayIDs[@]}"
do
# unieke id van de lamp ophalen. in het betand 'lights' kun je een lijst aanleggen
# van unieke ids van lampen die uitgeschakeld moeten worden
currentUniqueId=`echo "$result" | jq --arg value $lightIterator -r '.[$value].uniqueid'`
# komt het huidige unieke id voor in de lijst met ids?
if [[ $lightsToSwitch == *"$currentUniqueId"* ]]; then
# ja
# lamp naam ophalen zodat deze getoond kan worden
currentName=`echo "$result" | jq --arg value $lightIterator -r '.[$value].name'`
# toon informatie
echo "Uitschakelen: $currentName ($currentUniqueId)"
# schakel de lamp uit
toonResult=`curl -s -X PUT -H "Content-Type: application/json" -d '{"on":false}' "http://$hueIP/api/$hueAPIKey/lights/$lightIterator/state"`
fi
done
# Tenminste een apparaat online?
else
# ja
# toon informatie
echo "Een of meer apparaten online, thermostaat herstellen..."
# hervat het programma van toon
# gebruik curl, parse de uitvoer als JSON en sla de waarde van 'result' op
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=1" | jq -r '.result'`
# waarde van result 'ok'?
# dat betekent dat Toon het programma hersteld heeft
if [[ $result == "ok" ]]; then
# toon informatie
echo "Toon hervat programma"
# waarde van result ongelijk aan 'ok'? dit kan alles zijn, van een ander resultaat tot
# verbindingsproblemen, etc.
else
# toon informatie
echo "Kan het programma op Toon niet hervatten"
fi
# toon informatie
echo "Klaar..."
fi
Benodigde bestanden
Bestandsnaam ‘devices’
# lijst met MAC adressen van bekende apparaten.
# zet elk apparaat op een aparte regel
XX:XX:XX:XX:XX:XX
XX:XX:XX:XX:XX:XX
Bestandsnaam ‘lights’
# lijst met uit te schakelen Hue lampen bij afwezigheid
# zet elke lamp (of slimme stekker) op een aparte regel
# gebruik de 'uniqueid' parameter
XX:XX:XX:XX:XX:XX-XX:XX
XX:XX:XX:XX:XX:XX-XX:XX
Update na 48 uur
Het veranderen van DHCP leases had geen invloed op de betrouwbaarheid van de arp-cache. Ik moest dus een andere manier verzinnen om aanwezigheid te detecteren. Nu blijkt dat iPhones, zodra het scherm uit gaat, in een soort slaapmodus terecht komen waarin WiFi niet beschikbaar is, BEHALVE op poort 62078. Deze poort blijkt helaas niet altijd bereikbaar. Het script werkt nu als volgt voor ieder te controleren IP-adres:
Testresultaten na 24 uur
E3 arp-cache uitlezen bleek niet betrouwbaar. Vooral iPhones bleven onnodig lang in de cache staan. Ik heb geprobeerd om de maximale DHCP-lease te verkorten naar 10 minuten, zodat de apparaten hopelijk ook na maximaal 10 minuten inactiviteit uit de cache verdwijnen.
Een toiletbezoek zonder verlichting is lastig ?. Ik dacht nog even te testen en WiFi uit te schakelen op mijn mobiel. Vrouwlief was uit huis en de mobiel van m’n zoon uitgeschakeld. Het script werkte prima! In het toilet, hallen en badkamer heb ik bewegingssensoren. Het script werkte in dit geval prima, echter was de configuratie niet juist. Deze lampen verwijderd uit het ‘lights’ bestand zodat de bewegingssensoren niet overruled worden.
Nu wederom testen. To be continued!
Sinds vandaag werkt het script voor afwezigheidsdetectie met zowel (geroote)Toon als Hue. Er zijn een ook aantal aanpassingen gemaakt zoals het toevoegen van absolute paden naar bestanden voor gebruik met cron.
Het script bestaat uit drie bestanden:
Belangrijk is om voor Hue een unieke API-key aan te maken. Dit kan via de clip API debugger (check voor meer informatie de site van Philips Hue).
Bij mij draait het bestand elke vijf minuten via Cron en wordt uitvoer opgeslagen naar een log-bestand, waarvan de uitvoer als volgt is:
Zoeken naar apparaten, dit duurt een paar minuutjes...
Apparaat offline: xx:xx:xx:xx:xx:xx
Apparaat offline: xx:xx:xx:xx:xx:xx
Apparaat offline: xx:xx:xx:xx:xx:xx
Apparaat offline: xx:xx:xx:xx:xx:xx
Geen apparaten online, actie ondernemen...
Toon ingesteld op 'Weg'
Hue instellen...
Uitschakelen: Badkamer spot 1 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Badkamer spot 2 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Badkamer spot 3 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Hal boven spot 1 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Hal boven spot 2 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Hal boven spot 3 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Plafonniere (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Plafonniere hal (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Plafonnière (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Keuken (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Keuken spot 1 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Keuken spot 2 (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Tv hoek (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Zithoek (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Uitschakelen: Plafonnière (xx:xx:xx:xx:xx:xx:xx:xx-xx)
Het script ziet er nu als volgt uit:
#!/bin/bash
# Script door Dennis Bor
# IP van Toon
toonIP="192.168.0.58"
# IP van Hue
hueIP="192.168.0.87"
# API-key van Hue
hueAPIKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# pad naar het script
path="/home/dennis/home_automation/"
# pad naar arp
arpPath="/usr/sbin/"
# Array met mac adressen
# Als geen van deze apparaten gevonden wordt in het lokale
# netwerk, dan zal er geschakeld worden.
deviceArray=()
# itereer door bestand 'devices' waarin
# per regel een mac-adres van een apparaat opgegeven
# kan worden
while read line; do
# geen lege regel?
if [[ $line != "" ]]; then
# voeg het apparaat toe aan de array
deviceArray+=("$line")
fi
done < "$path"devices
# Boolean waarin opgeslagen wordt of er tenminste een
# van de gespecificeerde apparaten online is. Standaard false
deviceFound=false
# Toon informatie
echo "Zoeken naar apparaten, dit duurt een paar minuutjes..."
# Leeg de arp cache
ipResult=`ip -s -s neigh flush all`
# Wacht drie minuten
sleep 3m
# Haal de arp table op
arpResult=`"$arpPath"arp -a`
# Itereer door alle gespecificeerde mac adressen
for macIterator in "${deviceArray[@]}"
do
# huidige adres in de arp tabel?
if [[ $arpResult == *"$macIterator"* ]]; then
# ja
# toon informatie
echo "Apparaat online: $macIterator"
# stel de boolean in op true
deviceFound=true
# huidige adres niet in de arp tabel
else
# nee
# toon informatie
echo "Apparaat offline: $macIterator"
fi
done
# Geen apparaten online?
if [[ $deviceFound == false ]]; then
# nee
# toon informatie
echo "Geen apparaten online, actie ondernemen..."
# schakel programma Toon in op Weg
# gebruik curl, parse de uitvoer als JSON en sla de waarde van 'result' op
# de waarde wordt bij de tweede call overschreven; als de laatste faalt,
# dan moet de eerste ook gefaald zijn en andersom
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=0"`
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=2&temperatureState=3" | jq -r '.result'`
# waarde van result 'ok'?
# dat betekent dat Toon het gekozen programma geacvtiveerd heeft
if [[ $result == "ok" ]]; then
# toon informatie
echo "Toon ingesteld op 'Weg'"
# waarde van result ongelijk aan 'ok'? dit kan alles zijn, van een ander resultaat tot
# verbindingsproblemen, etc.
else
# toon informatie
echo "Kan toon niet instellen op 'Weg'"
fi
# toon informatie
echo "Hue instellen..."
# haal alle lampen op
result=`curl -s "http://$hueIP/api/$hueAPIKey/lights"`
# array keys uit de json array van Hue halen. helaas gebruikt Hue geen
# array met indices, maar met keys. van lampen die verwijderd worden
# vervalt het id.
arrayKeys=`echo "$result" | jq -r 'keys | .[]'`
# nieuwe array om alle keys in op te slaan
arrayIDs=()
# itereer door alle array keys
for key in ${arrayKeys//\\n/ }
do
# voeg de key toe aan de array
arrayIDs+=("$key")
done
# inhoud van bestand 'lights' opslaan in de variabele. Bij alle lampen van Hue
# wordt gecontroleerd of ze in deze lijst voorkomen, voordat ze uitgeschakeld worden.
# hierdoor blijft het mogelijk om bepaalde verlichting te laten branden (bijvoorbeeld
# tuinverlichting)
lightsToSwitchOff=`cat "$path"lights`
# itereer door alle IDs
for lightIterator in "${arrayIDs[@]}"
do
# unieke id van de lamp ophalen. in het betand 'lights' kun je een lijst aanleggen
# van unieke ids van lampen die uitgeschakeld moeten worden
currentUniqueId=`echo "$result" | jq --arg value $lightIterator -r '.[$value].uniqueid'`
# komt het huidige unieke id voor in de lijst met ids?
if [[ $lightsToSwitchOff == *"$currentUniqueId"* ]]; then
# ja
# lamp naam ophalen zodat deze getoond kan worden
currentName=`echo "$result" | jq --arg value $lightIterator -r '.[$value].name'`
# toon informatie
echo "Uitschakelen: $currentName ($currentUniqueId)"
# schakel de lamp uit
toonResult=`curl -s -X PUT -H "Content-Type: application/json" -d '{"on":false}' "http://$hueIP/api/$hueAPIKey/lights/$lightIterator/state"`
fi
done
# Tenminste een apparaat online?
else
# ja
# toon informatie
echo "Een of meer apparaten online, thermostaat herstellen..."
# hervat het programma van toon
# gebruik curl, parse de uitvoer als JSON en sla de waarde van 'result' op
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=1" | jq -r '.result'`
# waarde van result 'ok'?
# dat betekent dat Toon het programma hersteld heeft
if [[ $result == "ok" ]]; then
# toon informatie
echo "Toon hervat programma"
# waarde van result ongelijk aan 'ok'? dit kan alles zijn, van een ander resultaat tot
# verbindingsproblemen, etc.
else
# toon informatie
echo "Kan het programma op Toon niet hervatten"
fi
# toon informatie
echo "Klaar..."
fi
En nu maar testen. Vooral het detecteren van iPhones lijkt (nog) niet helemaal vlekkeloos te verlopen: ofwel ze blijven te lang in de cache staan, of ze worden niet verwijderd.
Na het rooten van Toon kun je door het aanroepen van een bepaalde URL veel, zoals programma’s, instellen. Ik heb het script voor afwezigheidsdetectie aangepast zodat Toon bij afwezigheid het programma ‘Weg’ activeert.
Een andere kleine update aan het script is dat MAC adressen van apparaten nu in een apart bestand ‘devices’ opgeslagen moeten worden. Het script leest dit bestand uit.
Omdat er gebruik wordt gemaakt van JSON output, dient ‘jq’ geïnstalleerd te zijn op de server.
#!/bin/bash
# Script door Dennis Bor
# IP van Toon
toonIP="192.168.0.58"
# Array met mac adressen
# Als geen van deze apparaten gevonden wordt in het lokale
# netwerk, dan zal er geschakeld worden.
deviceArray=()
# itereer door bestand 'devices' waarin
# per regel een mac-adres van een apparaat opgegeven
# kan worden
while read line; do
# geen lege regel?
if [[ $line != "" ]]; then
# voeg het apparaat toe aan de array
deviceArray+=("$line")
fi
done < devices
# Boolean waarin opgeslagen wordt of er tenminste een
# van de gespecificeerde apparaten online is. Standaard false
deviceFound=false
# Toon informatie
echo "Zoeken naar apparaten, momentje..."
# Haal de arp table op
arpResult=`arp -a`
# Itereer door alle gespecificeerde mac adressen
for macIterator in "${deviceArray[@]}"
do
# huidige adres in de arp tabel?
if [[ $arpResult == *"$macIterator"* ]]; then
# ja
# toon informatie
echo "Apparaat online: $macIterator"
# stel de boolean in op true
deviceFound=true
# huidige adres niet in de arp tabel
else
# nee
# toon informatie
echo "Apparaat offline: $macIterator"
fi
done
# Geen apparaten online?
if [[ $deviceFound == false ]]; then
# nee
# toon informatie
echo "Geen apparaten online, actie ondernemen..."
# schakel programma Toon in op Weg
# gebruik curl, parse de uitvoer als JSON en sla de waarde van 'result' op
result=`curl -s "http://$toonIP/happ_thermstat?action=changeSchemeState&state=2&temperatureState=3" | jq -r '.result'`
# waarde van result 'ok'?
# dat betekent dat Toon het gekozen programma geacvtiveerd heeft
if [[ $result == "ok" ]]; then
# toon informatie
echo "Toon ingesteld op 'Weg'"
# waarde van result ongelijk aan 'ok'? dit kan alles zijn, van een ander resultaat tot
# verbindingsproblemen, etc.
else
# toon informatie
echo "Kan toon niet instellen op 'Weg'"
fi
# Tenminste een apparaat online?
else
# ja
# toon informatie
echo "Een of meer apparaten online, afsluiten..."
fi