iBeacon/LBE-scanner

Er is onder de bezoekers van deze website behoefte naar een tool waarbij je met de Raspberry Pi naar iBeacons/LBE beacons kan scannen. Daarnaast wil men dat op basis van herkenning van specifieke beacons er een actie aan verbonden wordt zoals het aansturen van de GPIO. Waarschijnlijk ontstaat de vraag doordat Domotica in opkomst is en dat men zuiniger met energie wil zijn.

Wat is een beacon?
Wat een beacon is en wat het doet heb ik in de tutorial ‘Pi als iBeacon (USB-baken)’ uitgelegd. Ik raad aan om deze eerste even door te nemen alvorens je aan deze tutorial begint.

In deze tutorial leg ik uit hoe je BLE (Bluetooth Low Energy) en iBeacons kunt scannen en de ontvangen informatie (zoals het MAC-adres) kunt gebruiken om een GPIO aan te sturen.

GitHub
Op GitHub vind je een veelgebruikte BLE-Beacon-Scanner, dat bestaat uit de basisprogramma’s ScanUtility en BeaconScanner en naar iBeacon- en Eddystone BLE-bakens zoekt. Deze tutorial baseer ik op deze programma’s omdat deze de juiste handvatten bieden om er meer mee te doen.

Aan de slag!
Ik ga ervan uit dat je Raspberry Pi ‘schoon’ is en dat de pakketten van de laatste updates en upgrades voorzien zijn. Zo niet, voer dan de volgende opdrachten in de terminal in.

sudo apt-get update

sudo apt-get upgrade

Om de directorie ‘BLE-Beacon-Scanner’ van GitHub te klonen geef je het volgende commando:

git clone https://github.com/bowdentheo/BLE-Beacon-Scanner

Controleer of alle bestanden zijn gekopieerd.

De gekloonde directorie van GitHub

Om de bluetooth module te installeren geef je het volgende commando:

pip install pybluez

Het is het bestand BeaconScanner.py dat we gaan aanpassen. Het script ScanUtility.py wordt als module in BeaconScanner.py geïmporteerd waardoor BeaconScanner.py relatief klein blijft. Voorwaarde is wel dat beide scripts in dezelfde directorie staan, anders zal je de paden in het script BeaconScanner.py moeten aanpassen.

Zodra beide bestanden in dezelfde directorie staan kun je testen of hetwerkt. Omdat het bestand BeaconScanner.py straks in meerdere uitvoeringen aangeboden zal worden, voeg ik een 0 (nul) aan de naam van het originele bestand toe. Je hernoemt het bestand als volgt:

mv BeaconScanner.py BeaconScanner0.py


De volgende sectie is niet noodzakelijk voor deze tutorial, maar een mooie aanvulling op de scantooling.

MiniScanner
Persoonlijk vind ik de output van BeaconScanner niet prettig, het is erg onrustig. Daarom heb ik BeaconScanner.py omgebouwd naar MiniScanner.py. Dit tool toont snel en helder de informatie van een beschikbaar beacon. Ook MiniScanner.py maakt gebruik van ScanUtility.py en dient daarom in dezelfde directorie te staan.

Zodra je MiniScanner.py in de terminal opstart zie je het script wachten op een beacon signaal.

De scanner wacht op het signaal van een beacon

Zodra het beacon ontvangen wordt verschijnt de signaalsterkte en de informatie van het beacon.


ModuleNotFoundError: No module named ‘bluetooth’ Error

Mocht je deze melding tegenkomen, de meest voorkomende oplossing voor deze melding is het installeren van een van de volgende bibliotheken. Je kunt ze allemaal proberen…

sudo apt-get install bluetooth
sudo apt-get install bluez
sudo apt-get install python-bluez
sudo apt install python3-bluez

Voor de volledigheid de Pi even rebooten met: sudo reboot

Tip: Probeer het python script eens als super-user (sudo) op te starten.


