DUICUO

CircuitPython とオープンソース ツールを使用して温室を監視するにはどうすればよいですか?

[[406443]]

温室の温度、湿度、周囲光は、マイクロコントローラ、センサー、Python、MQTT を使用して継続的に追跡されます。

CircuitPythonは、マイクロコントローラボードと対話するための革新的な方法を提供します。この記事では、CircuitPythonを使用して温室内の温度、湿度、周囲光を監視し、CircuitPython MQTTクライアントを使用してその結果をMQTTプラットフォームにパブリッシュする方法を説明します。仲介者ブローカMQTT キューをサブスクライブし、複数のプログラムで情報をさらに処理できます。

このプロジェクトでは、シンプルな Python プログラムを使用して、Prometheus 形式のデータ収集エンドポイントを公開する Web サーバーを実行し、継続的な監視のために監視メトリックを Prometheus にプルします。

CircuitPythonについて

CircuitPythonは、Adafruitが低価格のマイクロコントローラ開発ボードで動作するように作成したオープンソースのPythonディストリビューションです。CircuitPythonは、互換性のある開発ボードと連携するためのシンプルな開発環境を提供します。開発ボードを接続するとマウントされるCIRCUITPYTHONルートドライブにcode.pyファイルを作成することで、プログラムを開始できます。CircuitPythonは開発ボードへのシリアル接続も提供しており、対話型インタープリタ(REPL)セッションもサポートしているため、Pythonコードを使用してボードとリアルタイムでやり取りできます。

Adafruitのウェブサイトでは、CircuitPythonを使い始めるのに役立つ豊富なドキュメントを提供しています。まず、「CircuitPythonへようこそ」ガイドをご覧ください。このガイドは、CircuitPythonを使って開発ボード上でコードを実行し、REPLを操作する方法を学ぶのに役立ちます。また、Adafruitが販売する多くの開発ボードやセンサーで使用できるCircuitPythonライブラリとサンプルのコレクションをインストールする方法についても説明しています。次に、「CircuitPythonの基礎」ガイドを読んで、CircuitPythonの機能についてさらに詳しく学びましょう。このガイドには、特定の互換性のある開発ボードでCircuitPythonを使用する方法に関する情報へのリンクも含まれています。最後に、他のオープンソースソフトウェアと同様に、CircuitPythonのソースコードを調べたり、リリースの問題に対処したり、貢献したりすることができます。

マイクロコントローラの設定

マイクロコントローラシステムは非常にシンプルです。このサンプルプロジェクトを完了するには、以下のものが必要です。

  • Raspberry Pi 4 : マイクロコントローラー システムをプログラムするにはコンピューターが必要です。私は Raspberry Pi 4 を使用しました。
  • CircuitPython 対応マイクロコントローラー: WiFi、周囲光センサー、Qwiic ケーブル入力を内蔵した Adafruit Feather S2 を使用しました。
  • マイクロコントローラーのWiFi :Feather S2にはWiFiが内蔵されています。お使いのマイクロコントローラーにWiFiが内蔵されていない場合は、開発ボード用のWiFi拡張ボードが必要になります。
  • センサー:Feather S2には環境光センサーが内蔵されているため、温度と湿度センサーも必要でした。Adafruit、SparkFun、Amazonなど、多くのメーカーから選択肢があります。私はAdafruitのセンサーと、Feather S2入力対応のQwiicケーブルを使用しました。ほとんどのSparkFunセンサーはAdafruitライブラリで動作しますが、Adafruit以外からセンサーを購入した場合は、CircuitPython互換のPythonライブラリを自分で探す必要があるでしょう。
  • パッチコードとケーブル:ブレッドボードやはんだ付けを使わないように、AdafruitのQwiicケーブルを使用しています。SparkFunが販売しているケーブルキットにも、長さの異なるケーブルが揃っています。

センサーをコンピューターに接続する前に、マイクロコントローラーに接続します。

センサーをマイクロコントローラに接続する

これで、USB ケーブルを使用してマイクロコントローラーをコンピューターに接続できます。

MQTT仲介者

このガイドに従って、Raspberry Pi システムに Mosquitto MQTT メディエーターと Mosquitto クライアントをインストールできます。Raspberry Pi を長期サーバーとして使用する場合は、ネットワーク上で Raspberry Pi 4 に静的 IP アドレスを設定してください。Mosquitto メディエーターが起動したら、ユーザー名/パスワードファイルを作成し、メディエーターを使用してメッセージをパブリッシュおよびサブスクライブする際にクライアントが使用する認証情報を設定してください。

Raspberry PiでMosquittoクライアントを使用してMQTTメディエーターをテストできます。2つのターミナル(ヘッドレスシステムの場合は2つのSSHセッション)を開きます。

ターミナルに次のように入力します。

  1. mosquitto_sub - h localhost - u $user - P $pass - t "mqtt/test"

