Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

  • IC Timer 555 yang Multifungsi

    IC timer 555 adalah sirkuit terpadu (chip) yang digunakan dalam berbagai pembangkit timer, pulsa dan aplikasi osilator. Komponen ini digunakan secara luas, berkat kemudahan dalam penggunaan, harga rendah dan stabilitas yang baik

  • Ayo Migrasi TV Digital

    Kami bantu anda untuk memahami lebih jelas mengenai migrasi tv digital, apa sebabnya dan bagaimana efek terhadap kehidupan. Jasa teknisi juga tersedia dan siap membantu instalasi - setting perangkat - pengaturan antena dan distribusi televisi digital ke kamar kos / hotel

  • Bermain DOT Matrix - LOVEHURT

    Project Sederhana dengan Dot Matrix dan Attiny2313. Bisa menjadi hadiah buat teman atau pacarmu yang ulang tahun dengan tulisan dan animasi yang dapat dibuat sendiri.

  • JAM DIGITAL 6 DIGIT TANPA MICRO FULL CMOS

    Jika anda pencinta IC TTL datau CMOS maka project jam digital ini akan menunjukkan bahwa tidak ada salahnya balik kembali ke dasar elektronika digital , sebab semuanya BISA dibuat dengan teknologi jadul

  • Node Red - Kontrol Industri 4.0

    Teknologi kontrol sudah melampaui ekspektasi semua orang dan dengan kemajuan dunia elektronika, kini semakin leluasa berkreasi melalui Node Red

Tampilkan postingan dengan label iot. Tampilkan semua postingan
Tampilkan postingan dengan label iot. Tampilkan semua postingan

Sabtu, 07 Desember 2024

Grafik IOT Dynamic dengan Webhook - GoogleSheets - Google Apps Script

 

Semakin hari layanan internet web "gratis" semacam google berlomba menyajikan kemudahan bagi penggunanya, seperti saya yang kebetulan sedang mencari cara menampilkan grafik IOT secara dinamic. Pada platform IOT semacam antares / telkomiot bisa memanfaatkan fasilitas widget grafik dan pernah juga saya bahas menggunakan webhook pada antares (baca disini). Namun teringat saya pada request seorang mahasiswa yang kesulitan melakukan embeeded / tempel grafiknya di laporan tugas akhirnya dan pada waktu itu saya pake jembatan di google collab untuk menampilkan grafik di quickchart.io. 


Lalu gambar grafik iot diatas kok bisa dinamis dan interaktif begitu ? Mari saya kasi tau caranya ..


Pertama kita butuh mikrokontroler untuk mengirimkan data atau bisa juga gunakan simulator saja dan yang saya pilihkan bernama wokwi yang sudah sering dibahas di blog ini. Jadi kita akan membuat simulator pengirim data tegangan dan arus (secara random) yang bisa dibuka pada link wokwi disini.




Script nya akan mengirim data secara POST menuju alamat endpoint webhooks dan format datanya berupa JSON. Untuk mengetest apakah data terkirim dengan benar dapat menggunakan tester webhooks / POST online bernama requestcatcher seperti pada gambar berikut :



Lalu kita lanjutkan mengirimkan weebhook ke Google sheets seperti yang saya tulis terdahulu (baca disini) menggunakan antares, dan kini tanpa antares langsung dari ESP32 menuju googlesheets dan hasilnya tiap item pada JSON akan di tambahkan ke baris baru kebawah terus menerus jika ada data baru yg masuk.



Lalu bagaimana caranya membuat agar datanya hanya dibatasi 20 data terakhir sehingga grafiknya dapat lebih mudah dilihat ? Ternyata googlesheets memiliki fasilitas APPS SCRIPTS yang bisa menjadi coding otomasi dari webhooks ke googlesheets. Secara default maka apps scripts yang disediakan adalah berhubungan dengan webhooks, namun kita bisa hapus dan kemudian kreasikan sendiri (thanks to chatgpt).


 

Script yang saya tambahkan seperti berikut


function doPost(e) {
  try {
    if (!e || !e.postData) {
      throw new Error("No postData received. Check the incoming request.");
    }
   
    // Log the raw data for debugging
    Logger.log(e.postData.contents);

    // Parse the incoming JSON data
    var jsonData = JSON.parse(e.postData.contents);
   
    // Extract voltage and current from the JSON payload
    var voltage = jsonData.volt || "N/A";  // Default to "N/A" if missing
    var current = jsonData.amp || "N/A";  // Default to "N/A" if missing
    var timestamp = new Date().toISOString(); // Get the current timestamp
   
    // Get the active sheet and append the data as a new row
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    sheet.appendRow([timestamp, voltage, current]);
   
    // Keep only the last 20 rows (delete older rows if necessary)
    var lastRow = sheet.getLastRow();
    if (lastRow > 21) { // Keep the header row
      sheet.deleteRow(2); // Always delete the second row (keep header row intact)
    }
   
    return ContentService.createTextOutput("Data added to Google Sheets");
  } catch (error) {
    // Log the error for debugging
    Logger.log("Error: " + error.message);
    return ContentService.createTextOutput("Error: " + error.message);
  }
}



Dan kemudian hasilnya grafik/charts yang saya buat sesuai harapan menjadi hanya 20 baris data saja.


Seperti yang kita ketahui, google sheets secara keseluruhan maupun grafiknya saja dapat dipublish sebagai gambar ataupun grafik interaktif, sehingga bisa ditempel secara iframe pada website seperti pada grafik paling atas tulisan saya ini.



Bagaimana ? Mudah bukan ? Secara default google yang memberikan fasilitas secara gratis ini, mengatur refresh rate tiap 5 menit untuk meng-update tampilan grafiknya. Jadi kendalanya grafik tidak terlalu realtime tapi cukup menggembirakan bagi saya yang pecinta gratisan...hehehehe..

Share:

Minggu, 01 Desember 2024

[android] IOT via MQTT dan menampilkan Gauge menggunakan quickchart.io

 


Wahh ngapain bahas MQTT dan Aplikasi IOT lagi? Kan sudah pernah tuh bikin grafik yang keren di smartphone ( baca disini ) bahkan sudah sempat dijadikan bahan ujian semester anak D4 Teknik Listrik Unesa. 

Memang sih menurut pandangan sekilas akan terlihat itu lagi dan lagi yang ditulis, namun sadar gak ya ? Kalau apk IOT MQTT panel itu terpaku pada susunan widget yang itu-itu aja dan cenderung kaku dalam tampilan. Merubah font saja pun gak akan bisa. Dan kalau aplikasinya digunakan untuk proyek maka terkesan kurang keren apabila ingin menambahkan logo-gambar-screen lain pada aplikasi. Lalu langkah pertama apa ya setelah berhasil belajar awal mengkreasikan aplikasi android di MIT APP INVENTOR (baca disini) ? Yang pertama akan saya bahas adalah bagaimana menambahkan gauge/meter pada aplikasi.


