ThingsBoard via
-
Nu ik een begin heb om data te verzenden, wil ik deze naar buiten ontsluiten.
Om het nog even gratis te kunnen testen lijkt thingsboard me een goede start.Via het portal wil ik dan mijn callback URL naar:
https://demo.thingsboard.io/api/v1/[mijntoken]/telemetry
Ik zie niet wat ik daar verkeerd intik, maar het portal zelf weigert die url al:Something went wrong with editing your callback URL
Doe ik iets fout? Ik zou daar toch gewoon een url moeten kunnen invoeren?
Welke controle wordt hier op de achtergrond gedaan waaraan ik blijkbaar niet voldoe? -
@supersjimmie Hoi Sjimmie, wanneer je een callback URL toevoegd wordt er een leeg HTTP[post] pakket naar jouw callback URL verstuurd. De callback URL (thingsboard dus) moet hierop reageren met een 200 OK bericht.
-
@stefan-de-lange Ah zo.
Dat wordt dan lastig, want:curl -v -X POST https://demo.thingsboard.io/api/v1/[mijntoken]/telemetry --header “Content-Type:application/json”
geeft Required request body is missing.
En deze:
curl -v -X POST https://demo.thingsboard.io/api/v1/[mijntoken]/telemetry --header “Content-Type:application/json” -d “{“ts”:1451649600512, “values”:{“key1”:“value1”, “key2”:“value2”}}”
resulteert netjes in een 200.
Kan ik bij het opgeven van de callback url dan al een body meegeven om door die test heen te komen?
-
@supersjimmie Heb het zelf ook even gecheckt. Thingsboard lijkt inderdaad niet om te kunnen gaan met een leeg datapakket.
Kan ik bij het opgeven van de callback url dan al een body meegeven om door die test heen te komen?
Misschien dat @afzal_m of @ericbarten dit weet. De oplossing zou ook kunnen liggen bij thingsboard maar hiervoor ken ik de applicatie niet goed genoeg. Misschien dat je ergens kunt aangeven dat telemetry data niet perse een JSON in de body moet verwachten?
Als alternatief voor thingsboard zou je ook eens kunnen kijken naar node-red. Ik gebruik dat al een tijdje in combinatie met NB-IoT en dat bevalt me erg goed
-
Resultaat is inderdaad (als ik de callback via de API probeer toe te kennen):
{“msg”:“Callback URL not accessible”,“code”:2000}
Feitelijk is de url wel accessible, alleen geeft die zonder body een 400 terug.
@stefan-de-lange Tsja, ik had een demo-projectje op het oog wat voortborduurt in thingsboard, dat dan weer ombouwen naar node-red omdat we hier thingsboard niet kunnen voeren maakt het allemaal nog complexer voor mij.
Ook hier, net als vorige week met het gebruiken van een sim7000e, een beetje mist is een korte uitleg. Soms is een klein beetje hulp genoeg voor mij om het verder weer zelf te kunnen.Als @afzal_m of @ericbarten (of iemand anders) mij opweg kunnen helpen om thingsboard als callback url erin te krijgen dan denk ik dat ik een heel eind verder kom…
-
@supersjimmie
De server valideert tijdens de registratie van de callback url of het ‘endpoint’ bestaat met een lage call. Volgens mij is het handig om een http code 200 terug te sturen…Overigens wordt je data verpakt in een JSON bericht zoiets als dit:
{"reports":[{"serialNumber":"IMEI:00000000000000","timestamp":1542371038999,"subscriptionId":"6acb29e3-293c-44ca-85bf-77aded8efde0","resourcePath":"uplinkMsg/0/data","value":"7b226e223a225465616d34222c226970223a2231302e302e312e323534222c2274223a313534323337313033382e39363639372c22736d223a3339352c227576223a3433312c227374223a32342e31382c226d6e223a3536377d"}],"registrations":[],"deregistrations":[],"updates":[],"expirations":[],"responses":[]}
meer dan een uplink bericht kan worden verpakt in de callback:
{"reports":[{"serialNumber":"IMEI:00000000000000","timestamp":1542799597211,"subscriptionId":"0f238f58-5bc3-4b02-be8f-a1985f84e3a5","resourcePath":"uplinkMsg/0/data","value":"7b226e223a225465616d33222c226970223a2231302e302e312e313633222 c2274223a313534323739393539372e31353131322c22736d223a3336362c227576223a3434382c227374223a2d3132372e30302c226d6e223a3131387d"},{"serialNumber":"IMEI:000000000000000","timestamp":1542799606147,"subscriptionId":"0f238f58-5bc3-4b02-be8f-a198 5f84e3a5","resourcePath":"uplinkMsg/0/data","value":"7b226e223a225465616d33222c226970223a2231302e302e312e313633222c2274223a313534323739393630362e31303930392c22736d223a3336372c227576223a3434332c227374223a2d3132372e30302c226d6e223a3131397d "},{"serialNumber":"IMEI:00000000000000","timestamp":1542799615678,"subscriptionId":"0f238f58-5bc3-4b02-be8f-a1985f84e3a5","resourcePath":"uplinkMsg/0/data","value":"7b 226e223a225465616d33222c226970223a2231302e302e312e313633222c2274223a313534323739393631352e36343634322c22736d223a3336362c227576223a3433342c227374223a2d3132372e30302c226d6e223a3132307d"},{"serialNumber":"IMEI:00000000000000","timestamp":1542799624654,"subscriptionId":"0f238f58-5bc3-4b02-be8f-a1985f84e3a5","resourcePath":"uplinkMsg/0/data","value":"7b226e223a225465616d33222c226970223a2231302e302e312e313633222c2274223a313534323739393632342e36303937352c22736d223a3334352c227576223a3434312c227374223a2d3132372e30302c226d6e223a3132317d"},{"serialNumber":"IMEI:00000000000000","timestamp":1542799634106,"subscriptionId":"0f238f58-5bc3-4b02-be8f-a1985f84e3a5","resourcePath":"uplinkMsg/0/data","value":"7b226e223a225465616d33222c226970223a2231302e302e312e313633222c2274223a313534323739393633342e30373131322c22736d223a3336362c227576223a3434362c227374223a2d3132372e30302c226d6e223a3132327d"}],"registrations":[],"deregistrations":[],"updates":[],"expirations":[],"responses":[]}
Ik ken de Thingsboard omgeving niet goed genoeg maar ik vermoed dat je het JSON bericht moet parsen, in de “uplinkMsg/0/data”,“value” staan de berichten in hex gecodeerd.
-
@techniek Thanks. Om een http 200 terug te krijgen (om door de callback url validatie heen te komen) heb ik er voor het gemak beeceptor tussen geduwd. Dus de callback url gaat naar beeceptor, die heb ik ingesteld om altijd een http 200 terug te geven. Vervolgens staat in beeceptor de proxy ingesteld om het naar Thingsboard door te proxy-en.
Maar wat je nu zegt over die ingepakte data had ik me nog niet gerealiseerd. Dat betekent dus dat mijn verzonden json data niet 1:1 bij de ontvanger terechtkomt. Ik zal dus inderdaad nu nog moeten uitzoeken hoe ik de value (met mijn json) uit de uplinkMsg/0/data van de grote json kan plukken, om die weer als bruikbare json in Thingsboard te gebruiken… (het is dus een json-in-json)
-
Ik zal dus inderdaad nu nog moeten uitzoeken hoe ik de value (met mijn json) uit de uplinkMsg/0/data van de grote json kan plukken, om die weer als bruikbare json in Thingsboard te gebruiken…
Dit kun je perfect doen in Node-RED. Node-RED is gebaseerd op node.js, je kunt dus gewoon JavaScript programmeren. Het uit elkaar plukken van een JSON (en deze zo nodig weer formatteren) is een kwestie van een paar regels code. Hier kan ik je eventueel mee helpen.
-
@stefan-de-lange Haha, thanks, dat is me in ThingsBoard ook al gelukt.
Wat ik nu doe is:
- Mijn sim7000e stuurt een blokje json-data,
- De callback url is mijn beeceptor url met daarachter het /api/v1/[token]/telemetry gedeelte,
- beeceptor ingesteld om altijd een 200 terug te geven,
- beeceptor is proxy naar demo.thingsboard.io,
- In thingsboard wordt de string opgehaald met de relevante json-data,
- De string wordt van HEX (31d1fa45d3a3-blabla) omgezet naar een text-string,
- Overtollige backslashes uit de vorige stap worden geschoond,
- Er wordt weer een json object gemaakt,
- Die nieuwe json-data wordt doorgezet naar het thingsboard-device,
- Het thinksboard-device geeft de data weer in het thingsboard dashboard.
Theoretisch zou dit het moeten zijn.
Ik vond het best goed verzonnen voor een eerste keer.Alleen ben ik te fanatiek geweest met bouwen en testen met curl -> beeceptor -> thingsboard, want nu ik dan eindelijk echt vanaf mijn sim7000e wil gaan verzenden is precies de dag-limiet van het gratis beeceptor account verlopen. En een nieuw account maken (en overal aanpassen) voor vanavond vind ik dan net teveel gedoe. Dus wachten tot morgen…
To-do:
- Wachten tot ik weer met beeceptor mag spelen,
- Zoeken hoe ik beeceptor er tussenuit kan krijgen, want die is puur om de callback-url check te doorstaan…
-
Helaas, na het toch maar aanmaken van een extra beeceptor url kon ik er even mee verder.
Maar het blijkt dat ThingsBoard niet overweg kan met de uitgebreide json code. Zodra er dingen als […] in zitten dan werkt het niet meer, en ik kan niet vinden hoe ik vooraf de data kan strippen.Als @afzal_m of @ericbarten nog meelezen, zou iemand me kunnen tippen?
-
Hoi @supersjimmie ,
Allereerst leuk dat je voor thingsboard hebt gekozen.
Je probeert de HTTP integratie van thingsboard te gebruiken.
Het probleem met HTTP integraties is dat er verwachtingen worden gesteld aan het formaat van de payload.
Wat je dan inderdaad nodig hebt is zoiets wat jij via Beeceptor probeert te doen.
Ik doe dat op mijn eigen Node Red server die ik host op AWS bijvoorbeeld hier kan ik ook de data omzetten naar MQTT of wat ever er nodig is.Maar goed dit is een extra component. Wat je nog niet weet is dat juist Thingsboard een native integratie heeft met ons platform.
Je moet hiervoor helaas wel voor de professional edition kiezen, welke 30 dagen gratis is en daarna redelijk geprijsd. Ik kan je helpen met de benodigde data converters de documentatie hiervoor is nog volledig afgerond helaas -
@ericbarten Ik koos voor thingsboard omdat ik had verwacht dat het daarmee relatief eenvoudig zou zijn. Op de help-pagina’s stond thingsboard genoemd en ik ging er vanuit dat het dan altijd zou werken.
En omdat er een gratis versie van (demo.)thingsboard(.io) is had ik verwacht dat ik het daarmee kon testen en vooral demo-en.Wellicht ben ik een vreemde eend in de bijt, maar ik ben met dit soort projectjes privé bezig. Mijn werk is wel ICT en ik verwacht in de redelijk nabije toekomst heel veel IoT werk, maar vooralsnog ben ik bezig om uit te zoeken en te laten zien hoe dingen werken om mensen te enthousiasmeren. Omdat het allemaal privé is, is het een extra regel dat het zeer low-budget is. De aanschaf van een sim7000e en overige benodigdheden was mijn enige investering, wat ik graag nog even zou houd.
Daarbij komt dat ik vind dat een dergelijke oplossing puur in de cloud moet kunnen worden gebouwd, zonder on-premise zaken. En dan dus ook nog in de gratis hoeken van de cloud.
Nu langzaamaan blijkt dat er geen “gratis” oplossing is (een maand is me te kort) vrees ik dat ik op thingsboard doodloop.
Ik twijfel nog of ik ga onderzoeken of ik bij AWS een free variant van de Lambda service kan gebruiken, dan gaat de data vanaf t-mobile naar de Lambda functie, die accepteert de data 1:1, verbouwt het tot thingsboard-compatible data en zet het door naar thingsboard. (Daarvoor moet ik me dan eerst verdiepen in wat allemaal free en haalbaar is in AWS)
-
Daarbij komt dat ik vind dat een dergelijke oplossing puur in de cloud moet kunnen worden gebouwd, zonder on-premise zaken. En dan dus ook nog in de gratis hoeken van de cloud.
Jammer. Een kastje of RPI in je meterkast is 100x leuker… (en gratis, behalve de HW dan). Draai er Node-RED op en al je problemen zijn opgelost.
-
@stefan-de-lange dat biedt wel weer nieuw licht… Ik ga toch eerst eens oefenen om er een aws lambda functie tussen te hangen, dat vind ik ook wel “stoer”… En als dat niet wil ga ik nog de tijd en energie overwegen van een rPI. Ik heb nog wel een hele oude rpi liggen (model 1b) die me al vaker met kleinigheidjes uit de brand hielp…
-
Het is gelukt!
Vanaf mijn sim7000e gaat het bericht nu naar een raspberry-pi bij mij thuis. (jaja, het kan beter)
Daar komt het in Python Flask terecht, die niets anders doet dan de json data uitkleden en ombouwen.
Flask zet de uitgeklede json data door naar een lokaal op die raspberry-pi geinstalleerde ThingsBoard.Helaas niet zonder een “lokale server” maar op een oude raspberry-pi Model B uit mijn rommelkast kost deze demo omgeving met alsnog “niets”.
Het zal in Flask vast netter kunnen, maar dit is zoals het nu werkt:
Vanuit de sim7000e stuur ik een pakketje json-style data:
AT+CIPSTART=“UDP”,“172.27.131.100”,15683
AT+CIPSEND=48
{“latitude”: 52.136421, “longitude”: 5.262903}(fake locatie!)
De Callback URL wijst naar het IP adres van mijn router, waarop een Port-Forward is ingesteld van buiten [80] naar binnen [8081]. Flask draait dan op [8081]. (Thingsboard draait op [8080] en is vooralsnog alleen voor mij binnen bereikbaar)
In Flask wordt het mega-pakket van T-Mobile gestript:
from flask import Flask, request, jsonify, json
import requests
app = Flask(__name__)
@app.route(‘/api/v1/Pca6uieWinGX6FjubpA6/telemetry’, methods=[‘POST’])
def hello():
data = request.data
data = data.replace(“u’”,“'”)
data = data.replace(“'”,“\”“)
data = data.replace(“L,”,”,")
msg = json.loads(data)
s = msg[‘reports’][0][‘value’].decode(‘hex’)
newmsg = json.loads(s)
json_str = ‘{“longitude”: ‘+ str(newmsg[‘longitude’]) + ’ ,“longitude”: ’ + str(newmsg[‘latitude’]) +’}’
url = ‘http://localhost:8080/api/v1/[key]/telemetry’
r = requests.post(url, json_str)
return ‘’,200if __name__ == ‘__main__’:
app.run(host= ‘0.0.0.0’,port=8081,debug=True)En in Thingsboard heb ik een Device die de longitude en longitude omzet naar een plattegrond.
Overigens liep ik hier ook even tegen het probleem aan dat de Callback URL alleen kan worden aangepast (naar mijn huis-router) wanneer een lege body toch een http code 200 teruggeeft. Maar met eenmalig een return ‘’,200 bovenin de hello-functie (die daarna weg kon) was dat nu snel opgelost.
Nu nog voor de show een https certificaat regelen bij Let’s-Encrypt en zien of/hoe dat met Flask geregeld kan worden…
En het viel me op dat ik soms een veel uitgebreidere json binnenkrijg dan de andere keren.
De grote versie begint met{“responses”:
Terwijl de kleine versie begint met
{“reports”:
Ik twijfel nog of ik het Flask script conditioneel moet laten strippen, afhankelijk van welke variant er binnenkomt?
-
Hoi Sjimmie. Mooi dat je het werkend hebt gekregen.
{“latitude”: 52.136421, “longitude”: 5.262903}
Ik zou dit anders aanpakken. Aan de kant van NB-IoT wil je enkel kale bytes sturen, het sturen van JSON data creëert onnodig veel overhead.
Je zou het ook zo kunnen doen namelijk:
AT+CIPSEND=16
031B89E500504E37Is maar 8 bytes. In je python flask kun je dit vervolgens weer scheiden omdat je weet dat beide variabelen 4 bytes zijn:
latitude = 031B89E5
longitude = 00504E37Dan converteren naar decimale notatie en de komma weer terugplaatsen.