Untuk dapat mengikuti praktek yang saya tampilkan ditulisan ini, maka sebelumnya pembaca sebaiknya mengikuti 2 tulisan sebelumnya yaitu :
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;
}
0 komentar:
Posting Komentar