- Quickchart.io

Ini merupakan website yang lama saya kenal karena sangat bermanfaat dalam membuat grafik secara statis maupun dinamis, dengan library yang opensource maupun berbayar. Jika anda masuk ke websitenya di bagian galery maka akan banyak jenis chart dan grafik yang mungkin kamu perlukan, seperti yang saya temukan yaitu gauge berupa speedometer.


Jadi tinggal mengkreasikan setingan CSS di editor sebelah kiri maka dapat membuat gambar speedometer seperti yang saya contohkan di link yang telah digenerate seperti  berikut :


https://quickchart.io/chart?w=150&h=150&bkg=rgba(246%2C%20241%2C%20241%2C%200.13)&c=%0A%7B%0A%20%20type%3A%20%27gauge%27%2C%0A%20%20data%3A%20%7B%0A%20%20%20%20labels%3A%20%5B%27Kering%27%2C%20%27Sedang%27%2C%20%27Basah%27%5D%2C%0A%20%20%20%20datasets%3A%20%5B%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20data%3A%20%5B30%2C%2070%2C%2099%5D%2C%0A%20%20%20%20%20%20%20%20value%3A%2050%2C%0A%20%20%20%20%20%20%20%20minValue%3A%200%2C%0A%20%20%20%20%20%20%20%20backgroundColor%3A%20%5B%27green%27%2C%20%27orange%27%2C%20%27red%27%5D%2C%0A%20%20%20%20%20%20%20%20borderWidth%3A%202%2C%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%5D%2C%0A%20%20%7D%2C%0A%20%20options%3A%20%7B%0A%20%20%20%20legend%3A%20%7B%0A%20%20%20%20%20%20display%3A%20false%2C%0A%20%20%20%20%7D%2C%0A%20%20%20%20title%3A%20%7B%0A%20%20%20%20%20%20display%3A%20true%2C%0A%20%20%20%20%20%20text%3A%20%27Kelembaban%27%2C%0A%20%20%20%20%7D%2C%0A%20%20%20%20needle%3A%20%7B%0A%20%20%20%20%20%20radiusPercentage%3A%201%2C%0A%20%20%20%20%20%20widthPercentage%3A%205%2C%0A%20%20%20%20%20%20lengthPercentage%3A%2080%2C%0A%20%20%20%20%20%20color%3A%20%27%23000%27%2C%0A%20%20%20%20%7D%2C%0A%20%20%20%20valueLabel%3A%20%7B%0A%20%20%20%20%20%20fontSize%3A%2020%2C%0A%20%20%20%20%20%20backgroundColor%3A%20%27white%27%2C%0A%20%20%20%20%20%20color%3A%20%27%23000%27%2C%0A%20%20%20%20%20%20formatter%3A%20function%20(value%2C%20context)%20%7B%0A%20%20%20%20%20%20%20%20return%20value%20%2B%20%27%20%25%20rH%27%3B%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20bottomMarginPercentage%3A%2060%2C%0A%20%20%20%20%7D%2C%0A%20%20%20%20plugins%3A%20%7B%0A%20%20%20%20%20%20datalabels%3A%20%7B%0A%20%20%20%20%20%20%20%20display%3A%20%27auto%27%2C%0A%20%20%20%20%20%20%20%20formatter%3A%20function%20(value%2C%20context)%20%7B%0A%20%20%20%20%20%20%20%20%20%20return%20context.chart.data.labels%5Bcontext.dataIndex%5D%3B%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20color%3A%20%27%23fff%27%2C%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D


Panjang ya ? namun sangat berguna jika kita akan tempelkan di widget browser atau pada MIT APP Inventor dinamakan webviewer. Jika link diatas dimasukkan di address browser akan muncul gambar yang sebeneranya bersesuaian dengan item-item parameter yang ada pada link. coba deh kamu masukkan sendiri ya di browser.


- Component WebViewer

Untuk menampilkan html ataupun browser pada MIT APP Inventor, maka komponen ini menjadi handalannya, baik bisa langsung membuka link internet maupun file html lokalan. Nah karena quickchart.io sangat simple memberikan alamat link grafik beserta parameter yang terpampang jelas, maka cukup dengan memotong bagian dimana value dari gauge akan dimasukkan, maka terpecahkanlah keruwetan yang sehari sebelumnya saya pikir akan susah. Perhatikan deh pemotongan link panjang menjadi 3 bagian block nya webviewer seperti di bawah.


Jadi dengan memotong dengan tepat lalu di join kan ke tiga potongan dengan menyisipkan angka humi maka hasilnya menarik seperti dibawah ini:



- Extension Paho MQTT (link disini)

Ini berguna sebagai tambahan library pada MIT APP Inventor untuk melakukan proses koneksi dan publish maupun subscribe sesuai standar library Paho MQTT. Jadi jika anda yang sudah sering membaca pembahasan saya mengenai MQTT yakin sudah sangat paham polanya. Untuk mempersingkat yang malas cari-cari tulisan saya mengenai mqtt yang dulu-dulu, saya siapkan hardware berupa ESP32 yang terhubung dengan sensor IOT sejuta umat DHT 11 yang akan mengirimkan data sensor ke broker mqtt test.mosquitto.org. Scriptnya seperti berikut :

#include <WiFi.h>
#include <PubSubClient.h> 
#include "DHT.h"


const char *ssid =  "wifiku";   // Gunakan sesuai wifi kamu
const char *pass =  "passwordku";   //

//inisialisasi broker
const char *mqtt_server = "test.mosquitto.org"; //BROKER GRATIS
const int mqtt_port = 1883;
const char *mqtt_user = "";
const char *mqtt_pass = "";
const char *mqtt_client_name = "aisi555keren"; // Client connections random dan gak boleh sama

// Daftar Topik disingkat, karena biasanya panjang-panjang namanya
#define TOPIC "/aisi555/mydata"


// DHT11 configuration
#define DHTPIN 4  // GPIO4 where the DHT11 is connected
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

//Timer
unsigned long previousMillis = 0;
const long interval = 10000;   // interval pengambilan dht 11
                               // broker gratis jangan cepet2

WiFiClient wclient;            //wifi client terhubung lib pubsub
PubSubClient client(wclient);

