PondCTRL – Live test #1

[iframe src="https://www.dennisbor.com/temporary/20190423_test1.php"]

Uiteindelijke conclusie na 24 uur testen:

PondCTRL was tijdens deze eerste test vrij stabiel. Met 98,92% geregistreerde meetwaarden durf ik deze eerste test vrij succesvol te noemen. Tijdens deze 24 uur is het eenmaal voorgekomen dat er een vreemde waarde uit de sensor gelezen werd, waardoor de hoogst gemeten waarde op 251,3°C uit kwam. Om foutieve sensorwaarden te filteren, zal ik in een update een filterfunctie schrijven, welke bij een afwijking van meer dan een bepaald percentage, de meting negeert.

Voorlopige conclusie na 10 uur testen:

Stabiele WiFi verbinding op ongeveer 15 meter tussen PondCTRL en router (RSSI van -78 dBm, signaalsterkte 44% *). De webinterface is toegankelijk en werkt naar behoren.

Er zijn totaal 98.73% aan meetwaarden naar de IoT-API gelogd. De software van PondCTRL is zo ingesteld dat er elke 5 seconden gelogd wordt. Meetresultaten laten zien dat de interval vrijwel altijd 5 seconden bedraagt, soms 4 of 6 (gemiddeld nog steeds 5 – kan te maken hebben met de vertraging naar de server) en een enkele keer 10 seconden (1 meetpunt wordt dan overgeslagen).

De test berekende de gemiddelde meetwaarde in eerste instantie onjuist. PondCTRL en de IoT-API werken met BCD (Binary Codec Decimals) waarbij middels een query het gemiddelde genomen werd (SELECT AVG). Dit is veranderd in een query waarbij alle meetwaarden opgehaald worden in de testperiode, waarna de som van alle waarden (geconverteerd van BCD naar normaal decimaal) gedeeld wordt door het aantal testpunten.

*) Berekening signaalsterkte is gebaseerd op de volgende formule: signaalkwaliteit = 2 * (dBm + 100)

Actiepunten volgende test

De volgende test wil ik als volgt uitbreiden:

  • Testsoftware op PondCTRL waarbij elke 30 seconden een relais geschakeld wordt, om de invloed van schakelen op het apparaat en eventuele storingen te testen.
  • Op elk van de drie relais een verbruiker aansluiten (bijvoorbeeld een lamp), zodat de invloed van stroomverbruik op het apparaat zichtbaar wordt.
  • Een separate test, waarbij het WiFi-bereik getest wordt. Het idee is om PondCTRL op een powerbank aan te sluiten en de signaalsterkte per afstand te registreren.
  • Test op stroomverbruik (watt), uiteraard zonder aangesloten verbruikers, om het verbruik van PondCTRL zelf te testen.

ESP8266 firmware: HTML requests

Laatst bijgewerkt op 26 maart 2019.

Dit document beschrijft de momenteel beschikbare HTML requests en de daarbij behorende waarden:

/findSlave

Methode: GET

Zoekt naar het eerst beschikbare (en compatibel) apparaat op de I2C bus en toont status, hardware-adres, aantal sensoren en aantal schakelbare stekkers of een foutstatus. De ESP fungeert als master en het andere apparaat (bijvoorbeeld een Arduino Uno) als slave.

Uitvoer:

  • status: “ok” indien gevonden, anders “no”
  • address: het hardware adres van het gevonden I2C-apparaat, waarbij waarden tussen 0-127 mogelijk zijn. Wordt alleen getoond bij status “ok”.
  • sensors: het aantal sensoren van het gevonden I2C-apparaat, waarbij waarden tussen 0 en 31 ondersteund worden. Wordt alleen getoond bij status “ok”.
  • outlets: het aantal schakelbare stekkers van het gevonden I2C-apparaat, waarbij waarden tussen 0 en 31 ondersteund worden. Wordt alleen getoond bij status “ok”.
{
"status":"ok",
"address":16,
"sensors":1,
"outlets":0
}

/getAdmin

Methode: GET

Toont de gebruikersnaam van de webinterface. Het wachtwoord wordt uiteraard om veiligheidsredenen niet getoond.

Uitvoer:

  • username: gebruikersnaam van de webinterface, standaard “admin”.
{
"username":"admin"
}

/setAP

Methode: POST

Stelt SSID en passphrase van het eigen access point in.

