สร้าง UDP server รับและส่งข้อมูล NBIoT ไปยัง LineNotify และ Blynk ด้วย Node-RED ตอนที่ 1
ลงไม้ลงมือ : “สร้าง UDP server รับและส่งข้อมูล NBIoT ไปยัง LineNotify และ Blynk ด้วย Node-RED ตอนที่ 1”
บทความ โดย… วิสิทธิ์ เวียงนาค
หลังจากใช้งาน NBIoT มาได้สักระยะหนึ่ง พบว่าปัญหาการส่ง Payload ไปยังอุปกรณ์ end node ทำได้ไม่ง่ายนัก เพราะ NBIoT ใช้ IP Address แบบ DHCP แจกให้กับตัวอุปกรณ์ NBIoT Shield ที่เชื่อมต่อ แน่นอนว่าทุกครั้งที่มีการบูตของ NBIoT Shield มันจะได้รับ IP Address ใหม่ทุกครั้ง และในแพลตฟอร์ม AIS Magellan นั้น ก็ยังไม่รองรับการส่ง Downlink นอกจากนั้นการเชื่อมต่อไปยังบริการ social media อื่นๆ เช่น LineNotify และ Twitter นักพัฒนาจำต้องสร้างขึ้นมาเอง และถ้าต้องการเชื่อมต่อกับ Application Blynk ที่หลายคนใช้งานกันอยู่และคุ้นเคยกันดีบนเครือข่าย WiFi เข้ากับ NBIoT แล้ว ก็ต้องพัฒนาและหาแนวทางกันเอง หลายท่านที่เป็นมือใหม่ เพิ่งเริ่มศึกษา คงปวดหัวและเสียเวลาไม่น้อยสำหรับเรื่องนี้
ผู้เขียนเข้าใจปัญหานี้ดี จึงขอนำเสนอแนวทาง การสร้าง UDP server รับและส่งข้อมูล NBIoT ไปยัง LineNotify และ Blynk ด้วย Node-RED แบบง่ายๆ เพื่อให้นักพัฒนาได้เห็นภาพและเข้าใจกระบวนการทำงาน เพื่อนำไปประยุกต์สร้างโปรเจคต่อไป
อุปสรรค์การพัฒนา NBIoT
หลังจากที่ AIS ได้เปิดให้บริการ NBIoT ทำให้วงการ IoT ในประเทศไทยตื่นตัวกันมาก เพราะมันมีสัญญาณคลอบคลุมทั้งในกรุงเทพและต่างจังหวัด ทำให้ความฝันการพัฒนา IoT ใกล้เข้ามาอีกขั้น ผู้เขียนได้มีโอกาสใช้ NBIoT หลังจากที่ AIS เปิดให้บริการไม่นาน เพราะได้จับจอง NBIoT Shield ของทาง AIS เป็นกลุ่มแรกๆ หลังจากได้ใช้งานมาสักระยะหนึ่ง พบว่าการส่งข้อมูลจาก end node ผ่าน NBIoT Shield เป็นไปอย่างง่าย เพราะทาง AIS มี Library บน Arduino IDE ให้ใช้งาน ทำให้การส่งข้อมูลเป็นไปอย่างสะดวก
แต่ปัญหาใหญ่สำหรับการใช้งาน NBIoT คือการทำ Downlink หรือการส่งข้อมูลกลับไปที่อุปกรณ์ end node เพราะ IP Address ที่ได้รับเป็นแบบ DHCP ที่มันพร้อมจะเปลี่ยนเป็นเลขใหม่ตลอดเวลา และตอนนี้แพลตฟอร์ม AIS Magellan ยังไม่รองรับ และทาง AIS ยังไม่ได้เปิดให้บริการ UDP server และ CoAP server ทำให้นักพัฒนาต้องตั้ง server ขึ้นมาใช้งานเอง ไหนจะเรื่อง security การเข้ารหัสข้อมูลอีก แน่นอนว่านักพัฒนามือใหม่ต้องออกแรงมากพอสมควรเลย
เนื้อหาของบทความ
ผู้เขียนขอจัดเรียงเนื้อหาออกเป็น 6 หัวข้อย่อย เพื่อให้ง่ายต่อการศึกษา เป็นขั้นเป็นตอนตามนี้
- การใช้ Node-RED สร้าง UDP server และการถอด NBIoT Payload ที่ได้มาให้อยู่ในรูปของ JSON ที่พร้อมใช้งาน
- การสกัดหา IP Address จริง ของ end node เมื่อส่ง payload มายัง UDP server และการสร้าง Flow ของ Node-RED สำหรับส่ง payload กลับไปยัง end node (Downlink)
- การใช้ Node-RED สร้าง Flow สำหรับ RESTful แบบ POST/GET เพื่อให้บริการส่ง payload กลับไปยัง end node (Downlink) ผ่านทาง Web Browser และการใช้เครื่องมือทดสอบ Postman
- การส่ง Payload ทีได้จาก UDP server ไปให้ LineNotify เพื่อแจ้งเตือน
- การส่ง Payload ที่ได้จาก UDP server ไปให้ Blynk API เพื่ออัพเดท Widget ใน Blynk Mobile Application
- การประยุกต์ใช้งาน สร้าง UDP server สำหรับการเก็บ Payload จาก end node และ IP Address ไว้ในฐานข้อมูล InfluxDB รวมถึงสร้าง Flow เพื่อ query หา IP Address ล่าสุด และการส่ง Downlink ไปยัง NBIoT end node แบบอัตโนมัติ
อุปกรณ์และเครื่องมือที่ใช้ในการทดลองครั้งนี้ มีดังต่อไปนี้
- บอร์ด SparkFun RedBoard UNO จำนวน 1 บอร์ด
- เซ็นเซอร์วัดอุณภูมิและความชื้น DHT11 จำนวน 1 ตัว
- โมดูลเซ็นเซอร์วัดความเข้มแสง LDR จำนวน 1 ตัว
- NBIoT Shield ของ AIS จำนวน 1 ตัว
- Arduino IDE เวอร์ชั่น 1.8.5
1) การใช้ Node-RED สร้าง UDP server และการถอด NBIoT Payload ที่ได้มาให้อยู่ในรูปของ JSON ที่พร้อมใช้งาน
ผู้เขียนขอข้ามขั้นตอนการติดตั้ง Node-RED นะครับ สำหรับใครที่ยังไม่เคยติดตั้ง และยังไม่มี Node-RED ใช้ ขอแนะนำให้ท่านหาขั้นตอนการติดตั้งในอินเตอร์เน็ตก่อน แนะนำให้ติดตั้ง Node-RED บน Cloud สำหรับผู้เขียนเองได้เลือกติดตั้ง Node-RED ไว้ที่ digital ocean เพราะถูกและใช้งานได้ดี
การสร้างโฟล์ เริ่มจาก ลาก node ของ udp ในฝั่งของ input ออกมาที่ work space ตามรูปข้างล่าง
จากนั้นให้ double click ที่ node udp ให้ตั้งค่าตามรูปข้างล่าง แค่นี้ท่านก็ได้ UDP server ไว้ใช้งานเองแล้ว
จากรูปข้างบนจะเป็นการตั้งค่าให้ node รอรับข้อความที่มาจากโปรโตคอล UDP ที่พอร์ต 42302 ใช้ IP แบบ IPV4 และส่งค่าออกไปเป็นแบบข้อความ ตั้งชื่อ node นี้ว่า “NBIOT”
ส่วนโค๊ดของ Arduino IDE ไม่ได้ใช้ไลบรารี่ของ AIS Magellen นะครับ จะส่ง Payload ตรงไปยัง UDP server เลย ก่อนอื่นท่านต้องเช็คก่อนว่า ได้ติดตั้งไลบรารี่ของ NBIoT Shield BC95 เสร็จแล้วหรือยัง ถ้าไม่แน่ใจให้ทำการตรวจเช็ค หรือติดตั้งตามขั้นตอนดังต่อไปนี้ก่อน
ไปที่เมนู Sketch -> Include Library -> Manage Libraries… แล้วพิมพ์คำว่า “BC95” ที่หน้า Library Manager ถ้าพบคำว่า “INSTALLED” เป็นสีเขียวแสดงว่าได้ติดตั้งไลบรารี่แล้ว แต่ถ้าไม่มีให้ติดตั้งให้เรียบร้อย
เซ็นเซอร์วัดอุณภูมิและความชื้น DHT11 จะใช้ไลบรารี่ SimpleDHT ดังนั้นให้ท่านตรวจเช็คอีกทีว่าได้ทำการติดตั้งไปหรือยัง ถ้ายังไม่มีก็ให้ติดตั้งให้เรียบร้อย
ส่วนโค๊ดใน Arduino IDE ให้ท่านระบุ IP Address ของ Server ที่ลง Node-RED ให้ถูกต้อง ในที่นี้คือ 155.5.5.5 และ UDP พอร์ตหมายเลข 42302
//ตัวอย่างการส่ง payload ไปยัง UDP server ด้วย NBIoT#include "AIS_NB_BC95.h"
#include <SimpleDHT.h>int LDRSENSOR = A0;
int DHTPIN = 7;SimpleDHT11 dht11;String apnName = "RSU.NBIOT";
String nodename = "RSU01";
String udpData;String serverIP = "155.5.5.5";
String serverPort = "42302";AIS_NB_BC95 AISnb;const long interval = 300000; //5 secounds
unsigned long previousMillis = 0;long cnt = 0;void setup()
{
AISnb.debug = true;
Serial.begin(9600);AISnb.setupDevice(serverPort);
String ip1 = AISnb.getDeviceIP();
delay(1000);pingRESP pingR = AISnb.pingIP(serverIP);
previousMillis = millis();}void loop()
{unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
cnt++;
Serial.println(cnt);// read the sensor DHT11
byte temperature = 0;
byte humidity = 0;dht11.read(DHTPIN, &temperature, &humidity, NULL);
while (temperature == 0) {
dht11.read(DHTPIN, &temperature, &humidity, NULL);
Serial.println("DHT11 get failed");
delay(1500);
}// read the sensor LDR
int ldr = analogRead(LDRSENSOR);
udpData = String(nodename + ","
+ int(temperature) + ","
+ int(humidity) + ","
+ ldr + ","
+ cnt
);Serial.println(udpData);UDPSend udp = AISnb.sendUDPmsgStr(serverIP, serverPort, udpData);previousMillis = currentMillis;} //if millisUDPReceive resp = AISnb.waitResponse();}
ให้อัพโหลดโค๊ดไปยังบอร์ด เสร็จแล้วให้เปิด Serial Monitor ขึ้นมา จะพบว่า NBIoT Shield มีการขอการเชื่อมต่อไปยังเครือข่าย และมีการ ping ไปยัง UDP server ที่ระบุไว้ ถ้าสำเร็จจะขึ้นข้อความว่า “Connecting NB-IoT Network..> Connected” และที่ Ping จะแสดงค่า ttl และ rrt ตอบกลับมา ในโค๊ดได้กำหนดการส่ง Payload ไปยัง UDP server ทุกๆ 5 นาที แบบว่าไม่รีบ แต่ถ้าใครใจร้อนก็สามารถปรับเปลี่ยนได้ โดยเปลี่ยนได้ที่บรรทัด const long interval = 300000 ในโค๊ดค่าเริ่มต้นจะเป็น 300000 หรือว่า 5 นาที
############ AIS_NB_BC95 Library by AIS/DEVI V1.0.5 ############
# Reboot Module.
# Module IMEI--> 865555531955555# Firmware ver--> SECURITY,V100R100C10B657SP3 PROTOCOL,V100R100C10B657SP3 APPLICATION,V100R100C10B657SP3 SEC_UPDATER,V100R100C10B657SP3 APP_UPDATER,V100R100C10B657SP3 RADIO,BC95HB-02-STD_900# IMSI SIM--> 525555500055555# Connecting NB-IoT Network..> Connected
################################################################
# Device IP: 10.0.12.109# Ping IP:155.5.5.5,ttl= 52,rtt= 1035
รอประมาณ 5 นาที end node จะทำการอ่านค่าอุณหภูมิและความชื้นสัมพัทธ์จากเซ็นเซอร์ DHT11 และเซ็นเซอร์วัดความเข้มแสง LDR แล้วนำมาสร้างเป็น Payload จากนั้นจะส่งไปยัง UDP server ผ่าน NBIoT ถ้าส่งสำเร็จจะเห็น Message ใน Serial Monitor แสดง Send OK ส่วน Payload จะถูกแปลงให้เป็นข้อความด้วยเลขฐาน 16 (HEX)
################################################################
# Sending Data IP=155.5.5.5 PORT=42302
# Data=52535530312c32352c37352c3238332c31
# Send OK
ทันทีที่ UDP server ใน Node-RED ได้รับ Payload จาก NBIoT ที่หน้าต่าง Message debug จะเห็นข้อความที่ได้รับจาก UDP server ที่แปลงเป็นข้อความดิบส่งมา ในที่นี้คือ “RSU01,25,75,283,1”
ต่อไป ผู้เขียนจะทำการจัดเรียง Payload และสร้างชุดข้อมูลขึ้นมาใหม่ ให้อยู่ในรูป JSON ในขั้นตอนนี้ ให้ท่านลาก node ของ function ออกมาที่ work space ทำการแก้ไขเส้นการเชื่อมโยงให้ถูกต้อง แล้ว double click ที่ node ของ function จากนั้นให้เพิ่ม JavaScript เข้าไป
ให้ double click ที่ node ของ function
ให้ตั้งชื่อ node ว่า “FILLTER” แล้วเพิ่ม JavaScript ตามโค๊ดข้างล่าง
var str = msg.payload;
var data = str.slice(0).split(',');msg.payload = {
"name": data[0],
"sensor0": parseInt(data[1]),
"sensor1": parseInt(data[2]),
"sensor2": parseInt(data[3]),
"cnt": parseInt(data[4])
}return msg;
หลังจากที่สร้าง Flow ใหม่และทำการ deploy เรียบร้อย ให้ลองสังเกตุที่หน้าต่าง Message debug จะพบว่าข้อความที่แสดงเปลี่ยนเป็นรูปแบบ JSON สวยงาม เป็นระเบียบเรียบร้อยและพร้อมนำไปใช้งาน
2) การสกัดหา IP Address จริง ของ end node เมื่อส่ง payload มายัง UDP server และการสร้าง Flow ของ Node-RED สำหรับส่ง payload กลับไปยัง end node (Downlink)
หลังจากที่ NBIoT Shield เชื่อมต่อกับทางเครือข่ายแล้ว มันจะแสดง IP Address ในหน้า Serial Monitor บน Arduino IDE โดยค่า IP Address นี้ จะเป็นแบบ Private IP Address ภายในของทาง AIS เอง มันไม่สามารถนำไปใช้ส่งข้อมูลจากภายนอกเข้าไปได้นะครับ
ถ้าต้องการทราบ IP Address จริง NBIoT ต้องทำอย่างไร ?
มีหลายวิธีเหมือนกันที่สามารถตอบคำถามนี้ได้ แต่แน่นอนว่าต้องออกแรงพอสมความเลย เพราะข้อมูลที่ NBIoT ส่งออกไปเป็นโปรโตรคอล UDP ดังนั้นถ้าจะคุยกันรู้เรื่อง Server ก็ต้องเปิดพอร์ต UDP ไว้รอรับข้อมูลด้วย เพื่อให้เห็นภาพแบบหลากหลายให้เกิดไอเดีย ผู้เขียนจะแสดงวิธีการสกัดเอา IP Address จริง ด้วย Script ภาษาแตกต่างกัน ดังต่อไปนี้
วิธีที่หนึ่ง Python Script
ผู้เขียนจะสร้าง Script บนภาษา Python ซึ่งมันเป็นภาษาที่ขึ้นชื่อว่าเป็นภาษาที่นำไปใช้งานได้อย่างหลากหลาย มีไลบรารี่ให้ใช้มากมาย มีโค๊ดที่สั้น และเป็นที่นิยมมากในขณะนี้ มาให้บริการเป็น UDP server เปิดพอร์ต 42303 รอไว้ จากนั้นให้มันดักดู UDP แพ็คเกจที่ส่งมา แล้วสกัดเอา IP Address ของปลายทางของ end node ที่เป็น IP Address จริง มาแสดงบน console เขียน code สั้นๆ ง่ายๆ ดังต่อไปนี้
# myudp.pyimport socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", 42303))
while True:
data, addr = sock.recvfrom(1024)
print(data, addr)
หลังจากที่ Shield ได้ส่งข้อความ payload “RSU01,24,72,290,1” ผ่านเครือข่าย NBIoT ด้วยโปรโตรคอล UDP ไปยัง UDP server แล้ว ที่ Serial Monitor บน Arduino IDE จะแสดงข้อความที่ส่งไปและสถานะที่ส่ง ในที่นี้คือ “Send OK” ซึ่งหมายความว่าส่งสำเร็จ
################################################################
# Sending Data IP=155.5.5.5 PORT=42303
# Data=52535530312c32342c37322c3239302c31
# Send OK
RSU01,24,72,290,1
ที่ฝั่ง UDP server ที่รัน Python Script ในที่นี้ชื่อ “myudp.py” รอไว้ที่พอร์ต 42303 ทันทีที่มี UDP แพ็คเกจส่งเข้ามา Python Script จะสกัดเอา IP Address จริงมาแสดงบน Console พร้อมแสดงข้อความ Payload ที่รับมา จากตัวอย่าง ได้ IP Address จริงคือ “119.31.119.67” และข้อความคือ “RSU01,24,72,290,1”
root@UDPserver: ~# python myudp.py
('RSU01,24,72,290,1', ('119.31.119.67', 42303))
วิธีที่สอง JavaScript บน NodeJS
ผู้เขียนได้สร้าง Script เขียนโดยภาษา JavaScript บน NodeJS ซึ่งเป็นภาษาที่ทำงานได้อย่างรวดเร็ว มีความยืดหยุ่นและได้รับความนิยมมาก ถูกนำไปใช้งานหลากหลายโปรเจค หนึ่งในนั้นก็คือ Node-RED เครื่องมือสำหรับนักพัฒนายอดนิยมนั่นเอง ครั้งนี้จะจำลองให้มันบริการเป็น UDP server เปิดพอร์ต 42304 รอไว้ จากนั้นให้มันดักดู UDP แพ็คเกจที่ส่งมา แล้วสกัดเอา IP Address ของปลายทางของ end node ที่เป็น IP Address จริง มาแสดงบน console เขียน code ดังต่อไปนี้
# myudp.jsvar dgram = require('dgram');
var server = dgram.createSocket('udp4');server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});server.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);});server.bind(42304, '0.0.0.0');
ที่ฝั่ง UDP server ที่ได้รัน JavaScript บน NodeJS ในที่นี้ชื่อ “myudp.js” รอไว้ที่พอร์ต 42304 ทันทีที่มี UDP แพ็คเกจส่งเข้ามา JavaScript บน NodeJS จะสกัดเอา IP Address จริงมาแสดงบน Console พร้อมแสดงข้อความ Payload ที่รับมา จากตัวอย่างได้ IP Address จริงคือ “119.31.119.197” และข้อความคือ “RSU01,24,73,292,5”
root@UDPserver:~# node myudp.js
UDP Server listening on 0.0.0.0:42304
119.31.119.197:42304 - RSU01,24,73,292,5
วิธีที่สาม PHP Script
ผู้เขียนจะสร้าง PHP Script บน Apache web server สำหรับ PHP มันเป็นภาษาที่มีอายุมากแล้วแต่ก็ยังใช้มาจนถึงปัจจุบันนี้ นักพัฒนาเว็ปรุ่นใหญ่จะต้องรู้จักกันแน่ และต้องเคยผ่านหูผ่านตา หรือไม่ก็ลงมือทำกันมาแล้ว ถือว่าเป็นอีกหนึ่งทางเลือก ครั้งนี้จะให้มันเปิดบริการเป็น UDP server เปิดพอร์ต 42305 รอไว้ จากนั้นให้มันดักดู UDP แพ็คเกจที่ส่งมา แล้วสกัดเอา IP Address ของปลายทางของ end node ที่เป็น IP Address จริง มาแสดงบน console เขียน code ดังต่อไปนี้
<?php// myudp.php$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', 42305);while(1)
{
socket_recvfrom($socket, $buf, 1024, 0, $remote_ip, $remote_port);
echo "$remote_ip : $remote_port -- " . $buf . "\n";
}?>
ที่ฝั่ง UDP server ที่ได้รัน PHP Script ไว้ ในที่นี้ชื่อ “myudp.php” รอไว้ที่พอร์ต 42305 ทันทีที่มี UDP แพ็คเกจส่งเข้ามา PHP Script จะสกัดเอา IP Address จริงมาแสดงบน Console พร้อมแสดงข้อความ Payload ที่รับมา จากตัวอย่างได้ IP Address จริงคือ “119.31.119.197” และข้อความคือ “RSU01,24,73,292,5”
root@UDPserver:~# node myudp.js
UDP Server listening on 0.0.0.0:42304
119.31.119.197:42304 - RSU01,24,73,292,5
วิธีที่สี่ Node-RED
ผู้เขียนจะสร้าง Flow บน Node-RED ซึ่งตัวมันเองเป็นโปรแกรมการสร้าง Flow เพื่อพัฒนาโปรแกรมอีกที ทำงานแบบ GUI เป็นสุดยอดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ตัวหนึ่งที่ต้องมีติดตัวไว้ พกไว้แล้วอุ่นใจ มันทำให้การเชื่อมฐานข้อมูล การจัดการ service ต่างๆ เป็นเรื่องที่ง่ายดาย ครั้งนี้จะนำมันมาให้บริการเป็น UDP server เปิดพอร์ต 42305 รอไว้ จากนั้นให้มันดักดู UDP แพ็คเกจที่ส่งมา แล้วสกัดเอา IP Address ของปลายทางของ end node ที่เป็น IP Address จริง มาแสดงที่ Message debug ให้สร้าง Flow ดังต่อไปนี้
ให้ double click ที่ node ของ function
ให้ตั้งชื่อ node ว่า “FILLTER” แล้วเพิ่ม JavaScript ตามโค๊ดข้างล่าง
var str = msg.payload;
var data = str.slice(0).split(',');msg.payload = {
"name": data[0],
"sensor0": parseInt(data[1]),
"sensor1": parseInt(data[2]),
"sensor2": parseInt(data[3]),
"cnt": parseInt(data[4]),
"ip": msg.ip
}return msg;
หลังจากที่สร้าง Flow เสร็จเรียบร้อย ให้ดูที่หน้าต่าง Message debug จะพบว่าข้อความที่แสดงจะมีทั้งข้อมูลที่ได้มาจากเซ็นเซอร์และมี IP Address จริงของ end node ด้วย ในรูปแบบ JSON
ทำ Downlink ส่ง Payload ไป end node อย่างไร ?
ตอนนี้ท่านคงพอเห็นภาพและทราบแล้วว่า จะสามารถสกัดเอา IP Address จาก NBIoT Shield ด้วยวิธีไหนได้บ้าง ทั้งนี้ขึ้นอยู่กับการใช้งานของท่าน เลือกเอาที่ท่านสะดวกและสบายใจ ส่วนการส่ง downlink เพียงแค่ท่านทราบหมายเลข IP Address จริงของ NBIoT Shield ที่ได้รับและหมายเลข UDP พอร์ตที่เปิดรอไว้ ท่านก็สามารถส่ง Payload ไปตรงๆ ได้เลย
ยกตัวอย่างในที่นี้ IP Address ของ end node ที่จะส่ง Payload ไปคือ “119.31.119.232” และข้อความที่ต้องการส่งคือ “hello”
ขั้นตอนต่อไปจะเป็นการทดลองส่ง Payload ขา Downlink ไปยังอุปกรณ์ end node โดยวิธีต่างๆ ดังนี้
- ส่ง Payload ขา Downlink โดยใช้ Command Line บน Linux OS
root@UDPserver:~# echo -n "hello" >/dev/udp/119.31.119.152/42302
2. ส่ง Payload ขา Downlink โดยใช้ Python Script
# send_udp.pyimport socket
port = 42302
host = "119.31.119.152"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto("hello", (host, port))
ทดสอบส่ง payload โดยใช้คำสั่ง
root@UDPserver:~# python send_udp.py
3. ส่ง Payload ขา Downlink โดยใช้ JavaScript บน NodeJS
// send_udp.jsvar PORT = 42302;
var HOST = '119.31.119.152';var dgram = require('dgram');
var message = Buffer.from('hello');
var client = dgram.createSocket('udp4');
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
client.close();
});
ทดสอบส่ง payload โดยใช้คำสั่ง
root@UDPserver:~# node send_udp.js
4. ส่ง Payload ขา Downlink โดยใช้ PHP Script
<?php// send_udp.php$server_ip = '119.31.119.152';
$server_port = 42302;
$message = 'hello';$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_sendto($socket, $message, strlen($message), 0, $server_ip, $server_port);?>
ทดสอบส่ง payload โดยใช้คำสั่ง
root@UDPserver:~# php send_udp.php
5. ส่ง Payload ขา Downlink โดยใช้ Flow ของ Node-RED
ให้ double click ที่ node ของ function
ให้ตั้งชื่อ node ว่า “NBIoT” แล้วเพิ่ม JavaScript ตามโค๊ดข้างล่าง
var t = "hello";
var ip = "119.31.119.152";
msg.port = 42302;const buf = new Buffer(t);let message = {"ip": ip, "port": msg.port, "payload": buf}return message;
ทดสอบส่ง payload โดยคลิ๊กที่ node “Send” ที่หน้าต่าง Message debug จะแสดงข้อความ “hello” ที่แปลงเป็น buffer เลขฐาน 16 (HEX) เหตุผลที่ต้องแปลงข้อความก่อนก็เพราะว่า node ของ UDP server จะรับข้อมูลที่เป็นแบบ buffer ไม่สามารถส่งข้อความธรรมดาไปได้นะครับ
อธิบายเพิ่มเติม ข้อความจะถูกแปลงเป็น HEX คือ 0x68 0x65 0x6c 0x6c 0x6f ลองมาที่ดูตาราง ASCII TABLE ที่ตัวหนังสือสีแดงจะเป็นเลขฐาน 16 (HEX) ส่วนตัวสีเขียวจะเป็นตัวอักษร (Char)
0x68 = h
0x65 = e
0x6c = l
0x6c = l
0x6f = o
ใน End node รับ Payload แล้วแสดงผลอย่างไร ?
การส่ง payload ขา Downlink ไปยัง end node ทั้ง 5 วิธีที่กล่าวมา จะให้ผลลัพธ์ที่เหมือนกัน ใน Serial Monitor ของ Arduino IDE จะแสดงข้อความ “hello” และระบุ IP Address ที่ส่งมาในที่นี้คือ 155.5.5.5 ความยาวของข้อความคือ 5 ส่วนหมายเลขของพอร์ตจะสุ่มหมายเลข การส่งแต่ละครั้งพอร์ตจะไม่ซ้ำกัน
ท่านสามารถนำ payload ที่ได้จากการส่ง downlink มาสร้างเงื่อนไขควบคุมอุปกรณ์ทางไกลได้ เช่น สั่ง ปิด เปิดไฟ เป็นต้น ขึ้นอยู่กับการประยุกต์ใช้ของแต่ละคน
################################################################
# Incoming Data
# IP--> 155.5.5.5
# Port--> 46658
# Length--> 5
# Data--> hello
# Remaining length--> 0
################################################################
บทสรุป
มาถึงนี้ตอนนี้ท่านคงได้แนวทางเบื้องต้นสำหรับการทดลองการสร้าง UDP server ไว้ใช้งานร่วมกับอุปกรณ์ NBIoT เอง ดังที่แสดงไว้ข้างต้น ทั้งการหา IP Address จริง การส่ง Payload ขา Downlink มีหลากหลายวิธี ทั้งนี้ขึ้นอยู่กับการประยุกต์ใช้ให้ตรงกับงานที่ทำ ผู้เขียนหวังว่าบทความนี้จะเป็นประโยชน์ต่อนักพัฒนา NBIoT ไม่มากก็น้อยครับ
แนวทางการพัฒนาต่อยอด
ผู้เขียนก็ใช้ Node-RED สร้าง UDP server สำหรับการเก็บข้อมูลจาก end node และ IP Address ไว้ในฐานข้อมูล InfluxDB รวมถึงสร้างโพล์การส่ง downlink ไป NBIoT end node ด้วย และยังได้สร้าง HTTP RESTful แบบ GET เพื่อรอรับการทำ Downlink ผ่าน Web Browser ผู้เขียนยังสามารถใช้ LineBot , Blynk และ Mobile Application ส่งข้อความไปยัง NBIoT end node ได้อีกด้วยนะครับ
ยกตัวอย่างการส่ง Payload มี message คือ “hello” ไปยัง end node ชื่อ “RSU01”
http://155.5.5.5:1880/rsu-nbiot?name=RSU01&payload=hello
หลังจากที่ Node-RED ได้รับ Payload ผ่าน HTTP RESTful จะตอบกลับข้อความในรูป JSON ตามข้างล่าง
{"name":"RSU01","payload":"hello"}
จากนั้น Node-RED จะทำการ query ดึงข้อมูลจาก InfluxDB เพื่อหา IP Address ล่าสุดที่ได้รับจาก node ชื่อ “RSU01” หลังจากทราบ IP Address แล้ว จะทำการแปลงข้อความ “hello” เป็น buffer เลขฐาน 16 (HEX) แล้วส่งไปยัง end node ด้วยโปรโตรคอล UDP
วิธีการแบบนี้ หลายท่านคงคุ้นๆ กัน มันก็เหมือนการใช้บริการ DynDNS , NoIP เพื่ออัพเดท IP Address ของ ADSL router ในช่วงเริ่มต้นของอินเตอร์เนตยุคแรกๆ ที่ Could ยังไม่แพร่หลาย ผมได้นำไอเดียนี้มาประยุกต์กับการจัดการ DHCP IP ของ NBIoT นั่นเองครับ
พบกันใหม่บทความหน้า การสร้าง UDP server รับและส่งข้อมูล NBIoT ไปยัง LineNotify และ Blynk ด้วย Node-RED ตอนที่ 2
ผู้เขียนมีความตั้งใจที่จะนำเสนอการใช้ IoT-LoRaWAN-NBIOT สำหรับพัฒนา SMART CITY เพื่อให้ผู้ที่สนใจนำไปพัฒนาต่อยอดสร้างนวกรรมใหม่ๆ ขอเป็นส่วนหนึ่งเล็กๆ น้อยๆ ช่วยผลักดันประเทศของเราให้เข้าสู่ยุคดิจิตอล Thailand 4.0 อย่างแท้จริง
ติดตามข่าวสารทาง facebook ได้ที่ลิงค์นี้