Rejeee Temp & Humid Sensor ใช้กับ Helium และ Private Influxdb
บทความนี้จะแนะนำเกี่ยวกับการส่งข้อมูลจาก LoRaWAN Device วัดอุณหภูมิและความชื้นยี่ห้อ Rejeee โดยมีรูปแบบการ Flow ของข้อมูลดังนี้
Rejeee Temp & Hum Sensor SL101AS-TH → Helium Hotspot →Helium Console →Mqtt Server →Telegraf — ->Influxdb
- 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\”}”