Hedy Lamarr Hacken

Lotte is het hele weekend weg en ik heb genoeg gewast en geplast voor vandaag, dus terwijl de spaghettisaus nog een uurtje pruttelt begin ik alvast aan mijn projectje voor dit weekend. Vanavond ga ik Hedy Lamarr hacken.

Hedy Lamarr was een filmactrice en de uitvindster van Frequency Hopping Spread Spectrum en sinds twee weken ook onze WiFi-router. Voor meer informatie over zowel onze router als de origenele Hedy lees je best mijn blogpost van vanmorgen, Nieuwe huisgenoot: Hedy Lamarr. Daarin kan je onder andere lezen dat ik ons Hedy graag van een bewegingssensor had voorzien zodat ze wat kan rusten als wij toch nog niet thuis zijn of liggen slapen.

Hedy Lamarr naakt in de kast

Hedy Lamarr naakt in de kast

Omdat ik daar zin in heb, ga ik dat stapsgewijs bloggen vanavond en morgen. Een soort van semi-livebloggen.

Ik heb al een aantal stappen en functionaliteiten in mijn hoofd en die ga ik één voor één aflopen. Om eerlijk te zijn. Wat ik voornamelijk ga doen is verschillende tutorials na elkaar doorlopen en de stukken die ik nodig heb er uit halen en terug combineren.

Het uiteindelijke doel is een router die aanspringt als er mensen in huis zijn en afspringt als er niemand thuis is of als iedereen slaapt, een logje bijhoudt van al dat af en aanspringen (om te kunnen finetunen) en die ik via een knop kan doen afsluiten of resetten.

Aangezien ik twee Raspberry Pi’s heb, ga ik Hedy rustig zichzelf laten wezen in de kast en experimenteren met mijn tweede Pi. Op die manier kan ik makkelijker resetten en knoeien zonder dat ook iedere keer het internet uitvalt. En ik ga het gros van het programmeerwerk ook via SSH doen (dus door via mijn laptop in te loggen op de Raspberry Pi). Op die manier kan ik niet alleen makkelijker code kopiëren van mijn laptop naar de Pi, maar kan ik ook op het einde alles makkelijk overzetten naar Hedy.

Stap 0: De voorbereiding

Die tweede Pi had ik snel gevonden, maar waar lagen mijn SD-kaartjes nu weer? Blijkbaar ergens onderaan in een doos. En op welk kaartje stond nu weer wat?

 

Wat stond er nu weer op welk SD-kaartje?

Dus even het televisietje op tafel gezet en de eerste kaart geprobeerd. Van de eerste keer prijs. Geprobeerd om met een vast IP-adres, maar het lukte me niet om dat geregeld te krijgen in combinatie met een internetverbinding via mijn laptop, dus probeer ik het maar met een dynamisch adres. Dus laat ik de TV maar in de buurt staan, voor het geval ik hem nog nodig heb.

 

Maar ondertussen zijn we bijna twee uur verder en ga ik toch eens een stukje eten. De saus heeft al lang genoeg geprutteld, snel even wat spirelli koken, eten en dan beginnen aan stap 1. Tot zo.

Stap 1: de PIR-sensor aan de praat krijgen

Dat ga ik doen aan de hand van deze adafruit-tutorial om beweging te detecteren. Al ga ik die zoals gewoonlijk weer niet helemaal exact volgen omdat ik niet helemaal dezelfde onderdelen gebruik. Bijvoorbeeld mijn Pi Protoplate in plaats van een Pi Cobbler, maar uiteindelijk zijn dat details.

Gemakkelijk te installeren, maar werkt hij ook?

Gemakkelijk te installeren, maar werkt hij ook?

De sensor installeren was enorm gemakkelijk: gewoon het juiste draadje in het juiste gaatje en dichtvijzen maar. Daarna het “echte werk: python installeren, de code kopiëren, aanpassen en laten lopen.

Een klein voorbeeldje met een koffietas over de sensor zodat hij zeker niets kan zien:


 

Dat ging dus vlot. Verdertesten met die handel. Op naar stap 2.

Stap 2: De PIR-sensor een linuxcommando laten triggeren

Tot ik de sensor aan ons Hedy koppel, kan ik moeilijk de WiFi aan of uitschakelen met de sensor (of testen of ik dat kan), dus gebruik ik deze adafruit-tutorial om een geluid af te spelen als er beweging gedecteteerd wordt.

Voor de tutorial heb je expliciet een WAV-bestandje nodig (MP3 werkt niet) dus ik even op zoek naar een WAV-bestandje op het internet. Zo kwam ik uit bij dailywav.com. Een site met als baseline “annoying your cubemates since 1995”, bij het REC Radiocentrum zijn ze denk ik blij dat ik die site niet kende toen ik er nog werkte…