void setup() {
    // Initialize Serial for debugging
  Serial.begin(9600);
  Serial.println();

  WiFi.begin(ssid, pass);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi Terhubung..");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  // Start DHT sensor
  client.setServer(mqtt_server, mqtt_port);
  dht.begin();

}
void reconnectmqtt() //function mengatur koneksi ke broker 
{
   
    
      Serial.println("Connecting to MQTT server..");
     
      if (client.connect(mqtt_client_name,mqtt_user, mqtt_pass)) {
        Serial.println("Connected to MQTT server");
      } else {
        Serial.println("Could not connect to MQTT server");   
      }
   
  
}

  void SendTempHumid(){
    //membaca sensor dan mengirim/publish ke topic
    float h = dht.readHumidity();
    float t = dht.readTemperature();

    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    
    else{
    String pubString ="";
    pubString += "Temp: "; 
    pubString += String(t);
    pubString += " °C ";
    pubString += "Humi: "; 
    pubString += String(h);
    pubString += " %rH";

    
    Serial.println("publish to topic: " );
    Serial.print(TOPIC);
    Serial.print(" : ");
    Serial.println(pubString);
    char message_buff[pubString.length() + 1];
    pubString.toCharArray(message_buff, pubString.length() + 1);
    client.publish(TOPIC,message_buff );

    }

  }
void loop() {

 if (!client.connected()) 
   {
    reconnectmqtt();
   }

  
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis >= interval) {
    // cek interval  
    previousMillis = currentMillis;   

   SendTempHumid();
  }

}

Dan jika benar kreasi hardware dan koneksi mqtt nya dapat diuji pada aplikasi MQTT di PC maupun di  smartphone.


Pada bagian designer MIT APP Inventor dapat disetting langsung parameter broker mqtt nya dari extension paho mqtt atau juga bisa dilakukan ada bagian block. 


- Block Screen Initial


Maksudnya adaah koneksi ke broker mqtt dimulai saat layar selesai dimuat.


- Block status koneksi broker dan subscribe topik



Block ini berisikan satus dari koneksi ke broker dimana 0= terputus, 1 = menghubungkan, 2= terhubung, 3= sedang memutus, 4=koneksi abort. Jadi saya bikinkan kondisi IF..Then..Else dimana jika kondisi koneksi selain terhubung maka segera menyambungkannya kembali. Bisa juga di kondisikan sesuai keinginan si pembuat yang penting konsepnya adalah akan selalu berusaha menghubungkan ke broker. Sedangkan jika connection state =2 alias terhubung, maka lakukan subscribe ke topic yang digunakan pubsub data. Coding ini saya kondisikan persis logika yang selama ini digunakan pada pubsubclient di arduino.


Update: 


Cara diatas lebih elegan dengan memanfaatkan trigger dari clock1 yang saya settng tiap 5 detik akan melakukan proses pengecekan status koneksi ke broker MQTT lalu menghubungkannya kembali jika koneksi terputus. Variabel "sudah" digunakan untuk menyimpan status /flag apakah broker sudah terhubung atau tidak.



- Block Message Received



Secara gamblang dapat dilihat ketika ada message yang diterima dari topic maka data yang berformat : "Temp: 31.90 °C Humi: 95.00 %rH " akan diextract untuk mendapatkan nilai suhu dan kelembaban. Sedangkan nilai-nilai lainnya hampir mirip dengan tulisan sebelumnya, namun dibedakan adalah penulisan grafik yang terdahulu menggunakan trigger clock1 tiap 1 detik sedangkan kali ini akan diproses setelah message dari broker diterima. Karena hanya 1 topic yang diolah maka sederhana saja hanya melakukan pengolahan atau parsing data text saja. Selanjutnya hasil aplikasi IOT nya dapat dilihat pada gambar paling atas.


Bagaimana ? Selamat mencoba kawan


Share:

Rabu, 30 Oktober 2024

[Telkomiot.id] Pembacaan Meter Pdam Berbasis Mqtt dan AI-Yolo-Roboflow

 


Mikrokontroler merupakan ujung tombak dari implementasi IOT diberbagai bidang, dimana dengan kemampuan pengolahan sensor yang semakin baik dapat dimanfaatkan untuk membantu kehidupan manusia sehari-hari . Seperti halnya ilustrasi gambar paling atas merupakan pemanfaatan ESP32 untuk membantu pembacaan meter PDAM secara digital dan kemudian saya bersama mahasiswa Teknik Listrik - Vokasi Unesa Surabaya, yang kebetulan lagi Ujian Tengah Semester (UTS), ingin meng-upgrade ilmu jaman sekarang, sehingga dapat memiliki pemahaman "digitalisasi" yang benar dan tepat guna. Ayo ikuti keseruan UTS kali ini dan pembaca bisa juga mencobanya dirumah !


Ada 5 proses penting dalam kerangka berpikir untuk perancangan sistem pembacaan meteran pdam seperti gambar diatas, walau ada keterbatasan di sisi  pengambilan foto (hanya simulasi file gambar meter dalam spiffs) yang akan kita lakukan, perancangan sistem digitalisasi  meter pdam  idealnya seperti ini :


  1. ESP32 / ESP32 CAM mengambil gambar dari meter pdam dan merubahnya menjadi teks ter-encoded base64 
  2. ESP32 mengirimkan gambar dalam bentuk base64 tadi secara MQTT ke sebuah topik
  3. Cloud computing dalam hal ini google colab, melakukan subscribe ke topic dan kemudian menerima data gambar base64, melakukan decoding menjadi gambar jpg kemudian dengan bantuan model yolo/roboflow melakukan deteksi angka meter melalui proses Artificial Inteligence, dan kemudian pembacaan angka meter di publish ke topic reply. 
  4. ESP32 yang sebelumnya sudah subscribe ke topic reply akan menerima angka pembacaan meter dan diolah ke serial monitor atau display LCD/OLED sesuai kreatifitas. 
  5. Database pelanggan di pusat billing center dapat di update secara otomatis dan tagihan dicetak sesuai penggunaan air di pelanggan. 



Perangkat minimum yang kalian gunakan adalah ESP32, resistor 10Kohm dan Push button / tactile switch. Cukup hanya itu saja bisa kalian rangkai dengan atau tanpa projectboard/breadboard. 


FLOWCHART :



Catatan : "GUNAKAN ARDUINO IDE 1.8.XX (VERSI LAMA) JIKA KALIAN INGIN MENGIKUTI LANGKAH DIBAWAH INI YANG BERBASIS SPIFFS , JIKA KALIAN SUDAH PAHAM MENGENAI LITTLE FS SILAHKAN GUNAKAN SAJA ARDUINO IDE 2.X.X (BARU) "


SPIFFS merupakan file system layaknya di komputer untuk menyimpan data-data gambar, teks, audio dll didalam memori flash nya ESP32. Untuk melakukan seting arduino ide 1.8.xx kalian, ikuti langkah berikut :

1. Unduh file zip yang berisikan file java / jar  di : https://github.com/me-no-dev/arduino-esp32fs-plugin/releases/download/1.1/ESP32FS-1.1.zip


Catatan : gambar diatas hanya untuk menunjukkan dimana file dan folder arduino kalian, tidak perlu dibuka atau browse. Cuman di copy nama foldernya lalu dibuka melalui explorer dan pindahkan file jar ke directorynya.


