Quantcast
Channel: uchimanajet7のメモ
Viewing all articles
Browse latest Browse all 32

SORACOM Flux を使って SORACOM LTE-M Button for Enterprise のクリックを Slack に通知する方法 #SORACOM #soracomug

$
0
0

目次

Please check it.

この記事は、 2024 年 8 月時点 (以下、現時点)の情報に基づいて記載しています。現時点では、株式会社ソラコムに所属していますが、本記事の内容はあくまで個人の意見であり、所属する会社や組織とは一切関係ありません。


(参考)
「一般消費者が事業者の表示であることを判別することが困難である表示」の指定及び「『一般消費者が事業者の表示であることを判別することが困難である表示』の運用基準」の公表について

前提

この記事は、SORACOM Advent Calendar 2022 の 23 日目に書いた記事で紹介した内容を、別の手段で実現したものです。

uchimanajet7.hatenablog.com

今回紹介する方法では、SORACOM Flux を使うことで、必要に応じて SORACOM 内で処理を完結でき、Make を利用するよりも手軽に利用できる場合があります。どちらの方法も一つの手段に過ぎませんので、ご自身のニーズに合う部分があれば、参考にしていただけると嬉しいです。

SORACOM LTE-M Button for Enterprise

SORACOM LTE-M Button for Enterprise (以下、ボタン) は、ボタンを押すことでクラウドに通知を送信できます。この通知をトリガーとするクラウド側のシステムを実装することで、メールの送信や特定の動作を行えます。詳細については、以下のリンクを参照してください。

soracom.jp

users.soracom.io

このボタンには他にも幾つかのシリーズがあり、用途に応じて選択できます。

users.soracom.io

IoTデバイスといえば、センシングしてデータを継続的にクラウドに送信するものをイメージする方も多いと思いますが、このボタンはユーザーがアクションを起こせるデバイスです。今回のように、ちょっとした試みを実装する場合には、打って付けのデバイスと言えるのではないでしょうか?

SORACOM Flux

SORACOM Flux (以下、Flux) は、デバイスから送信されたセンサーデータやカメラ画像に対してルールを適用し、複数のデータソースや生成AIを組み合わせて分析・判断を行うような、IoT アプリケーションをローコードで構築できるサービスです。詳細については、以下のリンクを参照してください。

soracom.jp

users.soracom.io

Flux を使えば、ローコードで複数のサービスを連携させ、実現したいことを簡単に実装できます。IFTTT や Zapier のような iPaaS (Integration Platform as a Service) をイメージしていただけるとわかりやすいかと思います。

Flux は現時点では初期リリース段階であり、Freeプランのみが提供されています。

soracom.com

これからの進化に期待しつつ、現時点の Flux で、できることを試してみたいと思います。

ボタンをクリックした際にメールを送信するには

ボタンをクリックした際にメールを送信したい場合、SORACOM ユーザーコンソールに用意されている機能を利用することで、簡単にメールを送信できます。詳細については、以下のリンクを参照してください。

users.soracom.io

この機能は SORACOM で、あらかじめ用意されているため、SORACOM ユーザーサイトの案内に従って必要な項目を設定するだけで、簡単にメールを送信できます。

ボタンには以下の3種類のクリックタイプがあります。

  1. SINGL : シングルクリック
  2. DOUBLE: ダブルクリック
  3. LONG: 長押し

今回は、ボタンのクリックに応じてメールを送信する代わりに、SORACOM Flux を利用して、ボタンのクリックタイプに応じた内容で、Slack に通知する方法を試してみたいと思います。

なぜ Slack 通知なのか?

以前、Make を利用した際にはメールを送信していましたが、今回は Slack に通知を行います。 その理由は、現時点で Flux が Free プランのみで提供されており、メール通知には制限があるためです。また、メール通知の送信先アドレスを設定するには、SORACOM ユーザーコンソールのルートユーザーである必要があり、一部のユーザーにとって設定が難しい可能性があるためです。

詳細については、以下のリンクを参照してください。

users.soracom.io

次のステップでは、通知先として Slack の設定していきます。

通知先の Slack を準備する