In ieder geval: snel een geluidje gekozen en gedownload. Dat werkte niet zo goed omdat het wel een wav-bestand was, maar niet van het juiste type. Grmbl. Dan maar snel wat drama van het internet geplukt met audacity en dat naar de Pi doorgesluisd.

In dit geval moest ik de code al iets meer aanpassen omdat ik geen deursensor wilde gebruiken, niet teveel wilde beginnen vijzen aan mijn sensor en toch ook even iets op het scherm wilde zien als er beweging was, maar het grootste gedeelte was nog steeds copy/paste.

Gelukkig lag Lotte’s kapotte hoofdtelefoon ook in de buurt, dus hoefde ik geen luidsprekers aan te sluiten.

Het tweede experiment met extra LED en hoofdtelefoon

Het tweede experiment met extra LED en hoofdtelefoon

De eerste test die ging zo:

Misschien iets teveel drama…

Ik vroeg me al af of het script enkel het bestand ging starten en dan doorgaan of eerst het hele bestand zou afspelen en dan pas opnieuw beginnen. Blijkbaar was het het eerste. Dan toch maar even het script aangepast en opnieuw getest.

Ook hier wordt het weer duidelijk dat de sensor nadat hij afgedekt is toch nog even blijft doorgaan. Geen idee hoe dat komt, misschien ligt het aan het script, misschien blijft de sensor zelf iets te lang doorwerken, miscchien ligt het aan de snelheid waarmee de sensor zijn signalen doorstuurt. In ieder geval heeft het normaal gezien niet al te veel invloed op wat ik van plan was, aangezien ik het internet pas na een uur wil laten uitvallen (en de sensor eerst wilde laten checken of de verbinding nog open stond of niet).

Maar goed, tijd voor de volgende stap.

Stap 3: de acties loggen

Ik wil graag ook een log creëren van de acties die uitgevoerd worden, zodat ik makkelijk kan zien wanneer het netwerk aanspringt, afspringt, de sensor getriggerd wordt en of ik die moet aanpassen.

Ik had daar al wat info over gevonden op stackoverflow, in deze thread.

Die probeer ik nu toe te passen. In eerste instantie leek me het voorbeeld dat gebruik maakt van de module Logbook wel handig, maar het lukte me niet om die op 1-2-3 te installeren en ondertussen is het na middernacht, dus heb ik ook niet teveel zin meer om te knoeien. Dus ging ik maar aan de slag met het eerste voorbeeld en weefde dat door de code van Stap 2.

Dat gaf het volgende resultaat:

Geen slecht begin, aangezien deze logger enkel de functie “print” bijhoudt, en print(“PIR ALARM!”) de enige “print” in het script is.

In eerste instantie kan ik hier mee verder, mits twee aanpassingen: een tijdsaanduiding & een “print” voor iedere verschillende actie om te kunnen differentiëren. Voor die tijdsaanduiding vond ik op stackoverflow onmiddellijk een aantal passende mogelijkheden. Ik koos voor
datetime.datetime.now().isoformat() 
En in dit script had ik maar twee mogelijkheden: “een alarm” en “geen alarm”, dus gaf ik ook een “print” voor “geen alarm”. Dat gaf het volgende resultaat:

White Russian Logbook

White Russian Logbook

Laat me stellen dat ik daar voorlopig tevreden mee kan zijn. Morgen eens kijken hoe makkelijk het is om Python te laten checken of onze WiFi nog aan staat en, indien niet om die enkel dan aan te zetten en, indien er al een uur geen beweging meer is, om dan de WiFi uit te schakelen. Maar, zoals ik al zei, dat zal voor morgen zijn. Genoeg gespeeld voor nu, tijd om nog een filmpje te kijken.

 Stap 4: op commando services checken en reageren

Tijd om er terug in te vliegen. Uiteindelijk is het de bedoeling dat de PIR-sensor er voor zorgt dat het draadloos internet aanspringt als we opstaan of als we thuiskomen en dan blijft werken tot we gaan slapen of vertrekken. Of beter gezegd: tot we een uurtje vertrokken zijn, naar dromenland, dan wel naar het werk of de Stanny.

Ik ga een delay van een uur nemen omdat ik niet wil dat het internet uitvalt terwijl we thuis zijn en ik er van uitga dat de kans enorm klein is dat we overdag een uur niet in de buurt van Hedy passeren. Ze staat namelijk in de boekenkast tussen de living en de keukenJe moet door de keuken (en dus langs die kast) om vanuit de living naar het terras, de slaapkamer of de badkamer te gaan, dus zelfs als je gewoon snel iets wil nemen om te drinken of even naar het toilet gaat is dat genoeg om een “nieuw uur internet” te starten.  Hedy kijkt ook recht op onze voordeur als die openstaat dus als we thuiskomen, wordt ze terug wakker.

