h_nari @ 熊本市のブログ。電子工作、プログラミング、ゲーム、TV、 政治、インターネットなどに日々の思い付きを、 うだうだ~と書いていきたい。
このブログにはコメント欄を設けておりません。 記事への御意見、ご質問はtwitter @h_nari宛に お願い致します。


アーカイブ

メタ情報
RSS
Login

XIAOMI湿度計その後

フィラメント・ケースの湿度を監視している XIAOMIの湿度計だがトラブルが発生した。 Linuxサーバーが遅くなる。 調べると bluepy-helperというプロセスが 幾つか全速で走っている。 どうも pythonのbluepyを使用しているプログラムで Peripheralとのconnectionを切断した時に 時々bluepy-helperのプロセスが走りっぱなしに なるようだ。

LYWSD03MMC.pyには bluepy-helperをkillする処理が何箇所か入っているが それでも充分では無いようだ。

いろいろプログラムを試して Threadをセンサー毎に走らせ connectionを繋ぎっぱなしで 切断しないプログラムにしたら bluepy-helper問題は発生しなくなった。 システムのload averageも監視しているが 特に重くなることも無いようだ。

ただし、 pythonでbluepyを使用し scanするプログラムが停止するようになった。 何かエラーが発生しているのだろう。 こちらのプログラムは停止していても さほど問題は無いので、このまま運用することにする。

プログラムを以下に示す。

#!/usr/local/bin/python3 -u
from bluepy import btle
import time
import sys
import os
import requests
import json
import threading
class XiaomiDelegate(btle.DefaultDelegate):
    def __init__(self, addr, sensor_id):
        btle.DefaultDelegate.__init__(self)
        self.addr = addr
        self.sensor_id = sensor_id
        self.tSend = None
    def handleNotification(self, chandle, data):
        if not self.tSend or time.time() - self.tSend > 60*10:
            self.sendData(data)
            self.tSend = time.time()
    def sendData(self, data):
        t = int.from_bytes(data[0:2],byteorder='little',signed=True)/100
        h = int.from_bytes(data[2:3],byteorder='little')
        v = int.from_bytes(data[3:5],byteorder='little')/1000
        s = self.sensor_id
        json_str = json.dumps([{'sensor_id' : s, 'value': t},
                               {'sensor_id' : s+1, 'value' : h},
                               {'sensor_id' : s+2, 'value' : v}])
        r = requests.post('http://my_server_addr/fluentd_port',
                      data=json_str)
def thread_getData(**kwargs):
    addr = kwargs['addr']
    sensor_id = kwargs['sensor_id']
    while True:
        try:
            p = btle.Peripheral(addr)
            p.writeCharacteristic(0x0038, b'\x01\x00', True);
            p.writeCharacteristic(0x0046, b'\xf4\0x01\0x00', True);
            p.withDelegate(XiaomiDelegate(addr, sensor_id))
            while True:
                p.waitForNotifications(10)
        except btle.BTLEException as e:
            print('Error:',e)
if __name__ == '__main__':
    sensors = {
        "A4:C1:38:91:79:3F": 138,
        "A4:C1:38:BC:11:D9": 132,
        "A4:C1:38:1F:EB:AB": 135,
        "A4:C1:38:79:5E:67": 141
    }
    threads = {}
    for addr in sensors:
        print('thread start for',addr)
        threads[addr] = t = threading.Thread(target=thread_getData,
                                             kwargs={'addr': addr,
                                                     'sensor_id':
                                                     sensors[addr]})
        t.start()
        time.sleep(20)

しかし、防湿フィラメント・ケースが完成し 湿度の監視ができるようになったら すっかり秋になり湿度が下がってしまった。 湿度50%ぐらいでも防湿は必要なのだろうか?