すでに Slack を利用している場合、今回の Flux からの通知に必要な Incoming Webhooks の設定を行ってください。設定の詳細については、以下のリンクを参照してください。

api.slack.com

qiita.com

もし、Slack の利用が初めての場合は、以下のリンクを参照して準備を行ってください。

slack.com

Webhook URL が発行できれば、Slack 側の設定は完了です。今回はこの Webhook URL に対して Flux から通知を送信します。Webhook URL が準備できたら、次は SORACOM ユーザーコンソールでの設定に移ります。

SORACOM ユーザーコンソールでボタンの準備をする

SORACOM ユーザーコンソールは、すでにボタンを利用中であればログインできるはずです。 詳細については、以下のリンクを参照してください。

users.soracom.io

現時点では、IoT デバイスから送信された情報を SORACOM Flux で利用するには、Unified Endpoint を通じてデータを送信する必要があります。

users.soracom.io

ボタンは Unified Endpoint を利用してデータを送信しているため、そのままの設定で Flux でデータを活用できます。

users.soracom.io

ボタンの SIM グループを確認する

ボタンは登録する際に、SIM グループを設定しています。 詳細については、以下のリンクを参照してください。

users.soracom.io

これは、ボタンに Embedded (MFF2) の IoT SIM (plan-KM1) が内蔵されており、SORACOM ユーザーコンソール上で IoT SIM として管理されるからです。

ボタンのメニューから SIM グループを編集をクリックし、SIM グループの設定を確認します。

SIM グループの設定では、次の点を確認してください。

  1. SORACOM Air for セルラーの設定項目で 簡易位置測位機能バイナリパーサーONになっていること。
  2. バイナリパーサーのフォーマットに @buttonが指定されていること。

    users.soracom.io

正しく設定されていない場合は、適切に設定を行ってください。

SORACOM Harvest

SORACOM Harvest (以下、Harvest) は、デバイスから送信されたデータやファイルをSORACOM で収集・蓄積するサービスです。詳細については、以下のリンクを参照してください。

soracom.jp

Harvest を使ってボタンのデータを確認する手順の詳細については、以下のリンクを参照してください。

users.soracom.io

Harvest でボタンのデータが確認できれば、結果的に SIM グループの設定が、正しく行われていることも確認できます。

SORACOM Flux でアプリを作成する

ここからは、SORACOM Flux を使ってアプリを作成していきます。Flux アプリを構成するコンポーネントの詳細については、以下のリンクを参照してください。

users.soracom.io

まず、Flux でボタンからのデータを扱うために、イベントソースの設定を行います。

ボタンからデータを受け取るイベントソースを設定する

各イベントソースの詳細については、以下のリンクを参照してください。

users.soracom.io

今回は、ボタンからのデータを利用するために、IoT デバイスイベントソースを設定します。

users.soracom.io

イベントソースが正しく設定されているかを確認するには、実際にボタンを押してデータを送信します。設定したイベントソースの メッセージ履歴にボタンからのデータが表示されていれば、Flux で正しくデータが受信できています。

ボタンからデータが送信され、Flux で利用可能になったので、次はアクションの追加を行います。

Slack に通知するアクションを設定する

ここでは、ボタンから送信されたデータを Slack に通知するアクションを設定します。

users.soracom.io

まず、Slack の設定で払い出された Webhook URL を、このアクションの URL欄に入力します。 次に、PAYLOADには Slack に通知したいテキスト文字列を入力します。今回は、ボタンから送信されたデータをそのまま確認したいので、以下のように設定しました。

  •  
  • SORACOM LTE-M ボタンがクリックされました
  •  
  • -----
  • `event.payload`
  • ```
  • ${event.payload}
  • ```
  •  
  • `event.context`
  • ```
  • ${event.context}
  • ```
  • -----
  •  
  • ${getUTCYear(now())}/${getUTCMonth(now())}/${getUTCDate(now())} ${getUTCHours(now())}:${getUTCMinutes(now())}:${getUTCSeconds(now())} UTC
  •  

${}で記載されている部分は、送信されたデータを利用するための記法です。 詳細については、以下のリンクを参照してください。

