MQTT Onderwerpboom Ontwerp beste praktijken, tips & voorbeelden
Generieke MQTT Achtergrond
Met MQTT zijn verzender en ontvanger zich niet van elkaar bewust - de broker zorgt voor de berichtgeving. Hierdoor kunnen de berichten worden gescheiden in ruimte, tijd en intensiteit. De verzender kan verzenden met de snelheid die hij wil en de tijd die hij wil. De ontvanger kan de berichten ophalen met de snelheid en de tijd die hij wil. De verzender en ontvanger hoeven elkaar niet te kennen, en er hoeft geen directe route tussen hen te zijn (zoals het geval zou zijn bij bijvoorbeeld een telefoonlijn). MQTT maakt het mogelijk om gemakkelijk multicast opstellingen te ontwerpen - waarbij één zender naar veel geabonneerde ontvangers kan zenden.
- Cliënten weten niet wie het bericht oorspronkelijk heeft gepubliceerd - tenzij het duidelijk is uit het onderwerp (en mogelijk afgedwongen op de makelaar door ACL's), of uit de inhoud van het bericht (mogelijk ondertekend met HMAC)
- MQTT is ontworpen voor low-power, low-latency communicatie (HMAC etc. kan duur zijn)
- Je kunt geen lijst van alle onderwerpen van een broker krijgen. De makelaar verwijdert berichten (en onderwerpen) waarop niemand is geabonneerd (mogelijk alleen volledig waar als de bewaarvlag niet is ingesteld)
- U weet niet wie geabonneerd is op een onderwerp (gebruik ACL's om abonnementen van niet-geautoriseerde clients te beperken)
laatste wil en testament / in leven houden
De cliënten kunnen verbinding maken, een bericht publiceren en de verbinding verbreken, of een persistente verbinding met de server houden. In het geval van een persistente verbinding zullen keep-alives worden verstuurd. Als de client geen keep-alives verstuurt binnen het tijdsbestek dat is overeengekomen tijdens het opzetten van de verbinding, kan de server (broker) een zogenaamd "last-will and testament"-bericht sturen, dat de client heeft ingediend tijdens het opzetten van de verbinding. Dit bericht kan van alles zijn en kan worden gepubliceerd naar één enkel onderwerp per verbinding. De makelaar zal het naar alle klanten sturen die op dit onderwerp geabonneerd zijn.
Als de cliënt de verbinding netjes verbreekt, zal de laatste wil en testament niet worden gepubliceerd.
De keep alive is vooral nuttig voor mobiele clients, waar de verbinding verbroken kan worden (b.v. door slecht netwerk, tunnels, enz.)
Zie ook:
http://www.steves-internet-guide.com/checking-active-mqtt-client-connections/
http://www.steves-internet-guide.com/mqtt-last-will-example/
https://owntracks.org/booklet/tech/mqtt/
Klant ID / Klant overname
Elke client die verbinding maakt met een MQTT-broker moet een uniek client-id hebben. Clients die een verbinding maken met hetzelfde client-id doden de vorige verbinding en nemen de nieuwe over. Als je twee clients hebt met hetzelfde client-id, kan dit leiden tot een ping-pong van verbroken verbindingen.
Behouden berichten
De laatste behouden bericht aan een onderwerp wordt opgeslagen en afgeleverd aan alle nieuwe abonnees van dit onderwerp. Dit kan worden gebruikt voor het communiceren van de apparaatstatus / configuratie / enz.
U stelt de behouden toestand in als een vlag per bericht.
Bewaarde berichten kunnen voor vele interessante dingen worden gebruikt, b.v. om auto-discovery te vergemakkelijken (zie suggestie 4 hieronder).
Kwaliteit van de dienst / QoS
Er zijn drie niveaus van kwaliteit van dienstverlening, die bepalen hoeveel overhead tijdens de verwerking van een bericht wordt ondervonden. Hoe hoger het niveau, hoe meer overhead.
- 0: geen enkele garantie
- 1: het bericht wordt ten minste eenmaal verzonden (duplicaten mogelijk)
- 2: het bericht wordt precies één keer verzonden (geen duplicaten mogelijk)
QoS kan worden ingesteld per bericht dat naar de makelaar wordt gestuurd, en tijdens de inschrijving. De laagste van de twee waarden zal worden gebruikt voor de daadwerkelijke aflevering van het bericht.
Kijk hier eens naar voor meer details:
https://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/qos.html
Onderwerpen
Feiten over onderwerpen
Onderwerpnamen zijn hoofdlettergevoelig, en UTF-8 strings. Het is raadzaam u te beperken tot afdrukbare ASCII-tekens om debugging te vergemakkelijken.
Onderwerpnamen moeten uit ten minste één teken bestaan om geldig te zijn.
/
is al een onderwerpsnaam
De $SYS onderwerp is voor makelaar gebruik / statistieken.
Je hebt de keuze om de informatie in de topicstructuur te plaatsen, of om ze in het bericht te plaatsen. Een JSON-structuur voor het bericht zal u helpen om het te kunnen uitbreiden met verdere gegevens.
Bedenk dat bij elke oproep aan de broker, elke publicatie van het onderwerp meegestuurd zal worden in de payload van het MQTT pakket - probeer daarom onnodige lengte te vermijden.
Overweeg het gebruik van wild cards
- # komt overeen met alles voor een willekeurige niveaudiepte vanaf het huidige niveau (jokerteken op meerdere niveaus, kan alleen aan het eind worden ingevoegd)
- + komt overeen met alles op het huidige niveau (jokerteken op één niveau)
Bv. als je meerdere temperatuursensoren hebt, zou je je gemakkelijk kunnen abonneren op berichten voor hen allemaal als je je topic tree correct ontwerpt.
Wild cards zijn alleen voor intekenaars, ze zijn niet toegestaan voor publicatie.
U kunt zich abonneren op alle onderwerpen met #
behalve het $SYS onderwerp. Gebruik $SYS/# om u te abonneren op alle onderwerpen voor $SYS
Mogelijk kunt u zich gemakkelijker op bepaalde kanalen abonneren als u het "functie"-gedeelte vóór de apparaatidentificatie gebruikt.
Bijvoorbeeld, als u uw paden definieert als tele/kamer1/sensorname1 tele/kamer2/sensorname2 enz. en stat/room1/sensorname1 stat/room1/sensorname2 abonnementen zijn mogelijk op:
tele/#
stat/#
Als je het andersom doet, met sensor1/stat en sensor2/statenz. kunt u gebruik maken van
+/stat
om zich te abonneren op statistieken, maar zal niet overeenkomen in willekeurige diepte zoals in het vorige voorbeeld. Dat wil zeggen, het pad naar je sensor moet uit precies één component bestaan.
Op die manier, als je de actie voorvoegt, zullen je paden meer consistent zijn.
Zie bijvoorbeeld https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch/
Niet doen.
- Gebruik geen voorloopschuine streep (bv. /mytopics ) om je topic tree te starten - het voegt overhead toe, geen waarde
- Niet gebruiken $SYS als het startonderwerp, dit is gereserveerd voor de makelaar
- Gebruik geen spaties in het onderwerp
- Gebruik geen niet-afdrukbare tekens in het onderwerp
- gebruik één MQTT onderwerp voor berichten met verschillende betekenis - maak er verschillende onderwerpen voor aan
Suggesties / Doen
- de client-id in de onderwerpenboom insluiten
- maak specifieke onderwerpen voor individuele adressering (b.v. van sensoren), in plaats van alle waarden over één onderwerp te zenden - zo wordt vermeden dat berichten worden gestuurd naar ontvangers die ze niet nodig hebben
- probeer de onderwerpnamen kort te houden (aangezien ze bij elke publicatie en elk bericht zullen worden meegestuurd)
- overwegen welke gegevens hoe vaak moeten worden verzonden
o bv. overwegen om metadata in een eigen onderwerp onder te brengen en te publiceren met een "bewaar"-vlag
- scheid commando/cmd en status topics voor een apparaat - op deze manier is bidirectionele communicatie mogelijk, en hoeft het apparaat niet te filteren op zijn eigen berichten.
- een laatste wil en testament bericht gebruiken om een onverwachte klantverbreking aan te geven
Overweeg multi-tenancy en overbrugging
Moet je meerdere clients / organisaties / onafhankelijke applicaties ondersteunen? Er is de mogelijkheid om, bijvoorbeeld met VerneMQ, verschillende mountpoints te gebruiken. Een ander alternatief is om multi-tenancy op te nemen in je topic tree (door een gepaste prefix te gebruiken aan het begin van de topic tree).
Ik geef de voorkeur aan de eerste weg, omdat die een extra laag ACL-scheiding oplevert - en minder kans om "de boel te verpesten".
Daarnaast is het mogelijk dat je verschillende MQTT brokers met elkaar wilt verbinden, waarbij je een deel van hun topic trees (zoals gedefinieerd door hun ACL's) deelt.
Zie deze https://owntracks.org/booklet/guide/bridge/ voor meer informatie over overbrugging.
Overweeg encryptie
MQTT kan worden uitgevoerd over versleutelde netwerken (b.v. over websockets / TLS versleuteld) of over onversleutelde kanalen. Daarnaast kun je overwegen om de payload van je gegevens te versleutelen en/of te ondertekenen.
Denk aan vindbaarheid
Overweeg onderwerpen in te bouwen die de vindbaarheid van diensten en mogelijkheden van uw apparaten bevorderen, bijvoorbeeld door gebruik te maken van bewaarde berichten.
Denk na over feedback over commando's
Wanneer je een commando publiceert, heb je niet onmiddellijk een back channel. Daarom kan het nuttig zijn een hiërarchie op te zetten voor specifieke feedback over specifieke commando's - of het apparaat het commando heeft ontvangen en heeft kunnen uitvoeren, om feedback te kunnen geven aan de gebruiker.
Een patroon dat ik hier dacht toe te passen was het geven van unieke commando ids als deel van de boodschap payload, waarnaar verwezen wordt in het feedback kanaal met een status code.
Overweeg multicast scenario's
Wilt u dat meerdere apparaten reageren op een enkel bericht dat u publiceert? Vergeet niet dat je niet kunt publiceren naar wildcard onderwerpen - alleen op hen abonneren. In dit geval moeten bijkomende topics aangemaakt worden die de clients toelaten te reageren op multicast scenario's. Alle clients / alle clients van een bepaalde groep zouden zich abonneren op het multicast onderwerp en reageren op de berichten.
Als je dit combineert met mijn feedback / verwijzing naar commando id suggestie hierboven, wordt een nieuwe eis van client id als payload geïntroduceerd op het (generieke) feedback kanaal. Een andere mogelijkheid is om de apparaten te laten antwoorden op hun individuele feedbackkanalen - waar de apparaat-id al deel uitmaakt van het pad. (Dat wil zeggen, zij ontvangen een commando op het multicastpad, maar antwoorden in hun eigen exclusieve berichtonderwerphiërarchie).
Rekening houden met verkeer en privacy, Sensortypes
Als u een commercieel systeem gebruikt, bijvoorbeeld voor het verzamelen van sensorgegevens voor gebruikers, willen zij misschien tot op zekere hoogte kunnen bepalen welke sensorwaarden überhaupt worden gepubliceerd.
Bovendien zal het automatisch publiceren van alle sensorwaarden het verkeer en de belasting van uw server(s) doen toenemen.
Daarom is het simpelweg pushen van alle beschikbare sensorwaarden naar je MQTT-broker misschien niet de beste keuze. Een mogelijkheid is om een behouden onderwerp aan te maken, met een configuratie waarop de client zich kan abonneren. Wanneer de client verbinding maakt, ontvangt hij automatisch de configuratie op het vastgehouden onderwerp, en kan hij de waarden die hij publiceert aanpassen aan de configuratie. Bovendien kan hij reageren op wijzigingen in de configuratie door te reageren op eventuele aanvullende berichten die op dit configuratie-onderwerp aankomen.
Bovendien is het belangrijk te bedenken dat er verschillende soorten sensoren bestaan. Voor een deursensor zou je bijvoorbeeld geïnteresseerd zijn in een statusverandering (gesloten vs. open), terwijl je bij een temperatuursensor misschien continue waarden zou willen ontvangen. Het is belangrijk voor uw ontwerp om te overwegen wat voor waarden de abonnees zullen ontvangen wanneer de client die verantwoordelijk is voor de sensormetingen de verbinding verbreekt. Vergeet niet dat u een laatste wil & testament slechts op één onderwerp kunt instellen (voor multi-sensor apparaten). In het geval van een verbroken verbinding kunnen bewaarde berichten een verkeerde indruk geven (b.v. dat de deur open is terwijl hij in werkelijkheid gesloten is, maar niet is bijgewerkt, enz.)
Anderzijds, indien bijvoorbeeld uw webinterface die de client bestuurt pas wordt verbonden nadat de deursensor-client enige tijd verbonden is geweest, en u niet-bewaarde berichten gebruikt, zal het bericht van de laatste bijwerking van de deurstatus worden gemist;
Er zijn hier twee mogelijkheden:
- actief te verzoeken om een update van de deurstatus (door bijvoorbeeld uw eigen get topic te gebruiken)
- gebruik te maken van bewaarde berichten, en webinterface client-side logica te gebruiken om de laatste waarde te negeren voor het geval de client zelf niet verbonden is / markeer het als oudbakken
De gebruiker moet er in ieder geval van op de hoogte worden gebracht of een sensorwaarde kan worden vertrouwd, dan wel of deze mogelijk onjuist is als gevolg van een losgekoppelde sensor-cliënt.
Zie ook http://www.steves-internet-guide.com/mqtt-sensors-traffic-observations/
- Steve merkt op dat het combineren van sensorgegevens van verschillende sensoren in een JSON-gecodeerde payload het verkeer niet vermindert, maar zelfs licht kan doen toenemen (in vergelijking met een niet-gecodeerde payload!)
semantisch vs. fysiek onderwerp pad
dingen die betekenisvol zijn voor een mens creëren de topic structuur: ("semantische benadering")
huis/badkamer/vochtigheid
apparaatpaden (aan welke apparaten zijn de sensoren gekoppeld, hoe worden ze aangesproken?) de themastructuur creëren: ("fysieke aanpak")
pi/00000234898324734/i2c/10/pressure
(de getallen symboliseren respectievelijk het seriële BCM- en het I2C-adres).
opnieuw publiceren
In dit idee zou u beide benaderingen combineren, en een extra dienst creëren die tussen de twee werelden vertaalt.
Zie: https://tinkerman.cat/post/mqtt-topic-naming-convention
Overzicht van online ontwerpvoorstellen
Suggestie 1: Frambozen-Vallei
van: https://raspberry-valley.azurewebsites.net/MQTT-Topic-Trees/
apparaat-categorie/device-id/payload-context/payload-differentiator
- apparaat-categorie: bijv. "pi", "arduino", enz.
- apparaat-id: b.v. BCM serieel
- payload-context: b.v. temperatuur
- payload-differentiator: b.v. front / back (toevoeging van een meetniveau voor een bepaalde context)
Let op de symmetrie tussen device-category/device-id en payload-context/payload-differentiator (generiek-> specifiek; generiek -> specifiek)
Suggestie 2: Steve
(Door Steve): http://www.steves-internet-guide.com/mqtt-topic-payload-design-notes/
U kunt de volgende items in uw onderwerpenboom opnemen:
- hulpmiddelen voor het groeperen van onderwerpen op hoog niveau
- toegewezen sensornaam
- functie (b.v. set / status / get / cmd )
Steve's aanpak:
- gebruik een onderwerpnaam voor een individueel apparaat (bijv. een sensor)
- gebruik payload / JSON gegevens voor attributen van deze sensor
- gebruik een apart onderwerp voor gegevens en commando's
Suggestie 3: MQTT-Smarthome
MQTT Smarthome voorstel
https://github.com/mqtt-smarthome/mqtt-smarthome
een pad ziet er in dit voorstel zo uit:
toplevelnaam/functie/item
knxgateway1/status/Keuken/Lichten/Voor links
- eerste niveau (knxgateway1) = toplevelname, de concrete gateway die wordt aangesproken
- voor meerdere gelijksoortige gateways moet deze naam instelbaar zijn om botsingen in de namespace te vermijden
- tweede niveau (status) = functie
- derde niveau, en verdere niveaus -> individuele adreshiërarchie van de specifieke gateway (item)
Het interessante zijn de functies, en hun positie voor de diepere paden (denk aan de wild cards voor abonnementen - zo kunt u zich gemakkelijk abonneren op alle apparaatstatusrapporten)
Beschikbare / gedefinieerde functies in dit voorstel:
- status - om statusrapporten te krijgen
- set - voor het aanvragen van toestandsveranderingen
- get - (optioneel) voor het actief aanvragen van een statusupdate (voor gateways die dit ondersteunen)
- het resultaat van het lezen zal worden gepubliceerd aan de status hiërarchie.
De daaropvolgende hiërarchieën voor de afzonderlijke werkwoorden moeten met elkaar overeenstemmen, zodat u hetzelfde apparaat / knooppunt / parameter zou aanspreken.
Er is een speciaal onderwerp "verbonden" per gateway, dat de cliënt in staat stelt een laatste wil & testament bericht in te stellen
toplevelnaam/verbonden
eenvoudige waarden zijn gedefinieerd voor dit onderwerp:
- 0 = losgekoppeld van broker (ingesteld als laatste wil)
- 1 = verbonden met MQTT, losgekoppeld van hardware
- 2 = verbonden met MQTT en hardware (volledig operationeel)
Merk op dat de waarde 0 geen onderscheid maakt tussen vrijwillige verbrekingen van de verbinding of een verbroken verbinding (waarbij de keep-alives uitgetimed zijn).
Er zijn ook suggesties voor de lading:
JSON-codering van de payload is facultatief.
In het geval van JSON codering, zal de waarde altijd in de sleutel "val" staan. Bovendien,
ts : tijdstempel (tijdstempel, milliseconden sinds tijdperken)
lc : laatste verandering van waarde (tijdstempel, milliseconden sinds Epoch)
Suggestie 4: Tinkerman
https://tinkerman.cat/post/mqtt-topic-naming-convention
overweeg of u een "semantische" aanpak wilt (bv. dingen die van betekenis zijn voor mensen) of een "fysieke" aanpak (bv. feitelijke apparaatpaden waarop uw systeem is aangesloten).
De fysieke benadering is machinevriendelijker.
(Merk op dat Tinkerman's en mijn begrip van mountpoints en hun gebruik afwijken - voor mij zijn mountpoints volledig gescheiden topic trees, bv. voor multi-tenancy)
Metagegevens kunnen worden gecodeerd als postfix-paden.
b.v.
/home/bedroom/temperature -> 21
/home/bedroom/temperature/units -> °C
/home/bedroom/temperature/timestamp -> 2012-12-10T12:47:00+01:00
Opmerking: aangezien het onwaarschijnlijk is dat de eenheden en sommige andere metagegevens zullen veranderen, kunnen zij als behouden onderwerpen worden verzonden.
Een interessant onderdeel van deze suggestie is ook de aggregatie (apparaatzijde):
/home/bedroom/temperature/last -> laatste temperatuurwaarde
/home/bedroom/temperature/last/timestamp
/home/bedroom/temperature/last24h/max -> maximum waarde in de laatste 24h
/home/bedroom/temperature/last24h/max/timestamp -> tijdstempel waarop de temperatuur zo hoog was
/home/bedroom/temperature/last24h/min
/home/bedroom/temperature/ever/max -> de absoluut hoogste temperatuur ooit gemeten
Ook hier zouden deze waarden kunnen worden ingesteld als bewaarde onderwerpen (specifiek "ooit") om netwerkverkeer te besparen - het ontvangende systeem zou oudere bewaarde waarden kunnen weggooien (indien de sensor is losgekoppeld, zoals zou moeten blijken uit een ander onderwerp - mogelijk ingesteld door laatste testament & testament), of het systeem zou ze kunnen tonen als "oude" waarden.
Dit is een interessant ontwerp (voor de aggregatie), en zou als inspiratie kunnen dienen om dit soort flexibiliteit toe te staan.
Suggestie 5: Homie IoT Conventie
Home IoT is gericht op de vindbaarheid van nodes in de IoT Home Automation omgeving. Homie maakt geen gebruik van JSON-gecodeerde berichten, maar van een directe weergave van de payload voor elk knooppunt. Zie dit voorbeeld:
Homie definieert een strikte tekensubset die je mag gebruiken om je nodes een naam te geven, aangezien speciale tekens (bijv. $ en de underscore _) voor speciale doeleinden worden gebruikt.
Het definieert datatypes, die als (bewaarde) metadata ("attributen") bij $datatype van de individuele eigenschap worden gepubliceerd (zie hieronder voor de definitie van eigenschap):
- String
- Integer
- Vlotter
- Booleaans
- Enum
- Kleur
(let op het gebruik van de $ om speciale onderwerpen te markeren).
Laatste wil wordt gebruikt om het apparaat als verloren te markeren:
homie/deviceID/$state -> verloren
Homie definieert 6 mogelijke staten voor het apparaat:
- init -> het apparaat heeft verbinding gemaakt met MQTT, maar nog niet alle noodzakelijke Homie-berichten gepubliceerd
- klaar -> het apparaat is aangesloten en klaar met instellen - alle noodzakelijke berichten zijn verzonden
- losgekoppeld -> het apparaat is op een nette manier losgekoppeld
- slapen -> zelfbeschrijvend
- verloren -> het apparaat is onverwacht losgekoppeld (ingesteld bij laatste wil & testament)
- alert -> het apparaat is verbonden, maar er is iets mis, er is menselijke tussenkomst nodig
Homie raadt aan om QoS 1 (aangezien de aard van Homie het veilig maakt voor dubbele berichten).
Een voorziening voor uitbreidingen wordt gemaakt met behulp van een omgekeerde domeinnaam syntaxis, bijv. org.mycompany.homie-extension
knooppunten en apparaten
In Homie-parlance, een apparaat is de basis hardware eenheid. Bijvoorbeeld, een Raspberry Pi, een koffiezetapparaat, een auto.
A knooppunt is een logische, onafhankelijke eenheid van het apparaat. Een auto kan bijvoorbeeld een knooppunt wielen, een knooppunt motor en een knooppunt verlichting hebben.
eigenschappen vertegenwoordigen basiskenmerken van het knooppunt/apparaat. Een auto, bijvoorbeeld, zou een "snelheid" en een "temperatuur" eigenschap kunnen hebben voor het motorknooppunt. De eigenschappen kunnen behouden en/of instelbaar zijn.
- Vastgehouden + niet instelbaar: b.v. temperatuursensor
- behouden + instelbaar: node kan een eigenschap publiceren en commando's ontvangen voor de eigenschap (bv. lampvermogen)
- niet-vastgehouden + niet-instelbaar: bv. een deurbel (kortstondige gebeurtenissen)
- niet-behouden + instelbaar: knooppunt kan commando's ontvangen voor de eigenschap, bv. koffie zetten
attributen:
de attributen zijn belangrijk voor Homie autodiscovery, ze worden gespecificeerd, en beginnen met een $ om hun bijzondere betekenis aan te geven / botsingen te vermijden. Ze worden gebruikt om metadata op te slaan en bij te werken.
Bijvoorbeeld, het apparaat publiceert een behouden bericht op
homie/apparaat-ID/$nodes
met een door komma's gescheiden lijst van de knooppunten. Om aan te geven dat een node een array is (kan worden gebruikt om b.v. voor- en achterlichten in een auto te groeperen), wordt de naam gespecificeerd met rechthoekige haakjes aan het eind, b.v.
lampen[]
Een voorbeeld voor de subboom apparaat-id:
Homie specificeert verschillende statistieken voor het apparaat vanuit de doos, de meeste zijn optioneel (behalve de uptime). Bijvoorbeeld:
Met knooppunten wordt opnieuw autodiscovery mogelijk gemaakt voor eigenschappen, door ze te specificeren in het $properties attribuut:
Op die manier hoeft u, als abonnee, niet alle evenementen te raden/abonneren - u kunt zich selectief abonneren op de evenementen die voor u van belang zijn.
In Homie worden de metadata (attributen) gepubliceerd als een achtervoegsel bij het pad. Bijv. voor een bepaalde eigenschap:
Controle in Homie
Homie is op status gebaseerd. Dit betekent dat je niet "het licht aanzet", maar de voedingstoestand van een apparaat instelt op "aan".
dan werkt het apparaat zijn vermogenstoestand bij om te melden dat het commando is uitgevoerd:
Uitzending
alert is een arbitraire keuze - de uitzending kan naar elk ander onderwerp gaan, waar de apparaten op kunnen filteren. De berichten worden uitgezonden naar alle apparaten - de apparaten kunnen reageren als ze dat willen.
Dit is de meest complete specificatie die ik in mijn online onderzoek heb kunnen vinden. Persoonlijk vind ik het een zeer elegant ontwerp.
Lees meer:
https://homieiot.github.io/specification/
Suggestie 6: Eigen tracks
https://owntracks.org/booklet/tech/json/
http://owntracks.org/booklet/guide/topics/
Owntracks is een Open Source applicatie, waarmee je je eigen fysieke locatie kunt volgen, om te delen met vrienden, etc. De locatie wordt gepubliceerd via HTTP of MQTT, idealiter aan uw eigen makelaar.
" Het kan ook detecteren wanneer u een bepaald gebied binnenkomt of verlaat waarvoor u een zogenaamd waypoint instelt. Mensen gebruiken dit bijvoorbeeld om een aspect van hun huisautomatiseringssysteem te bedienen. (Heeft iedereen het huis verlaten? Dan kunnen we de lichten uitdoen.)"
Als u meer wilt lezen over OwnTracks, ga dan naar deze website: https://owntracks.org/booklet/
Over het owntracks onderwerp ontwerp:
https://owntracks.org/booklet/guide/topics/
"De principes tijdens het ontwerp van het OwnTracks topic-noemingsschema waren
- menselijke leesbaarheid
- verkeersminimalisatie
- granulaire toegangscontrole
“
Basisonderwerpnaam (andere zijn mogelijk):
owntracks/peter/iPhone
hier is owntracks een prefix, om andere toepassingen zonder botsingen op de MQTT-broker toe te laten.
peter is de eigenaar van opsporingsapparatuur, en iPhone is een van zijn apparaten.
commando's naar apparaten worden verzonden op: owntracks/peter/iPhone/cmd
de uitvoer van de commando's wordt gepubliceerd, b.v. naar relatieve onderwerpsnamen stap, dump enz.
enkele andere onderwerpen worden gedefinieerd (info, waypoint, gebeurtenis). Gebeurtenissen worden gepubliceerd, bijvoorbeeld wanneer een gebruiker een bepaald gebied binnengaat.
Op deze manier kunt u door u te abonneren op owntracks/+/+/event zien (voor gebruikers die u gemachtigd bent te zien) wanneer zij een bepaald gebied binnenkomen of verlaten.
Owntracks publiceert zijn berichten in het JSON-formaat:
https://owntracks.org/booklet/tech/json/
zoals u kunt zien zijn de functies na het apparaat.
Aangezien er een vaste "diepte" is voor gebruiker/apparaat die vooraf bekend is, kan een abonnement op meerdere gebruikers en apparaten worden gedaan met behulp van jokertekens:
In de JSON, de type van de specifieke JSON wordt meegezonden in het bericht:
Dit is een goed idee! Op deze manier kunt u controleren of uw toepassing de gebeurtenis correct begrijpt, typecontroles kan uitvoeren, enz.
De afzonderlijke elementen worden op een niet-verbose manier gespecificeerd. Dit helpt om verkeer te besparen, vooral voor berichten die vaak zullen worden gepubliceerd.
b.v.:
- acc: nauwkeurigheid van de gerapporteerde locatie in meters (zonder eenheid)
veel van de elementen zijn facultatief.
Interessant is dat het locatietype wordt gedefinieerd voor verschillende toestellen, die verschillende elementen ondersteunen.
Een eenvoudig laatste wil en testament bericht wordt gepubliceerd. Het bevat gewoon een tijdstempel tst, waarop het apparaat voor het eerst verbinding maakte.
tst is een Unix epoch timestamp.
Een interessant aspect van dit event type / payload type is dat er verschillende tijdstempels worden gespecificeerd:
- wtst: Tijdstempel van waypoint creatie
- tst: Tijdstempel waarop de gebeurtenis plaatsvond.
Een waypoint is een interessant punt, b.v. uw garage - als u uw garage binnengaat of verlaat zal een overgangsevent worden getriggerd:
- gebeurtenis: (enter|leave)
Een configuratie gebeurtenis. Indien ingeschakeld, accepteren apps ook configuratieberichten op afstand.
Dit event bevat veel mogelijke elementen, die meer verbose zijn (b.v. validatecertificatechain) - dit is verstandig, omdat de configuratie kan worden opgeslagen als JSON (! -> dit kan worden doorgegeven als MQTT bericht en opgeslagen!), en ook omdat het niet vaak wordt verzonden, is verbositeit geen groot probleem, maar eerder een voordeel voor gebruikers.
b.v. een actie met de "action": "dump" zal een publicatie van het configuratiebericht naar het relatieve pad dump triggeren
Voor een actie kunnen optionele subparameters worden opgegeven, bijvoorbeeld een tijdsbestek waarnaar moet worden gekeken:
Een ander interessant ontwerp-idee is dat door een bepaalde variatie van dit cmd-bericht een browser kan worden geopend naar een bepaalde URL. Bijv. als je de garage binnengaat, zou een garage controle site geopend kunnen worden, ...
een matrix van een ander berichttype kan / moet hier als parameter worden doorgegeven.
Het interessante aan dit bericht is dat het ook een veld bevat voor een Base64 gecodeerde PNG afbeelding:
het interessante idee hier is dat een optionele _schepper item kan worden doorgegeven, dat de entiteit identificeert die deze waypoints heeft gecreëerd.
Merk ook op, dat owntracks de underscore _ gebruikt voor "speciale" parameters.
facultatief kunnen al deze berichten gecodeerd voor transport met een gedeelde symmetrische sleutel.
De versleutelde payload (het oorspronkelijke bericht) staat in het "data"-element, Base64-gecodeerd.
Berichten
De payload van het bericht is binair en kan van alles zijn, er is geen eis dat de berichten geldig UTF-8 zijn.
Daarom kunt u ook digitale gegevens, b.v. afbeeldingen, als payload over bepaalde onderwerpen publiceren.
Veel van de huidige IoT Dashboards gebruiken gegevens die zijn gecodeerd als JSON.
In het algemeen lijken er twee stromingen te zijn: berichten zijn in feite onbewerkte waarden, en metadata is gecodeerd op de topic tree, en JSON gecodeerde waarden die metadata met zich meedragen als de payload.
suggesties
- Gebruik JSON formaat voor bericht payload
- attributen bundelen in berichten, in plaats van er afzonderlijke onderwerpen voor te maken
- omvatten:
- laadgegevens
- sensor-/apparaat-id (indien geen deel van de onderwerpenboom)
- functie
- tijdstempel
Interessante bronnen
Awesome MQTT: Verzameling van MQTT-gerelateerde links:
- https://github.com/hobbyquaker/awesome-mqtt
individuele projecten:
twitter-to-mqtt - Een python daemon die de Twitter Streaming API gebruikt om tweets te openen en ze opnieuw publiceert in een MQTT topic.
fritz2mqtt - Verbind FRITZ!Box met MQTT.
Ref:
- https://raspberry-valley.azurewebsites.net/MQTT-Topic-Trees/
- https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
- https://homieiot.github.io/
- https://github.com/homieiot/convention
- https://github.com/mqtt-smarthome/mqtt-smarthome
- http://www.steves-internet-guide.com/mqtt/
- http://www.steves-internet-guide.com/understanding-mqtt-topics/
- http://www.steves-internet-guide.com/mqtt-topic-payload-design-notes/
- https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch
- https://tinkerman.cat/post/mqtt-topic-naming-convention
- https://github.com/mqtt-smarthome/mqtt-smarthome/blob/master/howtos/homematic.md (toont de stroom met Knooppunt ROOD)
- https://owntracks.org/booklet/tech/json/
Heruitgave:
- https://lodge.glasgownet.com/2012/09/23/mqtt-republishing-itch/
- https://github.com/kylegordon/mqtt-republisher