3. Restart arduino ide kalian dan jika berhasil pada menu tools muncul menu baru "ESP32 sketch data upload". Buat file sketch/ino baru dan save terlebih dahulu.

4. Untuk seting jenis board yg dipakai pilih "ESP32 Dev Module" dan seting lainnya berupa pilihan "Huge App" seperti pada gambar berikut:


5. Fotokan meter pdam yg ada di sekitar kalian (gunakan hp) kemudian kecilkan dan compress sampai file JPG nya berukuran dibawah 30Kb namun masih dapat terbaca dengan jelas. Gunakan tools kompresi online yang saya rekomendasikan adalah : https://www.imgonline.com.ua/eng/compress-image-size.php

6. Pindahkan file gambar tadi (rename dulu dengan pdam.jpg) ke folder baru bernama "data" yg lokasinya satu tingkat dibawah folder dimana kalian menyimpan sketch atau file .ino, seperti pada ilustrasi berikut:


7. Untuk memindahkan file ke ESP32, maka setelah file gambar pdam.jpg tersimpan di folder /data, cukup lanjutkan dengan pilih tools => ESP32 sketch upload, sampai sukses seperti gambar berikut:



Selanjutnya kita akan melakukan coding ke ESP32 kita yang akan bertujuan untuk mengirimkan data secara mqtt, sehingga dibutuhkan library "pubsubclient" yang  bisa kalian install seperti biasanya. Namun karena ada keterbatasan maksimum teks yg bisa dikirim, maka kita butuh melakukan "tweak" terhadap librarynya dan ikuti saja langkah berikut:


1. Masuk ke folder arduino kamu lalu menuju libraries/pubsubclient/src dan cari file bernama pubsubclient.h lalu edit menggunakan teks editor. Temukan item bernama #define MQTT_MAX_PACKET_SIZE 256 , lalu ganti menjadi 50000 seperti gambar dibawah:




2. Setelah library disimpan, maka dapat melakukan editing coding sebagai acuan dibawah ini, sesuaikan dengan yg kamu pakai.  Saya menggunakan broker : mqtt.telkomiot.id karena masih gratis dan kecepatan serta quotanya dapat digunakan untuk data mqtt yg lumayan panjang. Jadi jika belum punya akunnya silahkan daftar dulu di www.telkomiot.id


//UTS MIKROKONTROLER 2024
//d4 teknik listrik vokasi unesa surabaya
//by: nyoman yudi kurniawan ST

#include <WiFi.h>
#include <SPIFFS.h>
#include <PubSubClient.h>
#include <Base64.h>  

#define tombol 19 //sesuaikan pin tombol yg digunakan

//sesaikan wifi yang kamu pake
const char* ssid = "Nama Wifi";
const char* password = "password";

//Kita gunakan telkomiot sebagai broker, perhatikan baik-baik
const char* mqtt_server = "mqtt.telkomiot.id"; // jangan pernah ubah ini
const char* mqtt_key = "18f8e70xxxxxxxx"; // access key akun
const char* mqtt_token = "18f8e70xxxxxxx"; // token key akun

// topic dan reply silahkan ditambah no kelompok kamu di akhir,
// semisal "/tlunesa/pdam-12" , jangan sampai sama kelompok lain 
const char* topic = "/tlunesa/pdam"; 
const char* reply = "/tlunesa/pdam/reply"; 

WiFiClient espClient;
PubSubClient client(espClient);

// Function untuk terhubung ke wifi
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print(F("UTS Mikrokontroler 2024 - Menghubungkan ke "));
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println(F("WiFi Terhubung.."));
}

// Function untuk koneksi MQTT
void reconnect() {
  while (!client.connected()) {
    Serial.print(F("Mencoba koneksi MQTT ..."));
    String clientId = "Unesa-d4-";
    clientId += String(random(0xffff), HEX);
    // menghubungkan..
    if (client.connect(clientId.c_str(),mqtt_key,mqtt_token)) {
      Serial.println(F("Terhubung ! dan Subscribe"));
      client.subscribe(reply);
    } else {
      Serial.print(F("failed, rc="));
      Serial.print(client.state());
      delay(5000);
    }
  }
}

void setup() {

  pinMode(tombol, INPUT);
  Serial.begin(9600);

  // Inisialisasi SPIFFS
  if (!SPIFFS.begin()) {
    Serial.println(F("SPIFFS Mount gagal"));
    return;
  }

  // Inisialisasi WiFi and MQTT
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

 //jika tombol ditekan (aktif low)
 if (!digitalRead(tombol))
 {
  Serial.println("");
  Serial.println(F("Tombol Ditekan.."));
  
  // buka gambar di binary mode, catatan : maksimal 30kb
  File file = SPIFFS.open("/pdam.jpg", "rb");
  if (!file) {
    Serial.println(F("Gagal membuka file di spiffs"));
    return;
  }

  // Read the file size
  size_t fileSize = file.size();
  Serial.print("File size: ");
  Serial.println(fileSize);

  // memesan alamat memory
  uint8_t* buffer = (uint8_t*)malloc(fileSize);
  if (buffer == nullptr) {
    Serial.println(F("Kesalahan mengalokasi buffer memori"));
    file.close();
    return;
  }

  // Baca data binarry ke buffer
  file.read(buffer, fileSize);
  file.close();

  // Encode gambar dalam Base64
  String encodedImage = base64::encode(buffer, fileSize);

  // bersihkan buffer
  free(buffer);

  // Publish ke topik MQTT
  
 if (client.publish(topic, encodedImage.c_str())) {
    Serial.println(F("Gambar berhasil di publish"));
  } else {
    Serial.println(F("Gagal mengirim gambar"));
  }
  // Biar brokernya gak tewas
  delay(1000);
 }   
}

//callback untuk membaca hasil subscribe/reply

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print(F("Pesan masuk ["));
  Serial.print(topic);
  Serial.print(F("]  Pembacaan Meter :"));
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
 

}

3. Setelah sukses melakukan upload coding, kalian bisa menggunakan aplikasi MQTT seperti mqtt.fx untuk mengetest apakah data berhasil terkirim atau tidak (tentunya setelah tombol dipencet) dengan bantuan aplikasi online base64 decoding : https://base64.guru/converter/decode/image




Google colab merupakan fasilitas gratis dari google untuk meng-explore dunia cloud computing. Kali ini kita akan manfaatkan google cloud untuk mengolah data gambar kemudian melakukan komputasi AI melalui API yolo-roboflow untuk menterjemahkan data gambar meter pdam menjadi data pembacaan meter pdam.  Lakukan langkah berikut untuk membuat cloud server pembaca meter pdam di google colab :


