54
Raspberry Pi Pico WでBlueSkyの投稿を送受信する方法
ブルースカイ
(画像クレジット:Tom's Hardware / Pexels)

X(旧Twitter)に代わるソーシャルメディアプラットフォームの人気が高まっているようです。BlueSkyは現在1500万人のユーザーを抱えています。政治的な話はさておき、私はX、Mastodon、BlueSkyを3つ使い分けていますが、それぞれに長所と短所があります。 

Xの強みの一つは、アプリとボットでした。開発者APIを使えば、ユーザーとインタラクションするアプリを簡単に構築できました。Raspberry Piの登場により、Xを使ってGPIOとインタラクションできるようになりました。センサーを搭載したRaspberry Piを使えば、Xのフォロワーにデータを送信でき、フォロワーはRaspberry Pi Pico WのNeoPixelの色を変えるトリガーを打つことができます。Mastodonでも同じことが可能です。これはまだ詳しく調査が必要ですが、ここでBlueSkyの出番です。

ブルースカイ

(画像提供:Tom's Hardware)

先週、BlueSky の API であるatprototoolsに関するメッセージを目にしました。これは、X にあるのと同じ機能を BlueSky プラットフォームを使って実現するものです。最初は半信半疑でしたが、試してみました。とてもうまく動作し、1 時間も経たないうちに Python アプリを実行することができました。しかし、もっと便利なものが欲しかったので、それには Raspberry Pi が必要でした。そこで、アプリを Raspberry Pi 5 に移行することを検討し始めました。確かにうまくいくと思いましたが、その後、仲間のメーカーで BlueSky ユーザーでもある Mike Bell さんがアイデアを思いつきました。Bell さんのアイディアは、atprototools モジュールを Raspberry Pi Pico W で使用できるかどうかを確認するというものでした。数時間後、Pico W で BlueSky からの投稿を読むことができるようになりました。さらに数時間後、Bell さんは Pico W から BlueSky に投稿できるようになりました。

このハウツーを作成するのに必要なのはこれだけです。Raspberry Pi Pico Wを搭載したデバイスを構築し、BlueSkyアカウント(そして私たちのアカウントのみ)の最新の投稿を読み取り、DHT11温度センサーを使って温度をチェックします。温度はBlueSkyにメッセージとして送信されます。Pico Wは、次のメッセージが届くのを待ち、プロセスを開始します。

スパム行為や迷惑行為に使用しないでください。テストの際は、フォロワーの体験を損なわないように、予備のアカウントで使用してください。 

最後に、そして最も重要なこととして、この方法を可能にしてくれた Mike Bell の助力と努力に深く感謝します。

このプロジェクトに必要なものは

Tom's Hardware の最高のニュースと詳細なレビューをあなたの受信箱に直接お届けします。

  • BlueSkyアカウント
  • ラズベリーパイ ピコW
  • ブレッドボード×1
  • LED 1個
  • 1 x 100オーム抵抗器(茶-黒-茶-金)
  • 1 x DHT11
  • オス-オスジャンパーワイヤー5本
  • Thonnyがコンピュータにインストールされました

デモ回路の構築

ブルースカイ

(画像提供:Tom's Hardware)

デモ回路はLEDとDHT11温度センサーの2つのセクションで構成されています。

まずはLEDに取り組みましょう。

ブルースカイ

(画像提供:Tom's Hardware)

スワイプして水平にスクロールします

ラズベリーパイ ピコ GPIO配線色LED接続
GPIO 15陽極(+、長い脚)
GNDカソード(-、短い脚)100オームの抵抗器経由

LEDには2つのピンしかありません。アノード(長い脚)とカソード(短い脚)です。アノードはRaspberry Pi Pico WのGPIO 15に直接接続します。カソードは100Ωの抵抗を介してPico Wの任意のGNDピンに接続します。この抵抗はLEDの消費電流を制限し、LEDの寿命を延ばします。

最後に、DHT11温湿度センサーです。4つのピンがありますが、実際に使えるのは3つだけです。

ブルースカイ

(画像提供:Tom's Hardware)

スワイプして水平にスクロールします

ラズベリーパイ ピコ GPIO配線色DHT11
3V3(物理ピン36)ピン1
GPIO 17黄色ピン2
GNDピン4

DHT11の電源は、Raspberry Pi Picoの3V3ピンから供給されます。このピンはDHT11のピン1に接続されています。データ接続はDHT11のピン2で、Pico WのGPIO 17に接続されています。これにより温度データを取得します。最後に、DHT11のピン4はGNDで、PicoのどのGNDにも接続できます。

配線を確認し、準備ができたらコーディングセクションに進みます。

BlueSky 温度ボットのコーディング

この記事の執筆時点では、Raspberry Pi Pico W をセットアップするために必要な手順を記載しています。数週間/数ヶ月後には変更される可能性が高いですが、状況を注視し、適宜更新していきます。

1.このハウツーのステップ 6までを実行して、 Raspberry Pi Pico W で MicroPython が実行され、Thonny を実行しているコンピューターに接続されるようにします。

2.新しい空のプロジェクトを作成し、ここからコードをコピーして、新しい空のファイルに貼り付けます。これは、Mike BellがRaspberry Pi Pico Wで実行できるように修正したコードです。

3.ファイルを atprototools.py として Raspberry Pi Pico W のルートに保存します。

4.別の空のファイルを作成し、ここにあるコードをコピーして貼り付けます。ファイルを datetime.py として Raspberry Pi Pico W のルートに保存します。atprototoolsモジュールが BlueSky の投稿を正しく取得して送信できるように、datetime が必要です。

5.ブラウザで Bluesky アカウントを開き、「設定」歯車をクリックして「アプリ パスワード」まで下にスクロールします。

ブルースカイ

(画像提供:Tom's Hardware)

6. 「アプリパスワードの追加」をクリックします。

ブルースカイ

(画像提供:Tom's Hardware)

7.アプリ パスワードに「Python」という名前を付け、「アプリ パスワードの作成」をクリックします。

ブルースカイ

(画像提供:Tom's Hardware)

8.コードをテキストファイルにコピーし、「完了」をクリックします。このコードはBlueskyで再び表示されることはありません。

ブルースカイ

(画像提供:Tom's Hardware)

9. Thonnyに戻り、新しいファイルを作成し、その中にSSID、PASSWORD、BSKY_USERNAME、BSKY_PASSWORDの4つのオブジェクトを作成します。引用符の中にあなたの情報を入力します。Blueskyのユーザー名はプロフィールURLの最後の部分なので、私の場合は「biglesp.bsky.social」です。BSKY_PASSWORDは先ほど作成したアプリのパスワードです。

SSID = “YOUR WI-FI ACCESS POINT”
PASSWORD = “YOUR WI-FI PASSWORLD
BSKY_USERNAME= ‘YOUR BLUESKY HANDLE”
BSKY_PASSWORD = “THE APP PASSWORD”

10.ファイルを secrets.py として Raspberry Pi Pico に保存します。

11.プロジェクト コード用の新しいファイルを作成します。

12. Wi-Fi アクセス (ネットワーク)、BlueSky (atprototools)、Wi-Fi および BlueSky の資格情報 (シークレット)、ネットワーク タイム プロトコル (ntp)、コード一時停止 (スリープ)、および GPIO の制御 (マシン) 用の事前に記述されたコードのモジュールをインポートします。

import network
from atprototools import Session
from secrets import SSID, PASSWORD, BSKY_USERNAME, BSKY_PASSWORD
import ntptime
from time import sleep
from machine import Pin

13. LEDが接続されているGPIOピンをコードに伝えるオブジェクト「led」を作成します。そして、これを使ってLEDを消灯させます。

led = Pin(15, Pin.OUT)
led.off()

14. wlanというオブジェクトを使って、Raspberry Pi Pico WをWi-Fiに接続します。これによりWi-Fiがアクティブになり、APへの接続を試行します。接続に失敗した場合(False)、1秒ごとに試行を続けます。

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while wlan.isconnected() is False: print('Waiting for connection...') sleep(1)

15. NTPを使用して、現在の時刻と日付を設定します。Pico WとBlueSkyが共通の時刻参照を持つように、この設定を行う必要があります。そうしないと、コードがクラッシュします。

ntptime.settime()

16.オブジェクトとセッションを作成し、それを使用して BlueSky に接続します。

session = Session(BSKY_USERNAME, BSKY_PASSWORD)

17. while True (永久) ループで始まるコードを実行するための例外ハンドラーを作成します。

try: while True:

18. latest_bloot オブジェクトを作成し、BlueSky セッションから返されたデータを保存するために使用します。これは基本的に、Python API が BlueSky から取得できるデータを JSON 形式でダンプしたものです。

 latest_bloot = session.getLatestBloot(BSKY_USERNAME).json()

19. if文を使って、ユーザーアカウントからの最新のメッセージを確認します。「Temp Check」というフレーズが(正確に)含まれている場合、条件はTrueとなり、以下のコードが実行されます。

 if latest_bloot['feed'][0]['post']['record']['text'] == "Temp Check":

20. forループを使ってLEDを3回点滅させます。これはPico Wがコマンドを受信したことを示します。

 for i in range(3): led.on() sleep(0.3) led.off() sleep(0.3)

21. DHT11を使用して温度を測定し、返された値を小数点以下2桁に丸め、メッセージで使用するために文字列に変換します。返される温度は摂氏単位であることに注意してください。

 sensor.measure() temp = round(sensor.temperature(),2) temp = str(temp)

22.メッセージのコンテキストを識別し、末尾にデータを追加するBlueSky投稿を作成します。この場合は、室温と実際の温度(摂氏)です。

 post = session.postBloot("The room temperature is "+temp+"C")

23. ユーザーからのメッセージがない場合、else条件を作成してPico Wを強制的に待機させ、ループが高速に実行されないようにスリープを追加します。BlueSkyにはレート制限があるため、新しいメッセージを常にチェックするとPico Wの接続が切断される可能性があることに注意してください。最大でも1分に1回チェックすることをお勧めします。

 else: print("Waiting for message") sleep(60)

24.キーエラーを捕捉するための例外を作成します。これは、返されたJSONフィードにデータが含まれていない場合、通常はレート制限に達した場合に発生するエラーです。

except KeyError as e: print('I got a KeyError - reason "%s"' % str(e))

25.コードを bsky.py として Raspberry Pi Pico W のルートに保存します。

26.緑色の「実行」ボタンをクリックしてコードを実行します。Pico WはWi-Fiへの接続を試み、接続が完了すると、スクリプトはフィード内の最新のメッセージで「Temp Check」をチェックします。そのメッセージが表示されると、コードが起動し、LEDが3回点滅します。その後、温度が測定され、BlueSkyに投稿されます。

bsky.py の完全なコードリスト

import network
from atprototools import Session
from secrets import SSID, PASSWORD, BSKY_USERNAME, BSKY_PASSWORD
import ntptime
from time import sleep
from machine import Pin
import dht
sensor = dht.DHT11(Pin(17))
led = Pin(15, Pin.OUT)
led.off()
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while wlan.isconnected() is False: print('Waiting for connection...') sleep(1)
ntptime.settime()
session = Session(BSKY_USERNAME, BSKY_PASSWORD)
try: while True: latest_bloot = session.getLatestBloot(BSKY_USERNAME).json() if latest_bloot['feed'][0]['post']['record']['text'] == "Temp Check": for i in range(3): led.on() sleep(0.3) led.off() sleep(0.3) sensor.measure() temp = round(sensor.temperature(),2) temp = str(temp) post = session.postBloot("The room temperature is "+temp+"C") else: print("Waiting for message") sleep(1)
except KeyError as e:
print('I got a KeyError - reason "%s"' % str(e))

レス・パウンダーは、トムズ・ハードウェアのアソシエイトエディターです。クリエイティブテクノロジストとして、7年間にわたり、老若男女を問わず、教育と啓発のためのプロジェクトを手がけてきました。Raspberry Pi Foundationと協力し、教師向けトレーニングプログラム「Picademy」の執筆・提供にも携わっています。