users.soracom.io

今回の通知では、ボタンから送信されたデータ (payload) と、ヘッダーに付与された情報 (context) をそのまま表示しています。さらに、Flux で通知した日時情報を UTCで付加しています。

条件によって異なる内容を Slack に通知をする

ここまでで、Flux を利用した Slack への通知は実現できました。 次に、ボタンのクリックタイプに応じて、Slack への通知の内容を変更できるように設定します。

もし、通知する Slack チャンネルも変更したい場合は、必要に応じて新たに Webhook URL を払い出してください。

Slack に通知するアクションを追加する

すでに設定済みの Slack 通知と同様の内容で、新たに Slack 通知アクションを追加します。現時点ではアクションをコピーする機能がないため、手動で設定を行ってください。

今回は、通知先の Webhook URL は同じものを使用しましたが、通知内容には識別のために *### ロングクリックです ###*という文字列を追加しています。その他の設定は既存の Slack 通知と同じで、以下の内容になっています。

  •  
  • SORACOM LTE-M ボタンがクリックされました
  •  
  • *### ロング クリックです ###*
  •  
  • -----
  • `event.payload`
  • ```
  • ${event.payload}
  • ```
  • `event.context`
  • ```
  • ${event.context}
  • ```
  • -----
  •  
  • ${getUTCYear(now())}/${getUTCMonth(now())}/${getUTCDate(now())} ${getUTCHours(now())}:${getUTCMinutes(now())}:${getUTCSeconds(now())} UTC
  •  

Flux でアクションの実行条件を設定する

アクションの実行条件を設定することで、特定の条件に当てはまる場合のみアクションを実行できます。今回は、ボタンのクリックタイプを条件として設定します。

users.soracom.io

設定は簡単で、アクションの実行条件に条件式を記載するだけです。ボタンから送信されるデータには clickTypeという項目と値が含まれており、この値がクリックタイプに応じて異なります。今回は、3: 長押しの場合にアクションが実行されるように設定します。

users.soracom.io

これで、ボタンのクリックタイプに応じて、Slack 通知の内容を変更できるようになりました。

ボタンのクリックで異なる動作を行う場合

ここまでの設定を実際に試してみた方は、ボタンのクリックで異なる動作を検討する際にいくつかのポイントを考慮する必要があることに気づかれたかもしれません。

まず、ボタンには LED 表示しかなく、その LED 表示は電池残量やデータ送信結果の表示に使われています。

users.soracom.io

https://soracom.jp/files/products/SORACOM_LTE-M_Button_manual.pdfsoracom.jp

このため、ボタン自体ではどのタイプのクリックを実行したのかを判別できません。また、ボタンをクリックしてデータ送信のシーケンスが始まると、ボタン側は送信のシーケンスが終了するまで、操作を受け付けなくなります。

このように、ボタンをクリックした側が自分でどの動作を行ったかを把握できないため、クリックミスやカバンの中での意図しないクリックが発生する可能性があります。そのため、メッセージを処理する側や運用の際には、ボタンがクリックされたという単純なトリガーとは異なる点を考慮して実装する必要が出てきます。

シンプルな解決策として、もし 3 種類の通知が必要であれば、物理的にボタンを3つ用意するのが手軽で良いかもしれません。

ボタンの簡易位置測位機能を活用してみる

ボタンのクリックタイプに応じた Slack 通知の送信は実現しましたが、ここからは Flux の可能性を探る実験として、ボタンの 簡易位置測位機能を利用し、送信される位置情報を Flux で活用できるか試してみたいと思います。

具体的には、ボタンの簡易位置測位機能で送信される緯度経度情報を利用して、Reverse Geocoding を試してみます。Reverse Geocoding を使うことで、緯度経度情報から住所の文字列を取得できます。

OpenStreetMapAPIを試してみる

OpenStreetMapが提供している Nominatim を利用して、Reverse Geocoding を実現してみます。

github.com

具体的には、以下の APIを使用します。

nominatim.org

今回は検証目的でボタンからのデータ送信に対してこのAPIを利用しますが、ご自身で利用する場合には、必ず API利用規約を確認してください。