1. Buka google colab ( https://colab.research.google.com/ ) dan login menggunakan akun google kalian. Buatlah notebook baru lalu beri nama sepantasnya. Koneksikan dengan runtime dan lakukan langkah pertama memasukkan perintah intalasi library seperti berikut :


#instal dependecies dulu biar gak salah paham
!pip install paho-mqtt==1.6.0
!pip install inference


Proses mungkin agak lama dan ada warning untuk Mulai Ulang sesi, lakukan saja seperti gambar:



2. Lanjutkan dengan menambahkan coding python sesuai contoh berikut, lalu jalankan dengan panah di kiri atas:

#UTS MIKROKONTROLER 2024
#d4 teknik listrik vokasi unesa surabaya
#by: nyoman yudi kurniawan ST

import cv2
from inference_sdk import InferenceHTTPClient
from google.colab.patches import cv2_imshow
from random import randrange
import base64
import numpy as np
import time
from paho.mqtt import client as mqtt_client


# Inisialisasi broker , samakan dengan script di esp32

broker_address="mqtt.telkomiot.id"
broker_port=1883
mqtt_key = "18f8e70xxxxxxxxxx"
mqtt_token = "18f8e70xxxxxxxxx"
topic = "/tlunesa/pdam"
reply = "/tlunesa/pdam/reply"



#koneksi ke broker
def connect_mqtt() -> mqtt_client:
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Berhasil Terhubung MQTT Broker!")
        else:
            print("Gagal koneksi mqtt, return code %d\n", rc)
    def on_publish(client,userdata,result):
        print("data reply terkirim ke broker")

    client= mqtt_client.Client(f'unesa-client-{randrange(0,1000)}')
    client.on_connect = on_connect
    client.on_publish = on_publish
    client.username_pw_set(mqtt_key,mqtt_token)
    client.connect(broker_address,broker_port, 60 )

    return client


#subscribe ke mqtt broker
def subscribe(client: mqtt_client):

    client.subscribe(topic)
    client.on_message = on_message


def on_message(client, userdata, message):

    print("Data foto masuk...")
    # Get the payload (Base64-encoded image)
    base64_image = message.payload.decode('utf-8')

    # Decode the Base64 string to binary image data
    image_data = base64.b64decode(base64_image)

    # Convert the binary data to a NumPy array
    np_arr = np.frombuffer(image_data, np.uint8)

    # Decode the image from the NumPy array
    image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)

    #terhubung dengan server Yolo / roboflow
    #jika API key nya penuh, kalian bisa daftar gratis sendiri
    CLIENT = InferenceHTTPClient(
        api_url="https://detect.roboflow.com",
        api_key="fuOy83MqlC1LtKZ25J0p" 
        )
    #lakukan pendeteksi object dengan model yolo
    results = CLIENT.infer(image, model_id="water-meter-dataset/1")


    # mendapatkan prediksi object dari result
    predictions = results['predictions']
    # Mengecek prediksis dan mengambar boxes
    for prediction in predictions:
        # Get the bounding box coordinates
        x = int(prediction['x'])
        y = int(prediction['y'])
        width = int(prediction['width'])
        height = int(prediction['height'])

        # Menggambar bounding box pada gambar meter
        cv2.rectangle(image, (x-int(width/2), y-int(height/2)), (x + int(width/2), y + int(height/2)), (0, 0, 255), 2)
        # Ambil class ID dari angka meter
        class_id = prediction['class']
        # Tambahkan nomer meter pada box 
        cv2.putText(image, class_id, (x-int(width/2), y+height+5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2)

    #tampilin gambar hasil pengolahan yolo
    cv2_imshow(image)
    # Sorting the predictions list by 'x'
    sorted_predictions = sorted(results["predictions"], key=lambda d: d["x"])

    # penggabungan class dari nomer menjadi teks
    class_order_numbers = [int(item["class"]) for item in sorted_predictions]
    combined_number = str("".join(map(str, class_order_numbers)))

    # Jadi deh angka pembacaan meter, lalu publish kembali ke topic reply
    print( f'pembacaan meter pdam:{combined_number}')
    client.publish(reply, combined_number)



try:
    client = connect_mqtt()
    subscribe(client)

    # Start the MQTT loop 
    client.loop_start()

    time.sleep(600)  #biargak kelamaan

except KeyboardInterrupt:
    print("KeyboardInterrupt terdeteksi, stop mqtt loop...")

finally:
    client.loop_stop()
    client.disconnect()
    print("MQTT loop selesai dan client terputus")


3. Hasilnya sebagai berikut , dan pada serial monitor / debug arduino ide juga terkirim angka pembacaan meter




4. Kreatifitas kalian bisa tambahkan LCD / OLED untuk menampilkan data pembacaan meter di display yang kalian pilih. Bisa juga LED berkedip jika ada reply yg masuk, sesuaikan dengan kemampuan kalian saja. 


Hasil paling baik dari UTS mahasiswa saya dapat dilihat pada video berikut :










Share:

Selasa, 01 Oktober 2024

[telkomiot.id] Pengiriman data DHT11 menggunakan modem SIM800 - full AT command

 


Untuk dapat mengikuti praktek yang saya tampilkan ditulisan ini, maka sebelumnya pembaca sebaiknya mengikuti 2 tulisan sebelumnya yaitu :

  • Pengiriman data sensor dengan REST API / POST disini 
  • Bermain SMS gateway dengan modem simcom disini

Dengan membaca 2 tulisan diatas mungkin dapat memberikan gambaran setup hardware dan perintah-perintah dasar yang akan dipakai terutama AT COMMAND untuk modem simcom yang kali ini akan kita manfaatkan sebagai pengirim data HTTP / POST ke REST API. Daripada bingung, kita coba mengirimkan secara POST menggunakan chrome extension "Talend API Tester" yang dulu pernah sudah dijelaskan pada tulisan sebelumnya. 



Mungkin sedikit akan membingungkan bagi yang tidak terbiasa kirim mengirim teks http, namun saya tekankan gak perlu takut karena yg dikirimkan adalah teks http yang sudah memiliki pola pasti dan tinggal mengikuti saja dan menyesuaikan terutama dibagian authorization credential (access key) dimana pada telkomiot menggunakan accesss:token dengan enkripsi base64.

Sedangkan di level komunikasi modem simcom,  AT Command yg digunakan dulu pernah dibahas ( baca disini ),  dimana secara garis besar urutan untuk modem sim800 terhubung ke network internet 2G/GPRS  adalah sebagai berikut:

void connectToNetwork() {
  sim808.println("AT");
  delay(1000);
  sim808.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
  delay(1000);
  sim808.println("AT+SAPBR=3,1,\"APN\",\"internet\"");
  delay(1000);
  sim808.println("AT+SAPBR=1,1");
  delay(2000);
  sim808.println("AT+SAPBR=2,1");
  delay(1000);
}

Untuk mengecek IP yang diberikan oleh operator, pada function diatas terdapat AT+SAPBR=2,1 , dan jika sudah terkoneksi dengan benar maka kedip dari lampu status modem menjadi lebih cepat sekitar 100ms periodenya. Lalu bagaimana dengan koneksi ke server REST API dan mengirimkan data secara POST? Berikut urutannya :


void sendDataToAPI(String data) {
  // Gabungkan accessKey dan accessToken, lalu encode ke dalam Base64
  String credentials = accessKey + ":" + accessToken;
  String base64Credentials = base64_encode(credentials.c_str());

  sim808.println("AT+HTTPINIT"); // Inisialisasi layanan HTTP
  delay(1000);

  sim808.println("AT+HTTPPARA=\"CID\",1"); // Atur identifikasi konteks ke 1
  delay(1000);

  sim808.println("AT+HTTPPARA=\"URL\",\"" + apiUrl + "\""); // Tentukan URL endpoint API
  delay(1000);

  sim808.println("AT+HTTPPARA=\"CONTENT\",\"application/json\""); // Tentukan tipe konten ke JSON
  delay(1000);

  // Tambahkan header Authorization dengan kredensial yang sudah di-encode Base64
  sim808.println("AT+HTTPPARA=\"USERDATA\",\"Authorization: Basic " + base64Credentials + "\"");
  delay(1000);

  // Persiapkan untuk mengirim data POST beserta panjangnya
  sim808.println("AT+HTTPDATA=" + String(data.length()) + ",10000"); // Tentukan panjang data
  delay(1000);

  sim808.print(data); // Kirim data JSON
  delay(10000); // Tunggu hingga data diunggah

  sim808.println("AT+HTTPACTION=1"); // Eksekusi permintaan HTTP POST (aksi 1 adalah POST)
  delay(5000); // Tunggu respons dari server

  sim808.println("AT+HTTPREAD"); // Baca respons dari server
  delay(1000);
  while (sim808.available()) {
    Serial.write(sim808.read()); // Tampilkan respons untuk debugging
  }

  sim808.println("AT+HTTPTERM"); // Akhiri sesi HTTP
  delay(1000);
}

Penjelasan Masing-Masing Perintah AT

AT+HTTPINIT:

Ini digunakan untuk menginisialisasi layanan HTTP di SIM800. Sebelum melakukan permintaan HTTP (GET atau POST), modem harus dipersiapkan dengan perintah ini.

Respons: OK jika layanan HTTP berhasil diinisialisasi.

AT+HTTPPARA="CID",1:

CID adalah "Context Identifier" yang memberitahu SIM800 koneksi GPRS mana yang akan digunakan. Di sini, CID=1 merujuk pada koneksi GPRS yang diatur dengan AT+SAPBR=1,1 di fungsi connectToNetwork().

Respons: OK jika pengaturan identifikasi konteks berhasil.

AT+HTTPPARA="URL","<your API URL>":

Perintah ini menetapkan URL dari server tempat data akan dikirim. Di sini, Anda memasukkan URL API (http://publish-data.telkomiot.id/v2.0/pubs/...).

Respons: OK jika URL berhasil diatur.

AT+HTTPPARA="CONTENT","application/json":

Perintah ini menentukan tipe konten yang dikirim. Dalam hal ini, Anda mengirim data dalam format JSON, jadi tipe konten diatur ke "application/json".

Respons: OK jika tipe konten berhasil diatur.

AT+HTTPPARA="USERDATA","Authorization: Basic <Base64 credentials>":

Perintah ini menambahkan header kustom ke permintaan HTTP. Di sini, kita menggunakannya untuk menambahkan header Authorization, yang berisi kredensial yang sudah di-encode dalam Base64 (gabungan access_key:access_token). Ini adalah cara standar untuk melakukan autentikasi dengan API.

Respons: OK jika header berhasil ditambahkan.

AT+HTTPDATA=<length>,<timeout>:

Perintah ini mempersiapkan SIM808 untuk menerima data untuk permintaan POST. Parameter <length> menentukan jumlah byte data yang akan dikirim, dan <timeout> adalah waktu (dalam milidetik) yang diizinkan untuk mengirim data. Pada kode di atas, data.length() memberikan panjang payload JSON, dan 10000 (10 detik) diberikan sebagai batas waktu.

Respons: DOWNLOAD jika SIM808 siap menerima data.

sim808.print(data):

Ini mengirim data sebenarnya (payload JSON) ke SIM800 setelah perintah AT+HTTPDATA. Modem sekarang mengetahui berapa banyak data yang akan dikirim dan menunggu dalam periode waktu yang ditentukan.

AT+HTTPACTION=1:

Perintah ini memulai permintaan HTTP POST (1 menandakan POST). SIM800 akan mengirimkan data yang telah disiapkan sebelumnya (dalam format JSON) ke URL yang ditentukan dengan header yang telah ditentukan.

Respons: OK diikuti dengan kode status HTTP, seperti 200 untuk sukses atau 404 untuk tidak ditemukan.

AT+HTTPREAD:

Setelah aksi POST selesai, perintah ini digunakan untuk membaca respons dari server. Respons ini bisa berisi informasi penting, seperti apakah permintaan berhasil.

Respons: Isi tubuh respons HTTP yang dikirim oleh server, ditampilkan di monitor Serial untuk keperluan debugging.

AT+HTTPTERM:

Ini digunakan untuk mengakhiri sesi HTTP dan melepaskan sumber daya yang digunakan oleh SIM800 untuk layanan HTTP. Sebaiknya selalu menutup sesi setelah menyelesaikan permintaan.

Respons: OK jika layanan HTTP berhasil diakhiri.


Dengan kombinasi perintah AT diatas ini, Anda bisa menghubungkan Arduino ke server web (REST API) melalui SIM800, memungkinkan untuk mengirim data sensor ke platform IoT melalui jaringan seluler.




Pada praktek yang sudah saya buat sebelumnya, saya menggunakan sensor DHT11 yang akan memberikan data suhu dan kelembaban dan selanjutnya dikirim ke telkomiot.id secara POST. Pada dashbord serta event trigger bisa disesuaikan dengan keinginan seperti yang telah dibahas pada tulisan sebelumnya. 


Koding Lengkap :


#include <SoftwareSerial.h>
#include <DHT.h>

#define DHTPIN 13      // DHT11 connected to pin 13
#define DHTTYPE DHT11  // DHT 11 sensor type
DHT dht(DHTPIN, DHTTYPE);

SoftwareSerial sim808(2, 3); // RX, TX for SIM800

String apiUrl = "http://publish-data.telkomiot.id/v2.0/pubs/APP111111111/DEV222222222"; //sesuaikan dengan endpoint aplication telkomiot
String accessKey = "11111111111111111";    //sesuaikan dengan akun telkomiot.id
String accessToken = "22222222222222222";

void setup() {
  Serial.begin(9600);
  sim808.begin(9600);
  dht.begin();
  delay(5000); // Give time for SIM800 to initialize

  connectToNetwork();
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  String postData = "{\"suhu\": \"" + String(t) + "\", \"humi\": \"" + String(h) + "\"}";
  Serial.println(postData);
  sendDataToAPI(postData);
  delay(10000); // Send data every 10 seconds
}

void connectToNetwork() {
  sim808.println("AT");
  delay(1000);
  sim808.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
  delay(1000);
  sim808.println("AT+SAPBR=3,1,\"APN\",\"internet\"");
  delay(1000);
  sim808.println("AT+SAPBR=1,1");
  delay(2000);
  sim808.println("AT+SAPBR=2,1");
  delay(1000);
}

void sendDataToAPI(String data) {
  // Combine accessKey and accessToken, then encode them in Base64
  String credentials = accessKey + ":" + accessToken;
  String base64Credentials = base64_encode(credentials.c_str());

  sim808.println("AT+HTTPINIT");
  delay(1000);
  sim808.println("AT+HTTPPARA=\"CID\",1");
  delay(1000);
  sim808.println("AT+HTTPPARA=\"URL\",\"" + apiUrl + "\"");
  delay(1000);
  sim808.println("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
  delay(1000);

  // Add Authorization header
  sim808.println("AT+HTTPPARA=\"USERDATA\",\"Authorization: Basic " + base64Credentials + "\"");
  delay(1000);

  sim808.println("AT+HTTPDATA=" + String(data.length()) + ",10000");
  delay(1000);
  sim808.print(data);
  delay(10000); // Time to send the data
  
  sim808.println("AT+HTTPACTION=1"); // Start the HTTP POST
  delay(5000);
  
  sim808.println("AT+HTTPREAD");
  delay(1000);
  while (sim808.available()) {
    Serial.write(sim808.read()); // Display response
  }
  
  sim808.println("AT+HTTPTERM"); // End HTTP session
  delay(1000);
}

String base64_encode(const char* input) {
  const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  String encoded = "";
  int i = 0, j = 0;
  unsigned char char_array_3[3], char_array_4[4];

  while (*input) {
    char_array_3[i++] = *(input++);
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for (i = 0; i < 4; i++)
        encoded += b64_alphabet[char_array_4[i]];
      i = 0;
    }
  }

  if (i) {
    for (j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; j < i + 1; j++)
      encoded += b64_alphabet[char_array_4[j]];

    while ((i++ < 3))
      encoded += '=';
  }

  return encoded;
}

Share:

Minggu, 21 Juli 2024

[telkomiot.id] Pengolahan Data Lorawan Menjadi Grafik Dengan Python

 


Setelah berhasil menggunakan API dengan benar pada tulisan sebelumnya, kini saya lanjutkan pengolahan data yang dikirimkan menggunakan LoRaWan pada telkomIOT. Alat yang saya gunakan masih yang lama ketika 3 tahun lalu berkenalan dengan lorawan yaitu hardware mikrokontroler berbasis arduino nano dengan modul lora sx1276 - 915Mhz.



Jadi jika pembaca baru berkenalan dengan lorawan, silahkan baca dulu klik disini karena scriptnya masih sama hanya beda di authentifikasi lorawannya saja kini menuju ke telkomiot. Dan juga yang mencolok adalah antenanya yaitu setelah saya dan anak-anak magang serta tugas akhir dari Unesa Surabaya - prodi D4 teknik listrik berhasil meneliti antena dipole + yagi sederhana (pake antena tv) sebagai pengirim sinyal lebih baik (baca disini). Hasilnya kini dalam rumah yang dulunya sangat susah kirim data akibat pembangunan gedung tinggi di sebelah rumah, kini dapat mengirimkan dengan lancar sekali





Dan sesuai contoh di tulisan sebelumnya maka dapat diolah data yang diterima menjadi widget seperti gambar dibawah ini.



Untuk pengolahan data diluar telkomiot sayangnya tidak bisa terlalu realtime dikarenakan mqtt yang belum jalan, yang disediakan hanya berupa REST API secara GET yang dinamakan API Integration seperti gambar dibawah.




Dan kalau kita coba pada postman atau Talend API Tester hasilnya berupa 10 data terakhir dari data lorawan yang berhasil di UPLINK ke database telkomiot.




Karena datanya berjumlah 10 maka sangat terbantu untuk membuat grafik menggunakan platform apapun baik java (node.js), php atau kesukaan saya menggunakan python seperti script berikut ini:


# Script Untuk Mengambil Data Lorawan TelkomIot
# by Nyoman yudi - www.aisi555.com
# ahocool@gmail.com 08155737755


import requests
import json
import base64
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from dateutil import parser
from datetime import datetime
import signal
import sys

# Telkom IoT API details , sesuaikan
API_URL = 'https://api-data.telkomiot.id/api/v2.0/APPxxxxxxxxxxxxx/DEVxxxxxxxxxxxx/lasthistory'
ACCESS_KEY = 'aaaaaaaaaaaaaaaa'
TOKEN_KEY = 'bbbbbbbbbbbnnnnnn'

# Encode accesskey:tokenkey to Base64
auth_string = f'{ACCESS_KEY}:{TOKEN_KEY}'
auth_bytes = auth_string.encode('utf-8')
auth_base64 = base64.b64encode(auth_bytes).decode('utf-8')

HEADERS = {
'Authorization': f'Basic {auth_base64}',
'Content-Type': 'application/json'
}

# Lists to store timestamps, temperature, and humidity data
timestamps = []
temperature_data = []
humidity_data = []

# Function to fetch data from Telkom IoT API
def fetch_data():
try:
response = requests.get(API_URL, headers=HEADERS)
if response.status_code == 200:
data = response.json()
timestamps.clear()
temperature_data.clear()
humidity_data.clear()
for entry in data:
timestamp = parser.isoparse(entry['time'])
sensor_data = json.loads(entry['data'])
temperature = sensor_data['suhu']
humidity = sensor_data['humi']
timestamps.append(timestamp)
temperature_data.append(temperature)
humidity_data.append(humidity)
else:
print(f"Failed to fetch data: {response.status_code}")
except Exception as e:
print(f"Error fetching data: {e}")


# Function to update the graph
def update_graph(i):
fetch_data()
ax.clear()
width = 0.4 # Width of the bars
indices = range(len(timestamps))

# Create bars for temperature and humidity
bars1 = ax.bar([x - width / 2 for x in indices], temperature_data, width, label='Temperature (°C)')
bars2 = ax.bar([x + width / 2 for x in indices], humidity_data, width, label='Humidity (%)')

# Set the labels
ax.set_xlabel('Time')
ax.set_ylabel('Value')
ax.set_xticks(indices)
ax.set_xticklabels([ts.strftime('%H:%M:%S') for ts in timestamps], rotation=45)
ax.legend(loc='upper left')


# Function to handle graceful shutdown
def signal_handler(sig, frame):
print('Stopping the script...')
sys.exit(0)


# Set up the plot
fig, ax = plt.subplots()

# Animate the plot
ani = animation.FuncAnimation(fig, update_graph, interval=10000, cache_frame_data=False) # Update every 10 seconds

# Register the signal handler
signal.signal(signal.SIGINT, signal_handler)

# Display the plot
plt.show()

Dan hasilnya cukup dapat dihandalkan lhooo....



Share:

[telkomiot.id] Mengirim Data DHT11 - ESP8266 via REST API dan Menampilkan di Widget & Notif Ke Email

 


Walau sempat galau karena MQTT gagal dikirimkan ke platform Telkomiot.id, tidak usah nyinyir berlebihan karena ada satu cara yang umum dilakukan untuk kirim-terima data yaitu via REST API / HTTP/ POST . Langsung aja yuk kita mencoba menggunakan software semacam postman untuk mengirimkan data secara HTTP, dan saya pilihkan yang lebih mudah yaitu chrome extension bernama "Talend API Tester". Langkah-langkahnya cukup straight forward, kita cek dulu alamat endpoint dari REST API nya pada console :application/device di website telkomiot.




Sesuai petunjuk bapak presiden...ehhh salah..dokumentasi yang sangat sedikit, saya menerka bahwa akan ada authentification /authorization berdasarkan access key dan token key untuk access  api dan biasanya ditambahkan pada header berupa "authorization". Lanjutkan aja dengan memasukkan pasangan key yang benar



Header yang gak kalah penting adalah "Content-Type" : "application/json" dan langsung saja saya coba dan berhasil mengirimkan data suhu dan humi ke telkomiot....yeahhh



Bagaimana dengan mengirimkan secara hardware? saya pilihkan microcontroller + sensor sejuta umat paling murah meriah : Wemos + DHT11.



Bagi yang masih awam dengan wemos/esp8266 untuk mengukur suhu dengan DHT11, dapat belajar dulu seri tulisan IOT yang full menggunakan rangkaian seperti diatas ( baca dulu klik disini )


*/telkomiot.id testing from www.aisi555.com
  by nyoman yudi kurniawan ahocool@gmail.com
  08155737755 - surabaya 2024
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include "DHT.h"
#include <base64.h>

// wifi kamu sesuaikan
const char* ssid = "hotspothp";
const char* password = "tanyasebelah";

// Domain http publish dari device DHT11 ditelkomiot, sesuaikan
const char* serverName = "http://publish-data.telkomiot.id/v2.0/pubs/APP1111111111/DEV222222222223";

// account key dari telkomiot
String AccessKey   = "aaaaaaaaaaaaaaaa";
String AccessToken = "bbbbbbbbbbbbbbbb";
String auth;
String authHeader;

const int dhtPin = D3; //Sesuaikan pin DHT
#define DHTTYPE DHT11  //Sensor DHT11
DHT dht(dhtPin, DHTTYPE); 

//timer untuk membaca DHT11 tiap 10 detik
unsigned long lastTime = 0;
unsigned long timerDelay = 10000;

WiFiClient client;
HTTPClient http;

void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.println("www.aisi555.com ==> telkomiot.id testing");
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Terhubung wifi : ");
  Serial.print(ssid);
  Serial.print("  IP : ");
  Serial.println(WiFi.localIP());


   //auth header untuk POST
  auth = AccessKey+ ":" + AccessToken;
  authHeader = "Basic " + base64::encode(auth);
 
}

String SendTempHumid(){ // 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() {
  //Send HTTP POST request tiap 10 detik
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){

      
      // server untuk kirim REST API
      http.begin(client, serverName);
      
      // Specify content-type header
      http.addHeader("Authorization", authHeader);
      http.addHeader("Content-Type", "application/json");
      // Data to send with HTTP POST
      String httpRequestData = SendTempHumid();           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
      

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
        
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi terputus");
    }
    lastTime = millis();
  }
}


