請問在IoT收集到的資料要如何讓它自動存入本地postgreSQL資料庫中呢?
是要在python寫程式和定義資料欄位嗎?
還是說要先在資料庫把欄位定義好?
還有如果收到的一段16進制的資料,
該怎麼切割欄位再存入資料庫?
(例如:16byte的字串,每兩個byte分別代表不同資料意義)
謝謝~
------補充------
上拋檔案為json格式
{"裝置ID","時間","經緯度","03 4C DF 48 ....17"}
字串部分分別代表各自意義,約十幾組。
例如:站號 電流 溫度 ...等等(1Byte 2 Byte ...)
我同事負責拋資料的部分,我要負責接到資料庫,
資料再拿來作dashboard的運用。
因為沒這方面的經驗,預想的多種解決方案是google來的。
其實不一定要用python來串接,只要可行的語言都能try看看。
以個人經驗.. iOT 用在地震服務以 A20-OLinuXino-LIME2 收集相關資料,當然用 Arduino 傳相關資料丟 WebAPI 當然也可以..
Arduino 的部份就在裡面用 URL 只要傳的出去應該都可以。
如果你是用 SQL Server 2016 版以上,WebAPI 接到資料後將 JSON 直接丟給 SQL SERVER 後用 SQL JSON QUERY 來拆解再存起來,非常簡單..
針對「如果收到的一段16進制的資料,該怎麼切割欄位」,
提供 Python 可能做法以供參考。
(主要是自己太閒又有興趣練習~)
(## ■ 基本範例
前的不用認真~ 只是無聊的初始化~)
## Python==3.8.16;
##
import random
## get random bytes; (@ cpython/Lib/random.py)
def randbytes(n): return random.getrandbits(n * 8).to_bytes(n, 'little')
##
## (myHL01b, myHL01b, myHL01b): highlight for print();
myHL01b = '\033[36m'; myHL01e = '\033[0m'
myHL02b = '\033[33m';
## myMsg for print();
myMsg01 = lambda na, obj : '' \
+ str(na) \
+ ': type:[' + myHL01b \
+ str(type(obj)) \
+ myHL01e + '], Value:[' + myHL01b \
+ str(obj) \
+ myHL01e + '];'
myMsg02 = lambda na, bs : myMsg01(na, bs.hex('-').upper())
##
## ■ 基本範例
print(myHL02b + ' ■ Basic Show:' + myHL01e)
myBytesRa = randbytes(20)
myTN='myBytesRa'; print(myMsg02(myTN, locals()[myTN]))
## 從字串轉取 Bytes 物件。
## https://docs.python.org/3/library/stdtypes.html#bytes.fromhex
myBytes01str = '03 4C DF 48 4C 48 03 DF 03 4C DF 48'
myBytes01 = bytes.fromhex(myBytes01str)
myTN='myBytes01'; print(myMsg02(myTN, locals()[myTN]))
print(myMsg02('myBytes01 slicing', myBytes01[2:4]))
## Bytes 轉取 int
## https://docs.python.org/3/library/stdtypes.html#int.from_bytes
myInt01 = int.from_bytes(myBytes01[2:4], byteorder='big', signed=True)
myTN='myInt01'; print(myMsg01(myTN, locals()[myTN]))
##
## □ struct 範例
## https://docs.python.org/3/library/struct.html
print(myHL02b + ' □ "struct" Show:' + myHL01e)
import struct
## read: big-endian ( short integer (size:2),)
print(myMsg02('myBytes01 slicing', myBytes01[2:4]))
myInt02 = struct.unpack('>h',myBytes01[2:4])
myTN='myInt02'; print(myMsg01(myTN, locals()[myTN]))
## read: big-endian (short integer (size:2), float (size:4))
print(myMsg02('myBytes01 slicing', myBytes01[2:8]))
myInt03 = struct.unpack('>hf',myBytes01[2:8])
myTN='myInt03'; print(myMsg01(myTN, locals()[myTN]))
print(myMsg01('myInt03[0]', myInt03[0]))
print(myMsg01('myInt03[1]', myInt03[1]))
##
print('')
##
## ■ numpy 範例
print(myHL02b + ' ■ "numpy" Show:' + myHL01e)
import numpy as np
## Usage: myMsg03 for print();
myMsg03 = lambda st, dt : 'dtype(' + st + '):[' + myHL01b + str(dt) + myHL01e + '];'
## dtype: https://numpy.org/doc/stable/reference/arrays.dtypes.html
## frombuffer: https://numpy.org/doc/stable/reference/generated/numpy.frombuffer.html
print(myMsg03(
"np.dtype(np.int16).newbyteorder('>')",
np.dtype(np.int16).newbyteorder('>')
))
myDT01 = np.dtype('>i2')
print(myMsg02('myBytes01 slicing', myBytes01[2:6]))
myNPAry01 = np.frombuffer(myBytes01[2:6], dtype=myDT01)
myTN='myNPAry01'; print(myMsg01(myTN, locals()[myTN]))
print('')
## Structured-dtype(?):
## Show for dtype-WebDoc: [(field_name, field_dtype, field_shape), ...]
print(myMsg03(
"np.dtype(np.float32).newbyteorder('>')",
np.dtype(np.float32).newbyteorder('>')
))
print(myMsg02('myBytes01 slicing', myBytes01[:8]))
myNPAry02 = np.frombuffer(myBytes01[:8], dtype=[
('f1', '>i2'), ('f2', '>i2'), ('f3', '>f4')
])
myTN='myNPAry02'; print(myMsg01(myTN, locals()[myTN]))
print('')
##
## Show for dtype-WebDoc: {'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., 'itemsize': ...}
## Sliced myBytesRa[:16] for [ValueError: buffer size must be a multiple of element size]
print(myMsg02('myBytesRa slicing', myBytes01[:16]))
myNPAry03 = np.frombuffer(myBytesRa[:16], dtype={
'names' : ['f1','f2','f3'],
'formats' : ['>i2', '>i2', '>f4']
})
myTN='myNPAry03'; print(myMsg01(myTN, locals()[myTN]))
print(myMsg01('myNPAry03[1]', myNPAry03[1]))
print(myMsg01('myNPAry03[1][0]', myNPAry03[1][0]))
##
至於存資料庫,找 drivers 連線、寫入,我覺得應該有一堆範例了:
這裡 還有人討論最佳方法呢!(不過是針對 numpy 就是了~)