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.
Hardware yang kita gunakan masih seperti sebelumnya yaitu breakout board LoRa RFM95 dan arduino uno/nano/pro sebagai pengontrol nya. Sebagai sensor saya gunakan DHT22 yang lebih bagus dari kakaknya DHT11, rangkaiannya kira-kira seperti ini (sesuaikan dengan pin SPI pada arduino yg dipakai) :
Script arduinonya merupakan penggabungan tutorial hello world sebelumnya dengan menggunakan library LoRaWan Packet yang lumayan stabil untuk pengiriman data. Tanpa menunda-nunda saya bagikan script untuk mengirim suhu dan kelembaban ke Antares melalui LoRaWan :
#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; }
Lalu bagaimana cara mengunduh atau mengambil data dari web antares tadi ? Sebenernya pada python telah dibuatkan library untuk mengunduh data antares secara http yang telah saya bahas disini : https://www.aisi555.com/2020/08/solderpiraspberry-pi-ke-antares-semakin.html . Namun kali ini saya ingin menggunakan protokol MQTT agar lebih memahami proses SUB dan PUB pada antares yang berbeda dengan broker MQTT pada umumnya. Secara singkat proses untuk mendapatkan data dari database antares sebagai berikut:
1. Gunakan broker MQTT antares dan dengan topik yang FIX gak bisa diutak-atik. Sesuaikan script dibawah dengan User key pada akun antares yang digunakan.
broker = 'mqtt.antares.id'
port = 1883
topicsubantares = "/oneM2M/resp/antares-cse/1111111111111111:2222222222222222/json"
topicpubantares = "/oneM2M/req/1111111111111111:2222222222222222/antares-cse/json"
2. Jika ingin mengunduh data terakhir dari sebuah device, maka dikirimkan (PUB) ke topik yang cuman ada satu itu. Pesan request JSON nya seperti ini :
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"
}
4. Dari data diatas maka dibutuhkan pemahaman bahasa python dan konsep parsing Dictionary atau JSON string untuk dapat mengolah data lebih jitu.
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')
Script python lengkapnya akan saya bagikan jika pembaca membutuhkannya, dan yang ingin bertanya langsung aja ke email: ahocool@gmail.com atau whatsapp ke 08155737755. Hasilnya bisa dilihat pada video singkat berikut ini :
0 komentar:
Posting Komentar