Setelah saya sukses membuat hello world antara modul LoRa dengan Gateway LoRawan Telkom (baca disini), saya akan lanjut membahas pengolahan data yang "lebih berguna" menggunakan sensor sejuta umat DHT dan dengan protokol IOT paling enteng yaitu MQTT. Untuk memahami bagaimana pemahaman PUB dan SUB dari platform IOT Antares yang menggunakan standar M2M, maka perlu sekali untuk memahami pembahasan sebelumnya di blog ini, diantaranya :
Breaking news: Telkom akan melakukan migrasi LoRaWan ke Telkomiot.id, Silahkan baca disini
- Proses PUB dan SUB dari Antares yang menggunakan 1 topik untuk PUB/REQ dan 1 topik untuk SUB/RESP. Jadi ketika data diterima antares, tidak serta merta akan diberikan kepada yag subscribe, jadi butuh REQUEST data dengan payload tertentu dan kemudian menerima RESPONSE pada 1 topik (hanya 1 tiap akun) yg telah di subscribe. Bisa dibaca disini , disini , dan disini .
- Python Paho-mqtt sebagai library paling umum untuk menerima dan mengolah protokol mqtt sehingga dapat dilanjutkan ke proses selanjutnya seperti menyimpan database, membuat grafik atau mengirim ke bot telegram. Bisa dibaca dulu agar mengerti disini dan disini.
#include <SPI.h> #include <LoRa.h> #include "DHT.h" #include <LoRaWanPacket.h> //Sesuaikan PIN CS, Reset, DIO0 const int csPin = 10; const int resetPin = 9; const int irqPin = 2; const int dhtPin = 3; //Sesuaikan pin DHT //Sesuaikan dev address dan key device LoRa const char *devAddr = "aabbccdd"; const char *nwkSKey = "11111111111111110000000000000000"; const char *appSKey = "00000000000000002222222222222222"; #define DHTTYPE DHT22 //Sensor DHT22 DHT dht(dhtPin, DHTTYPE); struct LoRa_config { long Frequency; int SpreadingFactor; long SignalBandwidth; int CodingRate4; bool enableCrc; bool invertIQ; int SyncWord; int PreambleLength; }; //Frekuensi Telkom LoRawan 922MHZ, sesuaikan dengan BTS GW terdekat static LoRa_config txLoRa = {922000000, 10, 125000, 5, true, false, 0x34, 8}; void LoRa_setConfig(struct LoRa_config config) { LoRa.setFrequency(config.Frequency); LoRa.setSpreadingFactor(config.SpreadingFactor); LoRa.setSignalBandwidth(config.SignalBandwidth); LoRa.setCodingRate4(config.CodingRate4); if (config.enableCrc) LoRa.enableCrc(); else LoRa.disableCrc(); if (config.invertIQ) LoRa.enableInvertIQ(); else LoRa.disableInvertIQ(); LoRa.setSyncWord(config.SyncWord); LoRa.setPreambleLength(config.PreambleLength); } void LoRa_TxMode() { LoRa_setConfig(txLoRa); LoRa.idle(); } void setup() { Serial.begin(9600); while (!Serial); LoRaWanPacket.personalize(devAddr, nwkSKey, appSKey); LoRa.setPins(csPin, resetPin, irqPin); if (!LoRa.begin(txLoRa.Frequency)) { Serial.println("LoRa init failed. Check your connections."); while (true); } Serial.println("LoRa init succeeded."); Serial.println(); dht.begin(); } String SendTempHumid(){ //kirim data pengukuran DHT float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); } Serial.print("Humidity: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" °C "); //yang dikirim data berupa string JSON return( "{\"suhu\":" + String(t) + ",\"humi\":" + String(h) +"}"); } void loop() { if (runEvery(10000)) { LoRa_sendMessage(); Serial.println("Kirim data!"); } } void LoRa_sendMessage() { LoRa_TxMode(); LoRaWanPacket.clear(); //Serial.println(SendTempHumid()); LoRaWanPacket.print(SendTempHumid()); if (LoRaWanPacket.encode()) { LoRa.beginPacket(); LoRa.write(LoRaWanPacket.buffer(), LoRaWanPacket.length()); LoRa.endPacket(); } } boolean runEvery(unsigned long interval) { static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; return true; } return false; }
broker = 'mqtt.antares.id'
port = 1883
topicsubantares = "/oneM2M/resp/antares-cse/1111111111111111:2222222222222222/json"
topicpubantares = "/oneM2M/req/1111111111111111:2222222222222222/antares-cse/json"
def antares_request_last(client: mqtt_client):
data_raw = ("{"
"\"m2m:rqp\": {"
"\"fr\": \"1111111111111111:2222222222222222\","
"\"to\": \"/antares-cse/antares-id/APP_NAME/Cevice_Name/la\","
"\"op\": 2,"
"\"rqi\": 123456,"
"\"ty\": 4"
" }"
"}")
ret=client.publish(topicpubantares,data_raw)
"m2m:rsp" : {
"rsc" : 2000,
"rqi" : "123456",
"pc" : {
"m2m:cin" : {
"rn" : "cin_TQ_E2xnzT42t3zsS",
"ty" : 4,
"ri" : "/antares-cse/cin-TQ_E2xnzT42t3zsS",
"pi" : "/antares-cse/cnt-pqq6TLDSTvqCizzB",
"ct" : "20220526T080631",
"lt" : "20220526T080631",
"st" : 0,
"cnf" : "text/plain:0",
"cs" : 239,
"con" : "{\"type\":\"uplink\",\"port\":1,\"data\":{\"suhu\":30.1,\"h
umi\":79.2},\"counter\":6,\"radio\":{\"gps_time\":1337562409369,\"hardware\":{\"
snr\":0.5,\"rssi\":-106},\"modulation\":{\"bandwidth\":125000,\"spreading\":10},
\"delay\":0.05295205116271973,\"freq\":922,\"size\":40}}"
}
},
"to" : "1111111111111111:2222222222222222",
"fr" : "/antares-cse"
}
def parsing_data(datae):
datanya = json.loads(datae['m2m:rsp']['pc']['m2m:cin']['con'])
gps_time = math.floor(datanya['radio']['gps_time']/1000) +25200
waktu = datetime(1980, 1, 6) + timedelta(seconds=gps_time - (35 - 19))
#print(type(datanya['radio']['gps_time']))
print(waktu)
print('Suhu = ' + str(datanya['data']['suhu']) + ' Celcius ')
print('Kelembaban = ' + str(datanya['data']['humi']) + ' % Rh\n\n')