このコマンドは、 mqtt/testキューに公開されたメッセージをリッスンする継続的に実行されるプロセスを開始します。

ターミナル2で以下を入力します。

  1. mosquitto_pub - h localhost - u $user - P $pass - t "mqtt/test" - m hello `

このコマンドはmqtt/testキューにメッセージを公開し、ターミナル 1 の出力に表示されます。

これで、ターミナル 1 で実行されているsubコマンドを終了できます。

Mosquitto の仲介機能により、クライアントはサブスクライバーがいないキューであっても、任意のキューにメッセージをパブリッシュできます。これらのメッセージは永久に失われますが、クライアントが引き続きメッセージをパブリッシュすることを妨げるものではありません。

3 番目のターミナルを開き、次のキュー (コントローラーがメッセージを公開するキュー) をサブスクライブします。

  • 温室/温度
  • 温室/ライト
  • 温室/湿度

マイクロコントローラのエンコード

これで、マイクロコントローラーをコーディングし、そのメトリックを Raspberry Pi 4 で実行されている MQTT 仲介者に公開する準備が整いました。

Adafruit には、CircuitPython ライブラリ コレクションを使用してマイクロコントローラーを WiFi ルーターに接続し、監視メトリックを MQTT 仲介者に公開する方法を説明する優れたドキュメントがあります。

以下のライブラリをCIRCUITPYTHON/libディレクトリにインストールしてください。これらは温室モニタリングに使用されます。これらのライブラリは、AdafruitのCircuitPythonライブラリコレクションから入手できます。

  • adafruit_bus_device : 複数の .mpy ファイルを含む Python パッケージ フォルダー (.mpy ファイルはスペースを節約するために圧縮された Python ファイルです)。
  • adafruit_requests : 単一の.mpyファイル
  • adafruit_register : パッケージフォルダ
  • adafruit_minimqtt : パッケージフォルダ
  • adafruit_si7021 : 温度センサーと湿度センサーをサポートするために使用される単一の .mpy ファイル。

ライブラリをインストールしたら、 CIRCUITPYTHONフォルダーのcode.pyファイルに次のコードを追加します。

  1. import time
  2. import ssl
  3. import socketpool
  4. import wifi
  5. import adafruit_minimqtt . adafruit_minimqtt as MQTT
  6. import board
  7. from digitalio import DigitalInOut , Direction , Pull
  8. from analogio import AnalogIn
  9. import adafruit_si7021
  10.  
  11. # Add a secrets . py to your filesystem that has a dictionary called secrets with "ssid" and
  12. # "password" keys with your WiFi credentials . DO NOT share that file or commit it into Git or other
  13. # source control .
  14. # pylint : disable = no - name - in - module , wrong - import - order
  15. try :
  16.         from secrets import secrets
  17. except ImportError :
  18.         print ( "WiFi secrets are kept in secrets.py, please add them there!" )
  19.         raise
  20.  
  21. print ( "Connecting to %s" % secrets [ "ssid" ])
  22. wifi . radio . connect ( secrets [ "ssid" ], secrets [ "password" ])
  23. print ( "Connected to %s!" % secrets [ "ssid" ])
  24. ### Feeds ###
  25. light_feed = "greenhouse/light"
  26. temp_feed = "greenhouse/temperature"
  27. humidity_feed = "greenhouse/humidity"
  28.  
  29. # Define callback methods which are called when events occur
  30. # pylint : disable = unused - argument , redefined - outer - name
  31. def connected ( client , userdata , flags , rc ):
  32.         # This function will be called when the client is connected
  33.         # successfully to the broker .
  34.         print ( "Connected to MQTT!" )
  35.  
  36. def disconnected ( client , userdata , rc ):
  37.         # This method is called when the client is disconnected
  38.         print ( "Disconnected from MQTT!" )
  39.  
  40.  
  41. def get_voltage ( pin ):
  42.         return ( pin . value * 3.3 ) / 65536
  43.  
  44. # Create a socket pool
  45. pool = socketpool . SocketPool ( wifi . radio )
  46.  
  47. # Set up a MiniMQTT Client
  48. mqtt_client = MQTT . MQTT (
  49. broker = secrets [ "broker" ],
  50. port = secrets [ "port" ],
  51. username = secrets [ "aio_username" ],
  52. password = secrets [ "aio_key" ],
  53. socket_pool = pool ,
  54. ssl_context = ssl . create_default_context (),
  55. )
  56.  
  57. # Setup the callback methods above
  58. mqtt_client . on_connect = connected
  59. mqtt_client . on_disconnect = disconnected
  60.  
  61. # Connect the client to the MQTT broker .
  62. print ( "Connecting to MQTT..." )
  63. mqtt_client . connect ()
  64.  
  65. # Create library object using our Bus I2C port
  66. sensor = adafruit_si7021 . SI7021 ( board . I2C ())
  67. light_pin = AnalogIn ( board . IO4 )
  68.  
  69. while True :
  70.         # Poll the message queue
  71. mqtt_client . loop ()
  72.  
  73.         # get the current temperature
  74. light_val = get_voltage ( light_pin )
  75. temp_val = (( sensor . temperature * 9 )/ 5 ) + 32
  76. humidity_val = sensor . relative_humidity
  77.  
  78.         # Send a new messages
  79. mqtt_client . publish ( light_feed , light_val )
  80. mqtt_client . publish ( temp_feed , temp_val )
  81. mqtt_client . publish ( humidity_feed , humidity_val )
  82.         time . sleep ( 0.5 )

コードを保存してください。シリアルモニターに接続して、プログラムがMQTT中継器にどのように接続するかを確認してください。Raspberry Pi 4のターミナルを、パブリッシュキューをサブスクライブしているターミナルに切り替えて、出力を確認することもできます。

処理監視指標

MQTTのようなパブリッシュ/サブスクライブ型ワークフローは、マイクロコントローラーシステムに多くのメリットをもたらします。複数のマイクロコントローラーとセンサーを組み合わせて、同じシステムに対して異なるメトリクスを報告したり、同じメトリクスの複数の測定値を並列に報告したりできます。また、複数の異なるプロセスが様々なキューをサブスクライブし、これらのメッセージに並列で応答することも可能です。さらに、複数のプロセスが同じキューをサブスクライブし、メッセージに対して異なるアクションを実行することも可能です。例えば、値が高すぎる場合に通知メールを送信したり、メッセージを別のMQTTキューに送信したりといったことが可能です。

もう1つの選択肢は、マイクロコントローラを外部キューにサブスクライブさせることです。これにより、マイクロコントローラにセッションの終了や新規セッションの開始などのアクションを実行するよう信号を送ることができます。最後に、パブリッシュ/サブスクライブ型ワークフローは、低消費電力のマイクロコントローラシステム(バッテリーや太陽光発電を使用するシステムなど)に適しています。これらのデバイスは、長いレイテンシ期間の後に監視メトリクスを一括でパブリッシュし、リターン間のインターバルで電力を大量に消費するWi-Fiブロードキャストを停止できるためです。

これらのメトリクスを処理するために、Pythonクライアントを作成し、Paho Python MQTTクライアントを使用してメトリクスキューをサブスクライブしました。また、公式のPrometheus Pythonクライアントを使用してWebサーバーも作成しました。このクライアントは、これらのメトリクスをダッシュ​​ボード情報として使用するPrometheus準拠のデータ収集エンドポイントを生成します。PrometheusサーバーとMosquitto MQTT仲介サーバーは、同じRaspberry Pi 4上で動作しています。

  1. from prometheus_client import start_http_server , Gauge
  2. import random
  3. import time
  4. import paho . mqtt . client as mqtt
  5. gauge = {
  6.   "greenhouse/light" : Gauge ( 'light' , 'light in lumens' ),
  7.   "greenhouse/temperature" : Gauge ( 'temperature' , 'temperature in fahrenheit' ),
  8.   "greenhouse/humidity" : Gauge ( 'humidity' , 'relative % humidity' )
  9. }
  10. try :
  11.         from mqtt_secrets import mqtt_secrets
  12. except ImportError :
  13.         print ( "WiFi secrets are kept in secrets.py, please add them there!" )
  14.         raise
  15. def on_connect ( client , userdata , flags , rc ):
  16.         print ( "Connected with result code " + str ( rc ))
  17.         # Subscribing in on_connect () means that if we lose the connection and
  18.         # reconnect then subscriptions will be renewed .
  19. client . subscribe ( "greenhouse/light" )
  20. client . subscribe ( 'greenhouse/temperature' )
  21. client . subscribe ( 'greenhouse/humidity' )
  22. def on_message ( client , userdata , msg ):
  23. topic = msg . topic
  24. payload = msg . payload
  25. gauge [ topic ]. set ( payload )
  26. client = mqtt . Client ()
  27. client . username_pw_set ( mqtt_secrets [ "mqtt_user" ], mqtt_secrets [ 'mqtt_password' ])
  28. client . on_connect = on_connect
  29. client . on_message = on_message
  30. client . connect ( 'localhost' , 1883 , 60 )
  31. if __name__ == '__main__' :
  32.         # Start up the server to expose the metrics .
  33. client = mqtt . Client ()
  34. client . username_pw_set ( 'london' , 'abc123' )
  35. client . on_connect = on_connect
  36. client . on_message = on_message
  37. client . connect ( 'localhost' , 1883 , 60 )
  38. start_http_server ( 8000 )
  39. client . loop_forever ()

次に、エンドポイント データをlocalhost:8000に収集するように Prometheus サーバーを構成しました。

Greenhouse MQTTマイクロコントローラープロジェクトのコードはGitHubからアクセスできます。このプロジェクトはMITライセンスの下でライセンスされています。