บทความนี้จะแนะนำเกี่ยวกับการส่งข้อมูลจาก LoRaWAN Device วัดอุณหภูมิและความชื้นยี่ห้อ Rejeee โดยมีรูปแบบการ Flow ของข้อมูลดังนี้

Rejeee Temp & Hum Sensor SL101AS-TH → Helium Hotspot →Helium Console →Mqtt Server →Telegraf — ->Influxdb

  1. Specification เบื้องต้น

Rejeee LoRaWAN SL101AS-TH เป็นเซ็นเซอร์อุณหภูมิและความชื้น มากับจอ E-paper 2.9 นิ้ว เป็นอุปกรณ์ที่ผ่าน กสทช. แล้ว กำลังส่งต่ำกว่า 500mW ผู้ใช้สามารถซื้อไปใช้งานได้ ไม่ต้องมีใบอนุญาติใช้/ตั้งสถานี จาก กสทช. อุปกรณ์นี้สามารถใช้ได้กับ The Things Network, Chirpstack หรือ Helium

คุณสมบัติทางเทคนิค
- LoRaWAN 1.0.3 Class A/C
- ใช้ลิเธียมแบต 5400mAh ใช้ได้นานถึง 5 ปี (ส่งข้อมูลทุก 30 นาที) ผู้ผลิตบอกว่าใช้ได้ถึง 10 ปีหากตั้งส่งเว้นช่วงห่างมากขึ้นอีก แบตเป็นแบบไม่สามารถ Charge ได้ ไฟหมดแล้วต้องหาก้อนใหม่ใช้แทน
- มี Port USB Type C สำหรับปรับตั้งค่าหรือใช้ป้อนไฟเลี้ยงจากภายนอก
- สามารถเปลี่ยน Logo และ Weblink
- ใช้ Chip Semtech SX1262 และ Sensirion STH 30
- ช่วงวัดอุณหภูมิ -45℃~+ 85℃ (±0.3℃)
- ช่วงวัดความชื้น 0–100%RH (±3%RH)
- ความถี่ 923–925Mhz
- TX Power 25dBm (316mW)
- ขนาด 102mm*60mm*25mm

2.การดูค่า Config ที่ตั้งไว้ในตัวอุปกรณ์ Sensor

อาจจะต้องติดตั้ง Serial Driver หากเสียบแล้วเครื่อง PC ไม่รู้จัก Download software ต่างๆ ได้จากเวป http://www.rejeee.com/#/download

ค่าความถี่ในการส่งข้อมูล ค่า Key ต่างๆ คือ DevEUI, AppEUI, Appkey จะเก็บไว้ในอุปกรณ์ให้ใช้สาย USB Type C เสียบเข้ากับ Sensor และให้ Download Sensor tools ได้จากเวป http://www.rejeee.com/#/download

เรียกใช้โปรแกรม Sensortool1.3

คลิกหลัง Uart Select: เลือก COM ที่ต่อกับ Sensor Rejeee เช่น COM3 USB-SERIAL CH340 เป็นต้น คลิก Open UART แล้วคลิก Read Config

จดค่า DevEUI, AppEUI, Appkey นำไปป้อนในหน้า Console Helium

หาต้องการแก้ไขความถี่ในการส่ง เช่น ของผู้เขียนค่า Uplink Period ตั้งมา 600 วินาที หรือ คือ 10 นาที ซึ่ง Sensor นี้จะส่งข้อมูลทุก 10 นาที สามารถแก้เป็นช่วงระยะห่างของการส่งข้อมูลแต่ละครั้งตามที่เราต้องการแล้วกด UpdateConfig

3. เพิ่ม Device Rejeee ใน Console

เปิด console.helium.com

อาจจะ Login ด้วย Google Account ที่มี

คลิก Devices ด้านซ้ายมือ

คลิกบวกมุมขวาล่าง เลือก Add Device

ใส่ Name, DevEui, AppEUI, App Key ที่จดจากโปรแกรม Sensortools

เช่น DevEui CACBB8010000322F
APPEUI CACBB80000000001
APPKEY 11223344556677889900AABBCCDDEEFF เป็นต้น