Misschien moet ik hier tussendoor nog eens aangeven waarom ik zoveel moeite doe om de WiFi aan en af te doen springen. Daar zijn verschillende redenen voor. Om te beginnen kan je je afvragen waarom dat draadloos netwerk de hele tijd zou moeten uitzenden als je toch niet thuis bent of als je drie meter verder ligt te slapen. Daar komt dan ook nog eens bij dat het WiFi-dongletje dat ik nu gebruik is ook niet echt ontworpen is om continu gebruikt te worden als Access Point. Dat is gemaakt om één computer te verbinden met een netwerk, niet om het verbindingspunt met het internet te zijn voor drie of vier toestellen tegelijk en dan nog de hele dag te staan roepen “Ik ben Hedy Lamarr! Ik ben Hedy Lamarr! Ik ben Hedy Lamarr!” Dus ga ik er van uit dat dat dongletje zo nu en dan wel wat rust kan gebruiken. De laatste reden is mischien nog de belangrijkste: omdat het kan en er enorm veel door leer. Dat is uiteindelijk ook de reden waarom de Raspberry Pi ontwikkeld werd: een goedkope computer waar je makkelijk mee kan experimenteren en leren. Ok, ik val een beetje buiten de oorspronkelijke doelgroep, ik zit namelijk niet meer op school, maar dat betekent niet dat ik er minder van zou kunnen leren. Anyway.

Back to Business. Het basisidee is:

“Als er beweging is, dan is er draadloos internet voor een uur.
Als er meer dan een uur lang geen beweging is,  is er geen draadloos internet meer.”

Spijtig genoeg kan je dat niet gewoon rechtstreeks omzetten in een computerprogramma. Hoe ik dat dan wel ga doen, ga ik vandaag proberen uitvogelen. Misschien is nu dan ook het moment om even aan te geven dat mijn programmeerervaring bestaat uit “ISOLAB” in het middelbaar (een virtueel autootje kegels laten zetten of weghalen), de eerste projecten uit “Getting started with Arduino”. Niet erg veel dus. Wat ik Hedy ga proberen te laten, zal in ieder geval het ingewikkeldste zijn dat ik tot nu heb geprogrammeerd.

Python iets laten doen op basis van een beweging kan ik ondertussen al, dus ga ik eerst de andere kant van het verhaal onderzoeken: Python het draadloos internet laten regelen. Hedy gebruikt daarvoor 2 services: hostapd en isc-dhcp-server. Omdat ik mijn experimenten doe op een PI zonder WiFi, kan ik die ‘services’ niet regelen. Daarom gebruik ik als vervangmiddel respectievelijk de services ‘mysql’ en ‘php’ tijdens mijn experimenten. Die gebruik ik niet op die Pi en hebben ook geen invloed op het netwerk, dus die kan ik makkelijk gebruiken.

In principe starten die services en het pyhton-script op als Hedy Lamarr opstart, dus zou ik kunnen veronderstellen dat ze van in het begin actief zijn en de waarde “running” als beginwaarde in mijn script zetten. Maar ik ben liever zeker en wil dus dat Hedy eerst gaat controleren of het draadloos internet wel aan staat. Op Stackoverflow vond ik veel verschillende voorbeelden, het onderstaande deed van de eerste keer wat ik vroeg.

import subprocess
output = subprocess.check_output(['ps', '-A'])
if 'mysql' in output:
    print("mysql is up and running!")
else:
    print("mysql is down :(")

Dat werkt naar behoren. Volgende stap: als de service mysql niet draait, gaan we die starten. Ook daar ga ik de Subprocess-library voor gebruiken. (je kan ook OS gebruiken, maar volgens deze post op cyberciti.biz kan dat problemen geven)

import subprocess
output = subprocess.check_output(['ps', '-A'])
if 'mysql' in output:
 print("mysql is up and running!")
else:
 print("mysql was down, but is running now")
 subprocess.call(["service", "mysql", "start"])

Als je de bovenstaande code test, is dit het resultaat:

pi@raspberrypi ~ $ sudo service mysql status
[info] MySQL is stopped..
pi@raspberrypi ~ $ sudo python running2.py
mysql was down, but is running now
[ ok ] Starting MySQL database server: mysqld . ..
[info] Checking for tables which need an upgrade, are corrupt or were
not closed cleanly..
pi@raspberrypi ~ $ sudo service mysql status
[info] /usr/bin/mysqladmin Ver 8.42 Distrib 5.5.31, for debian-linux-gnu on armv7l...