operations.osmfoundation.org

APIはシンプルで、指定されたエンドポイントに HTTP GET リクエストを送信すると、住所情報が返されます。

(リクエス例)
https://nominatim.openstreetmap.org/reverse?lat=<value>&lon=<value>&<params>

今回は format=geocodejsonを指定して APIを呼び出しています。

Flux で Webhook アクションを設定する

OpenStreetMapAPIを呼び出すために、Flux で Webhook アクションを設定します。

users.soracom.io

まず、HTTP メソッドの項目を GETに設定し、URL には以下のように OpenStreetMap API のエンドポイントを指定します。

https://nominatim.openstreetmap.org/reverse?format=geocodejson&lat=${event.context.resource.location.lat}&lon=${event.context.resource.location.lon}

ボタンの簡易位置測位機能は、SORACOM の設定で ON / OFF ができます。そのため、この Webhook アクションも、簡易位置測位機能が ON で、緯度経度情報が送信されている場合のみ実行されるように、実行条件を設定します。

緯度経度情報は、context の resource として送信されます。

users.soracom.io

具体的には、context には以下のようなデータが含まれています。

{"eventType": "device",
  "request": {"protocol": "udp"
  },
  "resource": {"imei": "<imei>",
    "resourceId": "<imsi>",
    "location": {"lat": <lat>,
      "lon": <lon>
    },
    "imsi": "<imsi>",
    "resourceType": "Subscriber",
    "simId": "<sim-id>"
  },
  "group": {"groupId": "<group-id>"
  }}

アクションの実行条件として event.context.resource.location != nullを指定し、緯度経度情報が存在しない場合には、アクションが実行されないように設定します。

最後に、アクションの出力を別のチャンネルに送信する設定を行い、OpenStreetMapAPIの実行結果を次のアクションで利用できるようにします。

OpenStreetMapAPIの実行結果を Slack に通知するアクションを設定する

これまでと同様に、Slack に通知するアクションを設定します。このアクションも緯度経度情報が存在しない場合には実行できないため、アクションの実行条件として、前段の OpenStreetMapAPI実行アクションと同じく event.context.resource.location != nullを指定しておきます。

OpenStreetMapAPIの実行結果から必要な情報を取り出すための詳細については、以下のリンクを参照してください。

nominatim.org

今回は以下のような内容の通知を行いました。

  •  
  • SORACOM LTE-M ボタンがクリックされました
  •  
  • *### 簡易位置情報が付加されています ###*
  •  
  • -----
  • ・クリックタイプ:
  •     ・ ${event.payload.clickType}
  •  
  • ・クリックタイプ名:
  •     ・ ${event.payload.clickTypeName}
  •  
  • ・バッテリーレベル:
  •     ・ ${event.payload.batteryLevel}
  •  
  • ・簡易位置情報:
  •     ・緯度: ${event.context.resource.location.lat}
  •     ・経度: ${event.context.resource.location.lon}
  •  
  • Google Maps URL:
  •     ・ https://www.google.com/maps?q=${event.context.resource.location.lat},${event.context.resource.location.lon}
  •  
  •  
  • OpenStreetMapAPIによる位置推定:
  •     ・ ${payload.features[0].properties.geocoding.label}
  •     ・ https://www.google.com/maps?q=${payload.features[0].geometry.coordinates[1]},${payload.features[0].geometry.coordinates[0]}
  • -----
  •  
  • ${getUTCYear(now()+32400000)}/${getUTCMonth(now()+32400000)}/${getUTCDate(now()+32400000)} ${getUTCHours(now()+32400000)}:${getUTCMinutes(now()+32400000)}:${getUTCSeconds(now()+32400000)} JST
  •  

実際にボタンを押してみると、以下のような通知が Slack に届いているのが確認できます。

通知には Google Mapsのリンクも含まれているので、クリックして確認してみてください。ボタンをクリックした位置(緯度経度情報)が、実際の現在位置から少しずれている可能性があります。これは、簡易位置測位機能が GPSからの情報ではなく、プラットフォーム側で付与されたデバイスの簡易的な位置情報であるためです。

