
X(旧Twitter)に代わるソーシャルメディアプラットフォームの人気が高まっているようです。BlueSkyは現在1500万人のユーザーを抱えています。政治的な話はさておき、私はX、Mastodon、BlueSkyを3つ使い分けていますが、それぞれに長所と短所があります。
Xの強みの一つは、アプリとボットでした。開発者APIを使えば、ユーザーとインタラクションするアプリを簡単に構築できました。Raspberry Piの登場により、Xを使ってGPIOとインタラクションできるようになりました。センサーを搭載したRaspberry Piを使えば、Xのフォロワーにデータを送信でき、フォロワーはRaspberry Pi Pico WのNeoPixelの色を変えるトリガーを打つことができます。Mastodonでも同じことが可能です。これはまだ詳しく調査が必要ですが、ここでBlueSkyの出番です。
先週、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がコンピュータにインストールされました
デモ回路の構築
デモ回路はLEDとDHT11温度センサーの2つのセクションで構成されています。
まずはLEDに取り組みましょう。
スワイプして水平にスクロールします
ラズベリーパイ ピコ GPIO | 配線色 | LED接続 |
---|---|---|
GPIO 15 | 緑 | 陽極(+、長い脚) |
GND | 黒 | カソード(-、短い脚)100オームの抵抗器経由 |
LEDには2つのピンしかありません。アノード(長い脚)とカソード(短い脚)です。アノードはRaspberry Pi Pico WのGPIO 15に直接接続します。カソードは100Ωの抵抗を介してPico Wの任意のGNDピンに接続します。この抵抗はLEDの消費電流を制限し、LEDの寿命を延ばします。
最後に、DHT11温湿度センサーです。4つのピンがありますが、実際に使えるのは3つだけです。
スワイプして水平にスクロールします
ラズベリーパイ ピコ 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 アカウントを開き、「設定」歯車をクリックして「アプリ パスワード」まで下にスクロールします。
6. 「アプリパスワードの追加」をクリックします。
7.アプリ パスワードに「Python」という名前を付け、「アプリ パスワードの作成」をクリックします。
8.コードをテキストファイルにコピーし、「完了」をクリックします。このコードはBlueskyで再び表示されることはありません。
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」の執筆・提供にも携わっています。