En nu volgt het stuk waarvan ik zelf nog niet goed weet hoe ik het best aanpak: hoe weet het script dat het al een uur geen beweging heeft gezien?

De scriptjes die ik tot nu toe gebruikte gingen eerst iets controleren (Is er beweging? Draait mysql?), dan iets doen (een geluid afspelen, een boodschap weergeven, een service starten) en stopten of gingen “slapen” en begonnen opnieuw. Dat kan ik hier moeilijk doen.

Of beter gezegd, ik zag niet hoe ik dat deftig kon gebruiken. Maar nu denk ik dat ik een oplossing zie…

En toen was de namiddag plots voorbij…

Quick recap: Ik was van in het begin van plan om de sensor iedere seconde te checken, omdat iedere halve seconde me wat veel van het goede leek, maar meer dan een seconde wachten te tricky, aangezien je niet veel tijd nodig hebt om die sensor te passeren en hij dus misschien toch uit zou vallen gewoon omdat je op het verkeerde moment gepasseerd bent.

En na een uur mag het internet uitgeschakeld worden. Dat laatste vond ik moeilijk. hoe kon ik in 1 loop zowel “1 seconde wachten” als “1 uur wachten” integreren en dan vooral nog “als er iets gebeurd begin je terug van 0 te tellen”. Awel dat “tellen” bracht me op een idee. In een uur zitten 3600 seconden, iedere seconde checkt Hedy of er beweging is, dus als ik Hedy iedere keer als ze niets ziet een streepje laat zetten, komt ze uiteindelijk uit bij 3600 seconden waarin niets gebeurde. Als ze dan nog iedere keer alle streepjes wegveegt als ze toch iets ziet, komt ze pas op 3600 als ze een heel uur lang niets gezien heeft. Op dat moment mag ze het internet afzetten en rustig verderdoen met iedere seconde te kijken. En als er iemand thuiskomt, zal ze dat zien, braaf gaan controleren of het internet nu aanstaat of niet en aangezien dat niet het geval is dat mooi terug aanzetten. Dank u, Hedy!

Tot zover de theorie. Ik probeerde dat in de praktijk om te zetten door het scriptje met het geluidsfragment en het logbestand aan te passen. Op die manier had ik ook auditieve input, kon ik ook achteraf in het logboek gaan kijken en had ik ineens code die ik makkelijk kon aanpassen. Om het mezelf makkelijker te maken voegde ik een tweede geluidje toe dat stond voor “internet afzetten” en liet ik Hedy maar tot 6 tellen in plaats van tot 3600.

Het werkte voor geen meter. Ik weet nog steeds niet wat er precies fout is aan die code, maar Hedy maakte vooral veel lawaai, weigerde terug vanaf 0 te beginnen, maar wilde ook niet vertellen wat er scheelde. De woorden “strekenwijf” en “vrouwenlogica” komen in me op, maar die zijn hier compleet niet op zijn plaats, aangezien Hedy er zelf niets aan kan doen, ik heb dat geschreven en ze heeft het geïnterpreteerd zoals het er staat.

In ieder geval. Ik ben maar opnieuw begonnen op basis van het eerste script: als je beweging ziet, print dan “PIR ALARM!”. Geen logboek, geen geluidjes. Eenvoud. Met een extra controlemechanisme: print ook iedere keer tot hoeveel je al geteld hebt. Kwestie van te zien of ze terug van 0 zou beginnen. Dat maakte het troubleshooten in ieder geval al stukken gemakkelijker. Na veel vijven en zessen kwam ik hier op uit:

import time
import datetime
import RPi.GPIO as io
io.setmode(io.BCM)

pir_pin = 18

io.setup(pir_pin, io.IN) # activate input

count = 0

while True:
  if io.input(pir_pin):
    print datetime.datetime.now().isoformat()
    print ("PIR ALARM!")
    print count
    count = 0
    time.sleep(2)
  else:
    if count != 6:
      count += 1
      print datetime.datetime.now().isoformat()
      print("Relax dude. Everything's cool...")
      print count
      time.sleep(2)
    else:
      count += 1
      print datetime.datetime.now().isoformat()
      print("This is boring. I'm outta here!")
      print count
      time.sleep(2)

En dat werkt. Als ik hier “controleer of er WiFi is”, “zet de WiFi aan” en “zet de WiFi af” heb ik de basisfunctionaliteit die ik wilde.

Maar dat zal voor later zijn. Eerst een beetje opruimen en koken (Rogan josh, al van 2007 geleden dat ik dat nog heb klaargemaakt), want straks komt Lotte thuis en die zal wel hongerig en moe zijn van haar weekend.