เนื่องจาก Device จะถูกเพิ่มเข้าไปในระบบ Blockchain ของ Helium จึงจะใช้เวลาระยะหนึ่ง ให้รอจนข้อความ Pending หายไปจึงจะเริ่มใช้งานได้

คลิกเมนูด้านซ้าย Data Credit

Node เราจะส่งข้อมูลเข้า Helium Network ได้ หากมี Data Credit เหลือพอต่อการใช่้งาน

4.การจัดการข้อมูลรับผ่าน Hotspot Helium

บทความนี้ไม่ได้กล่าวถึงการติดตั้ง Software influxdb บน Docker ตามรูปภาพ

สร้าง Integration mqtt

เปิด console.helium.com และสร้าง integration ใหม่ อาจใช้ชื่อ helium

ช่อง Endpoint ใส่ mqtt://broker.hivemq.com:1883 เป็น mqtt server ฟรี หรืออาจจะเลือก Mqtt Server ตัวอื่นก็ได้ ช่อง uplink/downlink เว้นว่างใช้ default

สร้าง Function Decode
สร้าง function ใช้ชื่อ เช่น rejeeetemphumid ป้อน Java script ดังต่อไปนี้ในช่อง decode

function Decoder(bytes, port) {
var input = {bytes: bytes, port:port};
var obj = {};
var warnings = [];
var len = input.bytes ? input.bytes.length : 0;
var offset = 0;
var dtype = 0, dlen = 0;
/* first is device information(0x00) */
offset++;
obj.battery = (input.bytes[offset++] & 0x1F);
obj.res = (input.bytes[offset++]);
do {
dtype = input.bytes[offset++];
if (0x01 == dtype) {
/* 3D sensor */
obj.evt = input.bytes[offset++];
obj.acceX = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1])
offset += 2;
obj.acceY = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1])
offset += 2;
obj.acceZ = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1])
offset += 2;
obj.angle = input.bytes[offset++];
} else if (0x04 == dtype) {
/* temperature sensor, value unit is 0.1 ℃ */
obj.temperature = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1]) / 10;
offset += 2;
} else if (0x05 == dtype) {
/* humidity sensor, value unit is 1 %RH */
obj.humidity = input.bytes[offset++];
} else if (0x06 == dtype) {
/* oxygen sensor, value unit is 0.1 %VOL */
obj.oxygen = (input.bytes[offset++]) / 10;
} else if (0x07 == dtype) {
/* pressure sensor, value unit is 1 Pa */
obj.pressure = ((input.bytes[offset] << 24) + (input.bytes[offset + 1] << 16) + (input.bytes[offset + 2] << 8) + input.bytes[offset + 3]);
offset += 4;
} else if (0x09 == dtype) {
/* switch sensor or status, value is ON(1) or OFF(0) */
obj.switch = input.bytes[offset++];
} else if (0x11 == dtype) {
/* Incline sensor, value unit is 0.001° */
dlen = input.bytes[offset++];
if (dlen >= 4) {
obj.degreeX = ((input.bytes[offset] << 24) + (input.bytes[offset + 1] << 16) + (input.bytes[offset + 2] << 8) + input.bytes[offset + 3]) / 1000;
offset += 4;
dlen -= 4;
}
if (dlen >= 4) {
obj.degreeY = ((input.bytes[offset] << 24) + (input.bytes[offset + 1] << 16) + (input.bytes[offset + 2] << 8) + input.bytes[offset + 3]) / 1000;
offset += 4;
dlen -= 4;
}
if (dlen >= 4) {
obj.degreeZ = ((input.bytes[offset] << 24) + (input.bytes[offset + 1] << 16) + (input.bytes[offset + 2] << 8) + input.bytes[offset + 3]) / 1000;
offset += 4;
dlen -= 4;
}
if (dlen > 0) {
offset += dlen;
}
} else if (0x14 == dtype) {
/* Mutil-temperature sensor, value unit 0.1 ℃ */
dlen = input.bytes[offset++];
if (dlen >= 2) {
obj.temperature1 = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1]) / 10;
offset += 2;
dlen -= 2;
}
if (dlen >= 2) {
obj.temperature2 = (((input.bytes[offset] & 0x80 ? input.bytes[offset] — 0x100 : input.bytes[offset]) << 8) + input.bytes[offset + 1]) / 10;
offset += 2;
dlen -= 2;
}
if (dlen > 0) {
offset += dlen;
}
} else if (0x15 == dtype) {
/* Mutil-humidity sensor, value unit 1 %RH */
dlen = input.bytes[offset++];
if (dlen >= 1) {
obj.humidity1 = input.bytes[offset++];
dlen -= 1;
}
if (dlen >= 1) {
obj.humidity2 = input.bytes[offset++];
dlen -= 1;
}
if (dlen > 0) {
offset += dlen;
}
} else if (0x1A == dtype) {
/* Current and voltage */
dlen = input.bytes[offset++];
if (dlen >= 2) {
/* Current value unit is 1 mA */
obj.current = ((bytes[offset] << 8) + bytes[offset + 1]);
offset += 2;
dlen -= 2;
}
if (dlen >= 2) {
/* voltage value unit is 0.1 V */
obj.voltage = ((bytes[offset] << 8) + bytes[offset + 1]) / 10;
offset += 2;
dlen -= 2;
}
if (dlen > 0) {
offset += dlen;
}
} else if (0x1B == dtype) {
/* Watt and value unit is 1 Watt */
dlen = input.bytes[offset++];
if (dlen >= 4) {
obj.watt = ((bytes[offset] << 24) + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3]);
offset += 4;
dlen -= 4;
}
if (dlen > 0) {
offset += dlen;
}
} else if (0x30 == dtype) {
/* Hybrid gas sensor: Length + Gas Type + Value */
dlen = input.bytes[offset++];
/* follow data length, normal is 5 */
if (dlen >= 5) {
/**
* Gas Type
* 0x01 CH4
* 0x02 CO
* 0x03 H2S
* 0x04 CO2
* 0x05 NH3
*/
var gastype = input.bytes[offset++];
/* Value unit is 0.01 */
obj.volume = ((input.bytes[offset] << 24) + (input.bytes[offset + 1] << 16) + (input.bytes[offset + 2] << 8) + input.bytes[offset + 3]) / 100;
offset += 4;
dlen -= 5;
if (obj.volume < 0) {
warnings.push(“it’s invalid”);
}
}
if (dlen > 0) {
offset += dlen;
}
}
len = len — offset;
} while (len > 0);
return obj;
}