Beacons gezocht
Als er nog geen geschikt beacon door de software gedetecteerd wordt, kun je een beacon met een app op je smartphone simuleren. Ik heb hiervoor drie apps succesvol op iOS getest. Hieronder lees je hoe je ze gebruikt. Ik neem aan dat er voor Android vergelijkbare apps beschikbaar zijn. Mocht je weten welke, laat me dit dan weten, dan zet ik ze erbij.

  1. Beacon Toolkit
  2. Beacon Transmitter
  3. Locate

1. Beacon Toolkit
Om de smartphone als iBeacon te simuleren, heb ik de app Beacon Toolkit van RNF – Digital Innovation gebruikt.

  • Open de app
  • Klik op Advertise Beacons
  • Druk op de +
  • Geef de beacon een naam, bijvoorbeeld Test1
  • En druk op Generate Identifiers. Hiermee wordt het veld van de unieke UUID en de Major en Minor numerical ID’s automatisch gevuld
  • Druk nu op het vinkje rechts bovenin.
  • Je bent nu klaar!

Je kunt met de app meerdere ‘advertisers’ aanmaken. Ik houd het nu bij één.

Om het iBeacon – de smartphone met de app – uit te laten zenden schakel je in de app (Beacon Toolkit) de net aangemaakte advertizing Test1 van Off naar On.

2. Beacon Transmitter
Deze app is door een student gemaakt met de bedoeling zijn IoT-studie te ondersteunen. Met de app Beacon Transmitter simuleer je een iBeacon. Het UUID wordt automatisch gegenereerd, maar de Major en Minor waarden kunnen handmatig ingesteld worden.

Nadat de Transmit iBeacon knop aangezet is, zie je in het scanresultaat van MiniScanner.py de uitgezonden datastring voorbijkomen.

3. Locate
• De app Locate is in te zetten als een scanner of een transmitter.
• Open de app
• Klik onderin het scherm op het zendende symbool, de transmitter.
• Kies een van de voorgeprogrammeerde beacons, bijvoorbeeld Radius Networks 2F234454, het getal achter de fabrikant is het ID van de fabrikant.
• Je komt in het Beacon Info scherm van de transmitter en ziet de unieke UUID
• Je kunt de waarden van de Major en Minor instellen
• Je kunt de Power waarden instellen tussen -1 en -255. Vreemd genoeg lukt dit niet met het beschikbare toetsenbordje, dus ik laat het zo.
• Vervolgens druk je op Advertise Now

Na het opstarten van MiniScanner.py zie de datastring van de ‘advertising’ in de scaninfo voorbij komen.

Tijdelijk MAC-adres? Neem een fysiek beacon!
In de datastring is tevens het MAC-adres te zien. Ik heb gemerkt dat dit NIET het MAC-adres van mijn smartphone is en dat het adres maar zeer kort beschikbaar is voordat het wisselt met een nieuwe. Waarschijnlijk heeft dit te maken met de gratis app. Wil je hier geen last van hebben, is het verstandig een fysiek beacon aan te schaffen. Op internet koop je LBE/(i)Beacons in allerlei soorten, maten en bedragen. Je hebt er al een voor zo’n 7 euro.

Voorbeeld van commerciële beacons (sleutelhangers)

Ontvangen informatie door de scanner
Open op de smartphone een van de hierboven beschreven apps en zet het gesimuleerde beacon aan. Ik gebruik de app Beacon Toolkit, het mag natuurlijk ook een ander zijn.

Zodra het script BeaconScanner0.py opgestart is, zou je alle iBeacon- en Eddystone-apparaten in de buurt moeten zien. De RSSI (signaalsterkte) verandert als je het iBeacon beweegt.

Na het opstarten van de app zie je in de terminal in een rap tempo complexe datastring(s) herhaald binnen komen. Bijvoorbeeld deze:

{’type’: ‘iBeacon’, ‘uuid’: ‘dcd6e8ae-16f2-423d-b5a8-c224860d7112’, ‘major’: 44733, ‘minor’: 56144, ‘rssi’: -60, ‘macAddress’: ’77:e7:33:4b:6b:b9′}

