Androidのメモとか

ポキオの日記です。今日も遅延してない。

SonosをIFTTT経由でコントロールしてみる(後編)

SonoSwitchをつくるお!

ポキオ Sonos IFTTT

前回までのあらすじ

SonosはIFTTTから制御できそうというところまでわかりました。

relativelayout.hatenablog.com

今回は、IFTTTのSonos Actionsを使うべく、WebhooksをTriggerとして、M5StackからIFTTT経由でSonosのスピーカーの制御をしてみようと思います。

M5Stackって?

詳しい説明は省きますが、ディスプレイやWi-Fi/BTなどがもろもろついた小さなマイコンボードです。

m5stack.com

プログラミング方法も色々ありますが、ブラウザ上でノンコーディングでプログラミングできるUI Flowを使って実装してみようと思います。

やりたいことは以下の通り。

  • Sonosのスピーカーを制御(Prev/Next/Pause)できるSonoSwitch
  • おしゃれなUIを表示
  • ボタンを押すと制御(Prev/Next/Pause)が行えるようにする
  • 裏ではIFTTTのWebhooksへHTTP-GETを行う

ポキオ Sonos IFTTT

IFTTT側の設定

先述の通り、TriggerをWebhooks、ActionをSonosとなるようにレシピを設定します。

ポキオ Sonos IFTTT

レシピは別々のWebhooksイベントで3つ作成します。今回は、それぞれのイベント名をこのようにしました。

  • sonoswitch1:Skip to previous
  • sonoswitch2:Pause
  • sonoswitch3:Skip to next
To trigger an Event
Make a POST or GET web request to:

https://maker.ifttt.com/trigger/{event}/with/key/{key}

それぞれのイベントごとにURLが決まり、ここにHTTP-GETをするとSonosのActionが発火するようになりました。今度は、M5StackからこれらのURLをHTTP-GETできるようにしていきます。

つぎにM5Stack側の実装

とはいえ、まずは(本質的ではないですが)UIを作ってみます。

ポキオ Sonos IFTTT

macOSKeynoteでこんな感じのUIを作ってJPGで保存し、UI Flow経由でM5Stackに流し込みます。SonosのロゴのフォントはGIll Sansが一番近かったです(笑)

UI Flowでは、こんな感じに実装していきます。

ポキオ Sonos IFTTT

MicroPythonのコードは、この記事の後ろの方で晒します。やっていることはざっくりこんな感じで、

  • 起動時にWi-Fi接続
  • ボタン押下時にそれぞれのレシピへのWebhooksへHTTP-GETを送るようにする
  • HTTP-GET成功/失敗時に効果音を出す

これをUI Flowで組んでいきます。

つかってみますー

これが、ふつーに使えます(笑)

ポキオ Sonos IFTTT

Sonosのスピーカーに直接コマンドを送っているわけではないので、1〜2秒のタイムラグはあるものの、Sonosのスピーカーの制御がちゃんとできています!

逆に言えば、インターネット回線さえあれば、理論上は地球の裏側からもSonosのスピーカーを制御できるということですねー。すごいー。

[asin:B07HSBKTFH:detail]

コードはこんな感じです

from m5stack import *
from m5ui import *
from uiflow import *
import wifiCfg
import urequests

setScreenColor(0x222222)




image0 = M5Img(0, 0, "res/SonoSwitch.jpg", True)

statusCode = None


def buttonB_wasReleased():
  global statusCode
  if not (wifiCfg.wlan_sta.isconnected()):
    wifiCfg.reconnect()
    while not (wifiCfg.wlan_sta.isconnected()):
      pass
  try:
    req = urequests.request(method='GET', url='http://maker.ifttt.com/trigger/sonoswitch2/with/key/xxxxxxx', headers={})
  except:
    pass
  statusCode = req.status_code
  pass
btnB.wasReleased(buttonB_wasReleased)

def buttonA_wasReleased():
  global statusCode
  if not (wifiCfg.wlan_sta.isconnected()):
    wifiCfg.reconnect()
    while not (wifiCfg.wlan_sta.isconnected()):
      pass
  try:
    req = urequests.request(method='GET', url='http://maker.ifttt.com/trigger/sonoswitch1/with/key/xxxxxxx', headers={})
  except:
    pass
  statusCode = req.status_code
  pass
btnA.wasReleased(buttonA_wasReleased)

def buttonC_wasReleased():
  global statusCode
  if not (wifiCfg.wlan_sta.isconnected()):
    wifiCfg.reconnect()
    while not (wifiCfg.wlan_sta.isconnected()):
      pass
  try:
    req = urequests.request(method='GET', url='http://maker.ifttt.com/trigger/sonoswitch3/with/key/xxxxxxx', headers={})
  except:
    pass
  statusCode = req.status_code
  pass
btnC.wasReleased(buttonC_wasReleased)


statusCode = -1
wifiCfg.autoConnect(lcdShow = False)
while not (wifiCfg.wlan_sta.isconnected()):
  pass
speaker.tone(1800, 100)
while True:
  if statusCode > 0:
    if statusCode == 200:
      speaker.tone(1800, 100)
      speaker.tone(2400, 100)
    else:
      speaker.tone(1800, 300)
    statusCode = -1
  wait_ms(2)
「Androidのメモとか」は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。

このブログは個人的なメモ書きであったり、考えを書く場所であります。執筆者の所属する団体や企業のコメントや意向とは無関係であります。また、このブログは必ずしも正しいことが書かれているとは限らず、誤字脱字や意図せず誤った情報を載せる場合がありえます。それが原因で読者が不利益を被ったとしても、執筆者はいかなる責任も負いません。ありがとうございます。