初めてのRaspberry Pi BLEプログラミング (3) CPU温度を送る

 前回、examplesのbatteryserviceをそのまま動かしました。固定値の98という数値が送れていたのをRSL10 Bluetooth Low Enaergy Exploerで確認しました。
 ファイルは、

  • main.py
  • Serviceを記述したBatteryService.py
  • Characteristic(キャラ)を記述したBatteryLevelCharacteristic.py

の三つで構成されています。

 BLEでは、GATTサービス(サーバ)というくくりの中に、複数のServiceがあります。そのServiceには、一つもしくは複数のCharacteristicがあります。具体的な数値はCharacteristicの中でValueもしくは、その下の階層DescriptorのValueで送ります。読み出しだけなら、read属性がつきます。

 Serviceには固有のUUIDがあります。きめられたUUID(短い場合が多い)が登録されていたり、オリジナルなUUID(長い)もあります。ややこしいのは、キャラにも固有のUUIDがあります。なくてもよいのですが、キャラのより詳細な記述をするDescriptorにもUUIDがあります。

 batteryserviceのこれらのファイルを修正してCPUの温度を送るようにします。

main.py

 GATTサービスを、マイコンの外に実際に電波を出すのはstartAdvertising()関数です。これはGitHubのpybleno/pybleno/Bleno.pyに書かれています。引数にnameがあります。たぶんLocal Nameです。現在、この関数を呼んでいるのがmain.pyなので、14行目、

bleno.startAdvertising('Battery', [primaryService.uuid]);

を'CPU temp'に変更します。

BatteryLevelCharacteristic.py

 Serviceの記述されたBatteryService.pyは変更しません。
 キャラの書かれたBatteryLevelCharacteristic.pyを大幅にシンプルにし、CPU温度を送るように変更しました。

 shellコマンドのvcgencmd measure_tempは、'b"temp=42.0\'C\\n のような文字列を返します。42という数字は[7:9]でスライスすると、うまく取り出せます。

from pybleno import *
import array
import subprocess

class BatteryLevelCharacteristic(Characteristic):
    def __init__(self):
        Characteristic.__init__(self, {
            'uuid': '2A19',
            'properties': ['read'],
            'value': None
          })

    def onReadRequest(self, offset, callback):
            tvalue_h = int(str(subprocess.check_output(['vcgencmd', 'measure_temp']))[7:9])
            callback(Characteristic.RESULT_SUCCESS, array.array('B', [tvalue_h]))

 実行結果です。42℃です。Readをクリックすると、ペリフェラルのラズパイではonReadRequest()関数を実行して最新のCPU温度値を送ってきます。