De string bevat veel informatie. Ik leg de onderdelen even kort uit.

Type : iBeacon
Het signaal is herkend als een iBeacon.

UUID : dcd6e8ae-16f2-423d-b5a8-c224860d7112
De proximity UUID is een standaard 16byte/128bit BLE UUID en is uniek voor
een bedrijf. Het eerste gedeelte (‘dced6e8ae’) vertegenwoordigt een bedrijf, in dit geval RNF Digital Innovation.

Major : 44733
De waarde is een subset van bakens dat binnen een grote groep identificeert. Hier zijn 65.536
mogelijkheden, bijvoorbeeld winkels.

Minor : 56144
Een nummer dat een specifiek baken identificeert binnen de (Major) subset. Bijvoorbeeld 65.536 mogelijke tags per winkel.

RSSI : -60
Received Signal Strength Indicator (Indicator voor ontvangen signaalsterkte) is een
meting van hoe goed het apparaat een signaal ontvangt. Hoe hoger de RSSI-waarde, hoe beter het signaal. Meestal wordt het signaal sterker naarmate het beacon de scanner of ontvanger nadert.

MacAdres : 77:e7:33:4b:6b:b9
Dit is het (unieke) MAC-adres van het zendende apparaat. MAC staat voor “media access control” en wordt ook wel hardware-adres of fysiek adres genoemd. In dit geval een gesimuleerd (tijdelijk) MAC-adres van de smartphone met de specifieke app dat de simulatie van het beacon doet.

Let op! Het echte MAC-adres van je smartphone gebruiken maakt je kwetsbaar
Een MAC-adres kan gebruikt worden om je locatie te traceren. Wanneer je met een apparaat van het ene wifi-punt naar het andere gaat (bijvoorbeeld op een luchthaven), wordt je MAC-adres voortdurend uitgezonden om verbinding met nieuwe wifi-punten te kunnen maken.

Een hacker kan je MAC-adres gebruiken om zich als jou voor te doen en je inloggegevens stelen. Ze kunnen je MAC-adres met speciale software achterhalen, je verbinding verstoren en verbinding met hetzelfde wifi-netwerk maken.

Omgedraaid kunnen hackers hun eigen MAC-adres bovendien aan je IP-adres koppelen en zo een zogenaamde man in the middle-aanval uitvoeren. Om deze en andere redenen is het een goed idee om je IP-adres met een VPN te beschermen.

Het veiligst is daarom om voor deze tutorial een zgn. commercieel beacon aan te schaffen en niet je echte smartphone MAC-adres te gebruiken. Een gesimuleerd MAC-adres is natuurlijk prima, maar deze kan een tijdelijke geldigheid hebben, waarna deze ververst moet wordt.


Finse hulp
Een viertal studenten van de Haaga-Helia University of Applied Sciences in Helsinki – Finland dat zich in 2019 met IoT based projecten bezighield, heeft meerdere scriptvarianten van BeaconScanner.py via GitHub beschikbaar gesteld. Het ging hen erom dat je op basis van de gescande datastring acties kunt opstarten.

Hieronder kun je hun 12 variaties van BeaconScanner.py downloaden. Wil je er meer over weten verwijs ik je naar hun GitHub. Niet alle scripts werken even goed. Ook de programmering laat hier en daar te wensen over, maar ze kunnen een goede basis zijn om verder te ontwikkelen.

Wat wil ik bouwen?
Toen ik de 12 scripts doorgenomen had moest ik voor deze tutorial bepalen welk script ik wilde gebruiken en welke toepassing ik er ervoor zou hebben. Ik bedacht het volgende:

Ik wil dat de lamp bij mijn voordeur inschakelt zodra ik me met een beacon op een specifieke afstand (lees: signaalsterkte) mijn woning nader. Het script moet ook werken als mijn vrouw met haar eigen beacon de woning nadert.