users.soracom.io

また、OpenStreetMapAPIで取得した情報も、実際の緯度経度の場所と異なる可能性があります。これは、登録されている情報の精度や粒度に依存するためで、精度が必要な場合には、必要に応じて確認を行ってください。

ここまでで、Flux を利用して緯度経度情報から位置情報の文字列を取得し、Slack に通知できました。精度の問題はあるものの、緯度経度の数値情報を人が理解できる情報に変換する手段を試せたと言えるのではないでしょうか。

生成 AI による Reverse Geocoding を試してみる

OpenStreetMapAPIで実現した Reverse Geocoding を、生成 AI を使って試してみたらどうなるかを、検証してみようと思います。

Flux で AI アクションを設定する

生成 AI による Reverse Geocoding を試すために、AI アクションを設定します。

users.soracom.io

OpenStreetMapAPIの場合と同様に、アクションの実行条件として event.context.resource.location != nullを指定し、緯度経度情報が存在しない場合には実行されないように設定します。

AI モデルは Azure OpenAI (GPT-4o)を利用しました。比較検証を行っていないため、他の AI モデルを利用すると結果と精度が異なる可能性があります。

生成 AI に渡すプロンプトは以下の内容です。

  •  
  • あなたは専門家です。専門分野は以下です。
  •  
  • 1. 日本地理
  • 2. 地図と住所
  • 3. 経路や乗り換え案内
  •  
  • あなたの使命は
  • 入力された緯度経度情報を日本の住所情報に変換することです。
  •  
  • あなたはこの世で唯一の専門家なので
  • 緯度経度情報を変換する場合は、`注意深く観察して、意識的に` より詳細な住所に変換してください。
  •  
  • 返答は以下に指示するJSON形式で行ってください
  •  
  • {
  •   "zipCode": "あなたが緯度経度情報から変換した住所の郵便番号を入力してください"
  •   "address": "あなたが緯度経度情報から変換した住所を入力してください"
  •   "landmarks":"他の人がその場所にたどり着けるような特徴的で目印になるものが存在した場合入力してください"
  •   "navigation": "出発地点は、東京駅として入力された緯度経度情報の場所まで到達するための経路を入力してください。公共交通機関を優先してください"
  •   "time": "出発地点は、東京駅として入力された緯度経度情報の場所まで到達するために、あなたが案内した経路の所要時間を入力してください"
  •   "fare": "出発地点は、東京駅として入力された緯度経度情報の場所まで到達するために、あなたが案内した経路の所要運賃を入力してください"
  • }
  •  
  • 以下の緯度経度情報について、上記の内容を返答してください
  •  
  • ${context.resource.location}
  •  

プロンプトでは、緯度経度情報を処理するための前提条件や出力結果の条件を指定しました。また、APIと異なり自然言語で柔軟なインプットが行えるのが、生成 AI の強みでもあるので、東京駅をスタート地点にした乗り換え案内も依頼しています。

最後に、生成 AI アクションの出力を別のチャンネルに送信する設定を行い、次のアクションで利用できるようにします。

AI アクションの実行結果を Slack に通知するアクションを設定する

これまでと同様に、Slack に通知するアクションを設定します。このアクションも緯度経度情報が存在しないと実行できないため、アクションの実行条件として、前段の AI アクションと同様に event.context.resource.location != nullを指定します。

AI アクションの実行結果の形式は、生成 AI に渡すプロンプト内で指定しています。

