はじめに
やりたいことはタイトルの通り。
5年ほどBME280で室内温湿度を監視してきた。Raspberry Pi(3B+; 4B)をサーバー兼ロガーで使ってきたが、停電その他の理由(おおかた主のミス)でSDカードのOSが死ぬこと数回。SDカード寿命を考えてHDDにデータを書いたりオーバーレイ設定にしてみたり工夫はしたけれど、手軽さが失われた時点でRaspberry Piにこだわらなくても良いのでは?という気がしてきた。
ESP8266/ESP32やRaspberryPiPicoWのようにWiFi接続が可能なマイクロコントローラであれば、電源断に対する耐性も高く手放し運用が可能。
データ蓄積用のサーバーは普段使っているSynologyを使うことで安定稼働を目指す。これまで自作スクリプトで描いていたグラフは、同じSynologyにGrafanaを立ち上げて可視化してみることとした。
構成
- Raspberry Pi Pico W
- BME280ブレイクアウトボード(Switch Science)
- Synology DS220+
 
(初稿ではSynologyでのDockerの使い方、influxDBの立て方は別記事に譲る)
コード
約1分ごとにデータを取得してサーバに送る。データは1度に15個取得して最大値と最小値を除外、平均値を算出する。
from machine import I2C, Pin
import bme280
import utime
import network
import urequests
import ubinascii
i2c=I2C(0, sda=Pin(16), scl=Pin(17), freq=400000)
bme=bme280.BME280(i2c=i2c)
bsize=15
ssid = 'your ssid'
password = 'your password'
def connect():
    #Connect to WLAN
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Waiting for connection')
        utime.sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip
def ledblink():
    machine.Pin('LED', machine.Pin.OUT).toggle()
    utime.sleep(0.1)
    machine.Pin('LED', machine.Pin.OUT).toggle()
    
def readval():
    t=[]
    p=[]
    h=[]
    for i in range(bsize):
        raw = bme.read_compensated_data()
        t.append(raw[0]/100)
        p.append(raw[1]/25600)
        h.append(raw[2]/1024)
        
        d = ledblink()
        utime.sleep(0.9)
    del t[t.index(max(t))]
    del t[t.index(min(t))]
    del p[p.index(max(p))]
    del p[p.index(min(p))]
    del h[h.index(max(h))]
    del h[h.index(min(h))]
    tav=sum(t)/len(t)
    pav=sum(p)/len(p)
    hav=sum(h)/len(h)
        
    return tav,pav,hav    
def postadata(temperature, humidity, pressure):
    mac = ubinascii.hexlify(network.WLAN().config('mac')).decode()
    headers = {'Accept': 'text/plain',
           'Connection': 'close',
           'Content-type': 'application/octet-stream'}
    location="south"
    unitid=mac
    influx_endpoint = 'http://xxx.xxx.x.xx:yyyy/write?db=sensor'
    fields = (u'sensor,'
              u'location={location}'.format(location=location),
              u',unitid={unitid}'.format(unitid=unitid),
              u' ',
              u'temperature={temp}'.format(temp=temperature),
              u',humidity={humidity}'.format(humidity=humidity),
              u',pressure={pressure}'.format(pressure=pressure))
        # building influxdb point protocol measurement.
        # See https://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/
    point = ''.join(fields)
    response = urequests.post(influx_endpoint,
                                  data=point,
                                  headers=headers)
    response.close()
    print('Submitted :{}'.format(point))
    print(response)
#MAIN
def main():
    ip = connect()
    while True:
        t,p,h = readval()
        postadata(t,h,p)
        print(t,p,h)
    
        utime.sleep(45)
if __name__ == '__main__':
    main()
結果
現在は同じ動作をするESP-WROOM-02の装置と2台で2週間ほど稼働しており、順調にデータが蓄積されている。