Kijkende naar de 12 scripts van de Finnen, denk ik dat script BeaconScanner8 en BeaconScanner9 een prima basis zijn voor mijn vraag. BeaconScanner9 laat het MAC-adres en de RSSI zien voor één beacon. Het script BeaconScanner8 doet hetzelfde, maar dan voor 3 beacons.

BeaconScanner9
Ik heb wat aanpassingen gemaakt waardoor het script, nu versie BeaconScanner92, in de basis prima werkt. De led op GPIO17/pin11 laat ik gemakshalve nu knipperen totdat je het programma stopt met [Ctrl]-c.

Ik heb ervoor gekozen dat als het beacon met het unieke MAC-adres gescand wordt en een vooraf ingestelde signaalsterkte gedetecteerd wordt, er middels een ‘if’-statement een led-functie geactiveerd wordt.

Je zou de led alleen als het donker is voor een bepaalde tijd kunnen laten oplichten, maar dat maakt het script onnodig complex voor nu. Wel een leuk stukje huiswerk overigens!

Nogmaals: Afhankelijk van de app heeft het MAC-adres mogelijk een korte houdbaarheid (~10-15min) waarna deze wordt vernieuwd. Als je niet snel genoeg bent ben je steeds bezig met het instellen van het MAC-adres….. erg irritant! Weer een goede reden een commercieel beacon aan te schaffen.

Om te controleren of het script helemaal werkt zal je een led met een serieweerstand (~330Ω) op GPIO17/pin11 kunnen aansluiten. Vergeet ook niet om het beacon eerst op een flinke afstand (~2m) van de Raspberry Pi te houden, anders begint de led direct al op te lichten/knipperen. De triggerwaarde van de signaalsterkte (-50dBm) kan naar wens worden ingesteld.

Het script wordt gestart met het commando:

sudo python BeaconScanner92.py

import time
import ScanUtility
import bluetooth._bluetooth as bluez
import RPi.GPIO as GPIO

GPIO.setwarnings(False)
GPIO.setmode (GPIO.BOARD)
GPIO.setup (11,GPIO.OUT)
GPIO.output(11,False)

def ledKnipper():
    p=0.2
    while True:
        GPIO.output(11,True)
        time.sleep(p)
        GPIO.output(11,False)
        time.sleep(p)

# Stelt bluetooth device in. Raspberry Pi bluetooth is 0.
dev_id = 0

try:
        sock = bluez.hci_open_dev(dev_id)
        print ("\n *** Zoekt naar BLE Beacons ***\n")
        print ("\n *** Gebruik [CTRL]-c om te stoppen ***\n")
except:
        print ("STORING - Geen toegang tot bluetooth")

ScanUtility.hci_enable_le_scan(sock)

# Scant voor iBeacons
while True:
    returnedList = ScanUtility.parse_events(sock, 10)
    for item in returnedList:
        if item ["macAddress"] == "7b:43:6a:c1:db:79": # Vul MAC-adres beacon in!
            print("BEACON GEVONDEN")
            print("---------------")
            print("macAddress:",item ["macAddress"])
            print("rssi",item ["rssi"])
            if item["rssi"] >= -50:
                print ("\n\033[1;32mBeacon is minder dan op -50dB \033[1;m")
                print ("\033[1;33mDe led (GPIO17/pin11) knippert\033[1;m\n")
                print ("Gebruik [Ctrl]-c om het programma te stoppen")
                ledKnipper()
                break
            else:
                print ("\033[1;31mBeacon is op meer dan -50dB \033[1;m\n")

Herkenning op meerdere MAC-adressen
Hieronder kun je script BeaconScanner81 downloaden met dezelfde functionaliteit, maar nu met de mogelijkheid meerdere MAC-adressen in te voeren. Slechts een van de MAC-adressen hoeft herkend te worden om de GPIO te activeren.

Have A Nice Day!

Geef als eerste een reactie

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd.


*