2021/10/31

#6 監測資料寫入InfluxDB資料庫, 長期保存並在NodeRED資訊看板裡顯示

大家好, 今天來和大家分享 “一起來學樹莓派, 寫入InfluxDB 資料庫”. 上集分享的是資料送到 MQTT 顯示到資訊看板後, 時間後後資料就消失了. 本集是把所有的資料收集起來之後, 可以用來以後做為資料分析的依據. 以前你可能要把資料寫到 Thinkspeak server上, 現在自己家裡的樹莓派上就可以做到了! 一起來學樹莓派吧!


這影片內容有:
  • 安裝 InfluxDB 資料庫
  • 比較 InfluxDB 與關聯式資庫的不同
  • 如何把ESP32送到 MQTT 資料寫入InfluxDB 資料庫
  • 讀取InfluxDB 資料庫, 再把這些資料在資訊看板上顯示出來




Format code for writing InfluxDB

  1. // Create the object key to match DB filed name from topic name(studio/temp1)
  2. msg.payload["temp"] = msg.payload["studio/temp1"];
  3. // Delete the unwanted studio/temp1
  4. delete msg.payload["studio/temp1"];
  5. // Update temp from string to float
  6. msg.payload["temp"] = parseFloat(msg.payload["temp"]);
  7.  
  8. msg.payload["humd"] = msg.payload["studio/humd1"];
  9. delete msg.payload["studio/humd1"];
  10. msg.payload["humd"] = parseFloat(msg.payload["humd"]);
  11.  
  12. //remove unused topic
  13. delete msg.topic;
  14.  
  15. //Create a temporary array
  16. var data = [];
  17. data.push(msg.payload);
  18.  
  19.  
  20. //Add object to DB Tag(index field)
  21. data.push({"location":"studio"});
  22. //msg.payload.push({"location":"studio"});
  23.  
  24. //Copy temporary array to msg.payload
  25. msg.payload = data;
  26. return msg;

Format code for reading historical InfluxDB data

  1.  
  2.  
  3. //Source from: https://discourse.nodered.org/t/display-2-extracts-from-influxdb-in-an-ui-chart/29665
  4. var series = ["Temperature °C", "Humdity %"];
  5. var labels = ["temp", "Humdity"];
  6.  
  7. var data0 = "[";
  8. var thetime0;
  9.  
  10. for (var i=0; i < msg.payload.results[0].series[0].values.length; i++) {
  11. thetime0 = (msg.payload.results[0].series[0].values[i][0]); // Some manipulation of the time may be required
  12. thetime0 = Date.parse(thetime0);
  13. data0 += '{ "x":' + thetime0 + ', "y":' + (msg.payload.results[0].series[0].values[i][1]) + '}';
  14. if (i < (msg.payload.results[0].series[0].values.length - 1)) {
  15. data0 += ","
  16. } else {
  17. data0 += "]"
  18. }
  19. }
  20.  
  21.  
  22.  
  23. var data1 = "[";
  24. var thetime1;
  25.  
  26. for (var j=0; j < msg.payload.results[0].series[0].values.length; j++) {
  27. thetime1 = (msg.payload.results[0].series[0].values[j][0]); // Some manipulation of the time may be required
  28. thetime1 = Date.parse(thetime1);
  29. data1 += '{ "x":' + thetime1 + ', "y":' + (msg.payload.results[0].series[0].values[j][2]) + '}';
  30. if (j < (msg.payload.results[0].series[0].values.length - 1)) {
  31. data1 += ","
  32. } else {
  33. data1 += "]"
  34. }
  35. }
  36. var data = [data0, data1];
  37. var jsondata = [JSON.parse(data0), JSON.parse(data1)];
  38. msg.payload = [{"series": series, "data": jsondata, "labels": labels}];
  39. msg.dataPoints = data;
  40.  
  41.  
  42. return msg;
  43.  

請在此下載本篇教學的 NodeRead 程式: #6 監測資料寫入InfluxDB資料庫, 長期保存並在NodeRED資訊看板裡顯示

更新:
影片內容不小心略過這個 InfluxDB Out Node (Write to studioTempDB)的內容:

InfluxDB out node 內容有兩項資料要輸入:
(1) 定義 InfluxDB Server, 按下鉛筆符號(見下圖)
(2) 寫入的 Measurement 資料表名稱,我們的範例裡,Measurement = studioTemp

定義 InfluxDB Server:
(1) InfluxDB - 在 Flow 裡看到的名稱
(2) InfluxDB 版本 - 教學裡案裝的是 v1.64
(3) Host: InfluxDB 的主機: 由於我們裝在本機,所以用 : raspberrypi.local, Port: 8086
(4) 資料庫名稱: 範例裡使用 studioTemp
(5) 資料庫帳號及密碼: 如果未設定可略過


Stonez56 一起來學樹莓派系列影片: 


2 comments:

  1. 網友 Gavin Ting 詢問:

    想再請教您一個資料庫的問題,如果我的資料記錄是累進的,如電表上的度數,我要show出每小時的用電量圖,這樣的sql指令要怎麼寫??

    ANS:
    嗯, 假設你有 temp(溫度), humd(溼度),
    1. 用 SELECT 在 SQL 求平均值mean(temp), mean(humd)
    2. 再把每一小時得平均值找出來 GROUP BY TIME(60m)
    3. time - > now() - 5h 是找出最後的 5 小時的資料

    SQL:
    Select mean("temp") as temp, mean("humd") as humd from MEASUREMENT_NAME where time > now() - 5h GROUP by time(60m) FILL(0) FILL(0)

    ReplyDelete
  2. 網友 Gavin Ting 詢問:

    想再請教您一個資料庫的問題,如果我的資料記錄是累進的,如電表上的度數,我要show出每小時的用電量圖,這樣的sql指令要怎麼寫?

    電表計錄就像是台電的電表一樣,是累計的,例如記錄為100,110,130,160…,就是要把每個小時內的最高值-最低值才會是這個小時的用電量.

    ANS:
    早上試作一下, 這樣應該可以計算出用電量:

    1) 取得前12小時, 最大/最小溫度:
    Select max(power), min(power) from yourDB where time > now() - 12h group by time(60m)

    2) 取得前12小時, 每小時用電量
    select max(power) - min(power) as power_usage from yourDB where time > now() - 12h group by time(60m)




    ReplyDelete