今回は以下のような内容で Slack 通知を行いました。

  •  
  • SORACOM LTE-M ボタンがクリックされました
  •  
  • *### 簡易位置情報が付加されています ###*
  •  
  • -----
  • ・クリックタイプ:
  •     ・ ${event.payload.clickType}
  •  
  • ・クリックタイプ名:
  •     ・ ${event.payload.clickTypeName}
  •  
  • ・バッテリーレベル:
  •     ・ ${event.payload.batteryLevel}
  •  
  • ・簡易位置情報:
  •     ・緯度: ${event.context.resource.location.lat}
  •     ・経度: ${event.context.resource.location.lon}
  •  
  • Google Maps URL:
  •     ・ https://www.google.com/maps?q=${event.context.resource.location.lat},${event.context.resource.location.lon}
  •  
  •  
  • ・生成AI による位置推定:
  •     ・${payload.output.zipCode} ${payload.output.address}
  •  
  • ・生成AI によるランドマーク推定:
  •     ・${payload.output.landmarks}
  •  
  • ・生成AI による `東京駅` からの乗り換え案内:
  •     ・${payload.output.navigation} ${payload.output.time} ${payload.output.fare}
  • -----
  •  
  • ${getUTCYear(now()+32400000)}/${getUTCMonth(now()+32400000)}/${getUTCDate(now()+32400000)} ${getUTCHours(now()+32400000)}:${getUTCMinutes(now()+32400000)}:${getUTCSeconds(now()+32400000)} JST
  •  

実際にボタンを押して実行してみると、以下のような通知が Slack に届いているのが確認できます。

通知には Google Mapsのリンクも含まれているので、クリックしてみて、ボタンをクリックした際に付加された位置情報の実際の場所を確認してみてください。

生成 AI によって推定された住所情報の精度はどうでしょうか? 私も何度か試してみましたが、推定された場所が実際の位置からかなり離れていることが多くありました。また、市単位など大まかな範囲では正確な場合もありましたが、詳細な場所については APIで確認した情報よりも大きくずれていることがありました。

しかし、住所情報以外のランドマーク情報や乗換案内情報については、生成 AI が提示した場所を前提とすれば、そこまで大きくずれていないように見受けられます。この結果から、生成 AI で Reverse Geocoding を行う場合、AI とのやり取りを何度か繰り返す必要があると感じました。ワンショットで期待する情報を取得するのは難しいという印象です。プロンプトもさらに工夫が必要だと感じたので、別の機会に再チャレンジしてみたいと思います。

まとめ

  • SORACOM Flux を使うことで、LTE-M ボタンの情報を簡単に Slack 通知できた
  • ボタンのクリックタイプに応じて、通知内容を変更できた
  • Flux のメール通知は、現時点では制限があるため、その点を理解して使用する必要がある
  • 単純に通知するだけでなく、途中で APIや生成 AI を呼び出すことで、情報に付加価値を与えたり、人にわかりやすく整理することができる
  • 一方で、APIの精度や生成 AI の出力特性を理解した上で利用することが重要となる
  • ボタンの簡易位置測位機能を ON にした場合、ボタンのデータが SORACOM に届いてから位置情報が付加される
  • そのため、ボタンの位置情報は Flux では contextに含まれている
  • ボタンを実際に利用する場合には問題ないが、例えば実行のテストで、実際にボタンを押さずに緯度経度情報のインプットを行いたい場合に困る
  • イベントソースには、テスト実行や API呼び出しを行える機能がありますが、この機能で指定できるのはイベントの message (payload) のみ
  • 現時点では、テスト実行すると、context は 必ず {"eventType":"api"}となり、位置情報を付加する手段がないため、正しくテストが行えない

  • また、 {"eventType":"api"}となっている場合、event.context.resource.location != null評価式自体がエラーになってしまう
  • これは 親の要素 event.context.resourcenullとなるため、子の要素を評価する際には null 参照となってしまうためではないかと思う
  • これらのマイナーな問題点については、今後の継続的なアップデートでの改善を期待したい
  • シンプルな解決方法は、位置情報が payloadで送信されるデバイスを利用すること

    users.soracom.io

  • 位置情報だけではなく、必要な情報がすべて payloadに入っているデバイスやデータであれば、テスト実行できるため、デバイスやデータの形式を検討するのが良さそう
  • 最終的には、Flux アプリを作成する段階から自然言語で指示できるようになって欲しい
  • すでに Flux の便利ツールがあるので、使って遊んでみたり

    blog.soracom.com

  • 猫の行動を見つめてみたり

    blog.soracom.com

  • Flux はさまざまな使い方ができ、今後も進化していくと思うので、ぜひ楽しんで活用してみてください!


以上です。


Viewing all articles
Browse latest Browse all 32

Trending Articles