Het SSID wordt gecontroleerd op juistheid:

  • minimaal 2 en maximaal 32 karakters lang.
  • geen spaties aan begin of eind.
  • toegestane ASCII karakters zijn 32 t/m 126, met uitzondering van 34, 36, 43, 63, 91, 92 en 93 (“$+?[\]).
  • het eerste karakter mag niet gelijk zijn aan ASCII codes 33, 35 en 59 (!#;).

De passphrase wordt gecontroleerd op juistheid:

  • minimaal 8 en maximaal 63 karakters lang.
  • toegestane ASCII karakters zijn 32 t/m 126.
  • een lege passphrase wordt geaccepteerd en resulteert in een open netwerk.

Vereiste parameters:

  • ap_ssid: het gewenste SSID voor het access point.

Optionele parameters:

  • ap_passphrase: de gewenste passphrase voor het access point.

Uitvoer:

  • status: ‘ok’ indien de parameters geaccepteerd worden, anders ‘no’.
{
"status":"ok"
}

/getAP

Methode: GET

Toont de SSID van het eigen access point.
Het wachtwoord wordt uiteraard om veiligheidsredenen niet getoond.

Uitvoer:

  • ap_ssid: SSID van eigen access point
{
"ap_ssid":"DennisBor-IoT"
}

/getAPI

Methode: GET

Toont informatie over de verbinding met de DennisBor IoT API.

Uitvoer:

  • api_status: Verbindingsstatus met API (0 = Niet verbonden, 1 = Verbonden).
  • api_url: URL naar de API, standaard ‘api.dennisbor.com’.
  • api_key: sleutel waarmee API gegevensuitgewisseling tot stand gebracht kan worden.
  • api_secret: geheime code waarmee API gegevens opgeslagen kunnen worden op de server.
  • sha1_fingerprint: SHA1 sleutel van de API server.
  • sha1_bypass: er kan een bypass ingesteld worden om SHA1 verificatie over te slaan. (0 = veilig, 1 = bypass).
{
"api_status": 1,
"api_url": "api.dennisbor.com",
"api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"api_secret": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"sha1_fingerprint": "00 11 22 33 44 55 66 77 88
99 AA BB CC DD EE FF 00 11 22 33",
"sha1_bypass": 0
}

/setAPI

Methode: POST

Slaat de opgegeven instellingen voor verbinding met de DennisBor IoT API op. Er vindt controle plaats op lengte van API-key, API-secret en SHA1-fingerprint. Er vindt controle plaats op juistheid van het formaat van de SHA1-fingerprint. Indien er een fout optreedt, dan krijgt de uitvoer een extra parameter “errno”.

Vereiste parameters:

  • api_url: URL van de API server.
  • api_key: sleutel waarmee API gegevensuitgewisseling tot stand gebracht kan worden.
  • api_secret: geheime code waarmee API gegevens opgeslagen kunnen worden op de server.
  • sha1_bypass: er kan een bypass ingesteld worden om SHA1 verificatie over te slaan. (0 = veilig, 1 = bypass).

Optionele parameters:

  • sha1_fingerprint: SHA1 sleutel van de API server. Deze parameter is niet verplicht omdat er een bypass ingesteld kan worden.

Uitvoer:

  • status: ‘ok’ indien instellingen geaccepteerd worden, anders ‘no’. Let op dat, ook al worden instellingen geaccepteerd, dit niet wil zeggen dat er ook een verbinding tot stand gebracht kan worden. De verbindingsstatus kan opgevraagd worden met /getAPI. Indien status ‘no’, dan krijgt de uitvoer een extra parameter ‘errno’ met als waarde een foutcode.
{
"status": "ok"
}

of

{
"status": "no",
"errno": 5
}

Mogelijke foutcodes:

  • 1: Incomplete call. Er ontbreken verplichte parameters.
  • 2: Lengte API key onjuist. Lengte moet 32 karakters zijn.
  • 3: Lengte API secret onjuist. Lengte moet 32 karakters zijn.
  • 4: Lengte SHA1 fingerprint onjuist. De fingerprint kan opgegeven worden als string met of zonder scheidingstekens, waarbij als scheidingsteken een spatie of dubbele punt gebruikt mag worden. De lengte met scheidingstekens moet 59 karakters zijn of zonder scheidingstekens 40 karakters.
  • 5: SHA1 fingerprint bevat ongeldige tekens. De fingerprint mag alleen bestaan uit hexadecimale tekens (0-F).
  • 6: Onjuiste API URL of SHA1 fingerprint komt niet overeen met de fingerprint van de server.

/setWifi

Methode: POST

Probeert te verbinden met het opgegeven access point en stelt deze, indien gelukt, in als standaard. Indien de verbindingspoging mislukt, dan wordt teruggevallen op het laatst bekende netwerk.

Vereiste parameters:

  • ssid: SSID waarmee verbonden moet worden.
  • passphrase: passphrase van het te verbinden SSID.
  • connection_attempts: aantal verbindingspogingen alvorens teruggevallen wordt op access point modus.
  • mdns_hostname: multicast DNS hostname waarmee verbonden kan worden zonder IP-adres.

Uitvoer:

  • status: ‘ok’ indien parameters geaccepteerd worden, anders ‘no’. Deze status heeft niets te maken met of de verbindingspoging al dan niet geslaagd is. Doordat de verbinding tijdelijk verbroken wordt door het wisselen van access point is het onmogelijk naderhand uitvoer te geven.
{
"status":"ok"
}

/getWifi

Methode: GET

Toont de instellingen van het access point waarmee verbinding wordt gemaakt. Het wachtwoord wordt uiteraard om veiligheidsredenen niet getoond.

Uitvoer:

  • ssid: SSID waarmee verbinding wordt gemaakt.
  • connection_attempts: maximaal aantal verbindingspogingen alvorens overgeschakeld wordt naar stand-alone modus (de ESP fungeert dan zelf als access point).
  • mdns_hostname: mDNS (multicast DNS) hostname die gebruikt kan worden om verbinding te maken zonder het IP adres te weten.
{
"ssid":"DennisBor-IoT",
"connection_attempts":25,
"mdns_hostname":"dennisbor_iot"
}

/listWifi?performscan=true

Methode: GET

Zoekt naar beschikbare WiFi netwerken en toont het aantal gevonden netwerken. De reden dat niet direct alle netwerkgegevens getoond worden, is dat de ESP8266 beschikt over een zeer beperkt geheugen. Wanneer er een groot aantal netwerken gevonden zou worden, zou dit na genereren van een grote JSON-string resulteren in een crash.

Uitvoer:

  • count: het aantal gevonden WiFi netwerken.
{
"count":15
}

Na deze functie kan ‘/listWifi?getnetwork=<index>’ aangeroepen worden, om per netwerk informatie te laden.

/listWifi?getnetwork=<index>

Methode: GET

Toont informatie van het opgegeven netwerk. Netwerken worden geïdentificeerd met nummers, waarbij het eerste nummer index 0 krijgt. Bij een netwerkaantal van 15 zijn indices 0-14 toegestaan. Deze functie kan pas aangeroepen worden na ‘/data_listwifi?performscan=true’.

Uitvoer:

  • ssid: SSID van gevonden netwerk
  • channel: netwerkkanaal van gevonden netwerk
  • rssi: RSSI (Received Signal Strength Indicator) ofwel signaalsterkte van gevonden netwerk.
  • security: beveiligingsmethode van het gevonden netwerk (2 = WPA, 4 = WPA2, 5 = WEP, 7 = open netwerk, 8 = WPA2)
{
"ssid":"DennisBor",
"channel":11,
"rssi":-52,
"security":4
}

/login

Methode: POST

Probeert in te loggen aan de hand van opgegeven POST-gegevens en zal, afhankelijk van of inloggen gelukt is, pagina index.html laden of anders een ‘401: unauthorized’ foutmelding geven.

Vereiste parameters:

  • username: gebruikersnaam van de webinterface
  • password: wachtwoord van de webinterface

Deze functie heeft geen uitvoer.

/logout

Methode: GET

Logt de gebruiker uit, waarna pagina login.html geladen wordt.

Deze functie heeft geen uitvoer.

/status

Methode: GET

Toont statusinformatie van de ESP8266 module.

Uitvoer:

  • mode: verbindingsmodus (client: verbonden met het opgegeven netwerk of ap: access-point).
  • ssid: in client-modus het SSID van het netwerk waarmee verbonden is of in het geval van AP-modus de eigen netwerknaam.
  • ip: IP-adres van de module. In clientmodus wordt hier het verkregen IP-adres getoond of in AP-modus het eigen IP-adres (altijd 192.168.4.1).
{
"mode": "ap",
"ssid": "https://www.dennisbor.com",
"ip": "192.168.4.1"
}

ESP8266 programmeren

Om de ESP8266 te programmeren gebruik ik een programmer. Deze programmer heb ik via jumpwires verbonden met een breadboard-adapter waarin de ESP8266 gestoken wordt.

Waarom deze constructie? Ten eerste gebruik je bij prototypen veelal een breadboard en door de pinout van de ESP kun je hem onmogelijk direct in een breadboard steken. De ESP8266 past natuurlijk wel direct in de programmer, maar om te kunnen programmeren zijn de volgende zaken belangrijk:

  • Om de ESP8266 te kunnen programmeren dienen GND en GPIO0 verbonden te zijn.
  • Om te kunnen uploaden dien je kort GND en TX te verbinden.

De verbinding tussen GND en GPIO0 is makkelijk met een jumpwire te maken. De verbinding tussen GND en TX heb ik door middel van een pushbutton gemaakt. Even indrukken en uploaden maar!

Arduino IDE en ESP8266

De Arduino IDE is een mooi hulpmiddel om de ESP8266 te programmeren echter dien je hiervoor nog wel de nodige aanpassingen te maken.

De eerste stap omvat het installeren van de Arduino IDE, waarbij de Windows-versie te downloaden is vanaf deze site:

https://www.arduino.cc/en/main/software

ESP8266 Board Drivers en libraries

Standaard kent de IDE het ESP8266 board nog niet. Om deze toe te voegen ga je eerst naar ‘Bestand’ > ‘Voorkeuren’ en vul je onder ‘Additionele Board Beheer URLs’ de volgende URL in:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Ga nu naar ‘Hulpmiddelen’ > ‘Board xxx’ > ‘Board beheer…’ en vul de zoekterm ‘ESP8266’ in. Klik op board ‘esp8266 by ESP8266 Community’, selecteer de meest recente versie en klik op ‘Installeren’.

ArduinoJSON

JSON (Javascript Object Notation), een gestandaardiseerd gegevensformaat, wordt tegenwoordig gebruikt door veel API’s. Mijn firmware maakt ook gebruik van JSON en dus dienen we ook deze library te installeren. Download de library vanaf:

https://esp8266.dennisbor.com/ArduinoJson-v5.13.4.zip

Laad de library via ‘Schets’ > ‘Bibliotheek gebruiken’ > ‘.ZIP bibliotheek toevoegen’.

ESP8266 instellingen

Er zijn verschillende ESP8266 modules waarbij ook de instellingen anders zullen zijn. Voor de in mijn vorig bericht genoemde module zijn de instellingen als volgt:

  • Board: Generic ESP8266 module
  • Flash size: 1M (128K SPIFFS)
  • Upload speed: 115200

Het poortnummer is afhankelijk van de computerconfiguratie, maar zorg er uiteraard voor dat er achter ‘Poort’ wel een poortnummer gekozen wordt.

SPIFFS

SPIFFS, Serial Peripheral Interface Flash File System, is simpelweg een bestandssysteem. De ESP8266 heeft een klein stukje (128kb) beschikbaar voor het opslaan van bestanden. Mijn firmware gebruikt deze ruimte voor het opslaan van oa. de Html-bestanden van de webinterface. Om de IDE naar het SPIFSS te kunnen laten schrijven dien je de volgende plug-in te installeren:

https://esp8266.dennisbor.com/ESP8266FS-SPIFFS-0.2.0.zip

Installeren doe je door de map ‘ESP8266FS’ uit het ZIP-bestand te kopiëren naar de ’tools’-map van de Arduino IDE (in Windows veelal ‘C:\Program Files (x86)\Arduino\tools’). Je dient de IDE te herstarten om de plug-in te laden.

ESP8266 Firmware

Om mijn DIY projecten te voorzien van internetfunctionaliteit voor onder andere besturing en vastleggen van gegevens, ben ik begonnen met het schrijven van aangepaste firmware voor de ESP8266 WiFi module.



De ESP8266 is niet groter dan een euromunt en kost niet meer dan een paar euro: uitstekend voor elk project.

De module kan gemakkelijk met een programmer van eveneens een paar euro geprogrammeerd worden vanuit bijvoorbeeld het Arduino IDE.

Wat moet mijn firmware kunnen?

  • De module gedraagt zich als WiFi hotspot wanneer er geen verbinding is met een Access Point.
  • De module moet verbinding kunnen maken met Access Points met alle op dit moment voorkomende soorten beveiliging.
  • De module moet in te stellen zijn via een intuïtieve gebruikersinterface zonder te veel poespas.
  • De gebruikersinterface dient beveiligd te zijn en door één gebruiker gelijktijdig te openen.
  • De module moet kunnen communiceren via het I2C protocol.
  • De module moet gegevens uit kunnen wisselen met een IoT API op het internet welke ik ook zelf zal schrijven.

Wat kan de firmware op dit moment?

De module start op als open Access Point met SSID ‘DennisBor-IoT’ en is na verbinding door middel van een mDNS (multicast DNS) hostname (dennisbor-iot.local) of IP-adres (192.168.4.1) te bereiken.

Na inloggen met de standaardgegevens wordt de verdere webinterface getoond waarin verbinding gemaakt kan worden met gevonden netwerken. Zowel de firmware als interface zitten nog vol met bugs en daar zal ik de komende tijd dan ook aan gaan werken. I2C verbinding is nog helemaal niet geïmplementeerd.

Open source

Deze artikelen zijn een project-dagboek waarin ik broncode en vorderingen zal delen en wat ook als naslagwerk gebruikt kan worden. Broncode mag vrij gedownload en gewijzigd worden.