เสร็จแล้วสร้าง Flow ตามรูปดังนี้ เชื่อมเส้นจาก device Sensor Rejeee ผ่าน function ไปยัง Integration helium ตามรูป

เปิด Sensor ถ้า Sensor Join สำเร็จและเริ่มส่งข้อมูลและการทำงาน Integration ไม่ผิดพลาดจะเห็น live data ของ device เช่น

Monitor mqtt server

ทำได้โดยเรียกคำสั่ง

mosquitto_sub -h broker.hivemq.com -t “helium/#”

จะเห็นข้อมูลแสดงบน mqtt server เช่น ตามตัวอย่างดังนี้

pi@raspberrypi:~ $ mosquitto_sub -h broker.hivemq.com -t “helium/#”
{“app_eui”:”CACBB80000000001",”dc”:{“balance”:5778,”nonce”:1},”decoded”:{“payload”:{“battery”:31,”humidity”:43,”res”:36,”temperature”:27.5},”status”:”success”},”dev_eui”:”CACBB8010000322F”,”devaddr”:”39000048",”fcnt”:10,”hotspots”:[{“channel”:1,”frequency”:923.4000244140625,”hold_time”:493,”id”:”14ZJJsZGg4v7KCXmUraTsRe3oUwLa3rqikbRF49CLJnK3U34V”,”lat”:13.99421768912186,”long”:100.847604336026,”name”:”carp-bubblegum-mustang”,”reported_at”:1658236622097,”rssi”:-42.0,”snr”:7.5,”spreading”:”SF10BW125",”status”:”success”}],”id”:”63fea6b-8a1d-4da2-ab1a-e1c538d59b01",”metadata”:{“adr_allowed”:false,”cf_list_enabled”:false,”multi_buy”:1,”organization_id”:”5a7d8498-f75a-4d10-b929–1c8cfb536eb8",”preferred_hotspots”:[],”rx_delay”:1,”rx_delay_actual”:1,”rx_delay_state”:”rx_delay_established”},”name”:”rejeee_temphumid”,”payload”:”AD8kBAETBSs=”,”payload_size”:8,”port”:1,”raw_packet”:”QDkAAEiACgAB+LukRuKRgdeirMOF”,”replay”:false,”reported_at”:1658236622097,”type”:”uplink”,”uuid”:”b9fb7ee6–0353–4997-a277–7d943430b5ac”}

ตั้งค่า telelgraf สำหรับการทำงาน บน Docker

อาจจะสร้าง dir ชื่อ telegraf-data แล้วสร้างไฟล์ชื่อ telegraf.conf ใน Dir ดังกล่าวโดยให้มีข้อมูลดังต่อไปนี้

[global_tags]
[agent]
interval = "5s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "5s"
flush_interval = "10s"
flush_jitter = "5s"
precision = ""
hostname = ""
omit_hostname = false
debug = true
quiet = false
[[outputs.influxdb_v2]]
urls = ["http://192.168.1.100:8086"]
token = GVyjoMQJdjP3C6MO8Q7QxcJApXjWn4HksmRaP841qSFDdLv1YID3HPg=="
organization = "influxdata"
bucket = "tablerejeee"

[[inputs.mqtt_consumer]]
name_override = "Helium"
servers = ["tcp://broker.hivemq.com:1883"]
qos = 0
connection_timeout = "30s"
topics = [ "helium/ID/#" ]
client_id = "helium"
username = "telegraf"
password = "telegraf123"
data_format = "json"

ให้ดู ID ของ Device แล้วแก้หัวข้อ Topic= แทรกแทน ID ใน telegraf.conf ด้วย

ตามคู่มือดังนี้

Run Container Telegraf บน Docker

run ด้วยคำสั่งดังนี้

docker run -d \
— name=telegraf \
— hostname=telegraf \
— user telegraf:$(stat -c ‘%g’ /var/run/docker.sock) \
-p 8125:8125/udp \
-p 8092:8092/udp \
-p 8094:8094 \
-v $PWD/telegraf.conf:/etc/telegraf/telegraf.conf:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e TZ=Etc/GMT+7 \
— restart unless-stopped \
telegraf

ใช้คำสั่ง docker logs telegraf เพื่อดู log ของ telegraf หาก run ปรกติ จะเห็นตามภาพตัวอย่าง

จะมีบรรทัด Wrote Batch หาก telegraf ดึงข้อมูลและเขียนลงใน Influxdb ได้สำเร็จ

เมื่อเปิด Influxdb ด้วย Web Brwoser ที่ http://ip:8086 สามารถสร้าง Dashboard ได้ตามต้องการจากข้อมูลที่ telegraf เขียนลง influxdb ใต้ _measurement ชื่อ Helium หรือตามชื่อที่เรากำหนดไว้ใน telegraf.conf

ref.https://chowdera.com/2021/09/20210920014603857S.html

หมายเหตุ หากลบ Bucket จะต้อง Gen Token ของ Bucket ใหม่มาใส่ใน telegraf.conf ใหม่

กรณี Downlink ทำโดย

คลิกที่รูปก้อนเมฆ มีลูกศรชี้ลง

ป้อนข้อมูลเสร็จให้คลิกรูปเมฆอีกครั้ง

ร่าง (รอทดสอบและเขียนเพิ่ม )หรือใช้คำสั่ง (error)

mosquitto_sub -h broker.hivemq.com -t “helium/bdcc7686-a9b1–45b6-a405–61862d7c4ba3/rx/#”

mosquitto_pub -V mqttv31 -h broker.hivemq.com -t “helium/bdcc7686-a9b1–45b6-a405–61862d7c4ba3/tx” -m “{\”payload_raw\”:\”encoded_string\”}”

--

--

Somsak Lima
Somsak Lima

Written by Somsak Lima

สนับสนุนและส่งเสริมให้ผู้สนใจสามารถใช้งานเทคโนโลยี LoRa และ LoRaWAN ได้ โดยนำความรู้ที่ได้ไปต่อยอดเพื่อใช้งาน

No responses yet