Hasilnya bagaimana  ?




Penjabarannya seperti berikut :


Library :

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include "DHT.h"
#include <base64.h>


Yang digunakan library standar ESP8266 untuk kirim terima data via http dan sudah tersedia semua secara default. Yang mungkin berbeda adalah base64.h yang jarang digunakan, kali ini tujuannya untuk meng-enkripsi auth key sebagai standar auth pada REST API.


Rest API endpoint + auth:

// Domain http publish dari device DHT11 ditelkomiot, sesuaikan
const char* serverName = "http://publish-data.telkomiot.id/v2.0/pubs/APP1111111111111111/DEV222222222222222";

// account key dari telkomiot
String AccessKey   = "aaaaaaaaaaaaaaaa";
String AccessToken = "bbbbbbbbbbbbbbbb";
String auth;
String authHeader;

WiFiClient client;
HTTPClient http;


Base 64 auth Header :

   //auth header untuk POST
  auth = AccessKey+ ":" + AccessToken;
  authHeader = "Basic " + base64::encode(auth);


Baca DHT 11 :

String SendTempHumid(){ // 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) +"}"); 
  }

Kirim secara post :

      // server untuk kirim REST API
      http.begin(client, serverName);
      
      // Specify content-type header
      http.addHeader("Authorization", authHeader);
      http.addHeader("Content-Type", "application/json");
      // Data to send with HTTP POST
      String httpRequestData = SendTempHumid();           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
      

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
        
      // Free resources
      http.end();


Lumayan straight forward, hanya meniru apa yang sudah dilakukan pada aplikasi testing REST API sebelumnya, dan jika data json / dht11 benar maka pada monitor terminal muncul ini.


Http response 200 artinya data diterima dengan benar, sedangkan jika 400 berarti json pengambilan data dht11 nya salah.

Lalu bagaimana cara menampilkan gauge dan grafik seperti gambar paling diatas? tinggal menuju menu personal dashboard , lalu buat dashboard kamu serta tambahkan widget yang dihubungkan ke device kamu.



Dan jika benar, maka akan muncul widget berupa gauge-line chart-bar chart sesuai yang kamu pilih. Dan tiap widget ini dapat ditempelkan pada website kamu lhoo..



Dan bisa kirim alarm lewat  event trigger ke email lhooo ...






Walau kekecewaan masih tersirat pada saya yang pencinta MQTT ini, namun dengan praktek diatas agak sedikit terobati, dan semoga kalian bisa mencobanya sendiri

Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (14) antares (11) arduino (28) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (26) euro2020 (13) gcc (1) gsm (1) iklan (1) infrared (2) Input Output (3) iot (76) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (11) lorawan (2) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (2) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (8) radio (28) raspberry pi (9) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (167) television (28) telkomiot (5) transistor (2) troubleshoot (3) tulisan (94) tutorial (108) tv digital (6) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3) yolo (7)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika