LoginSignup
10
5

More than 1 year has passed since last update.

ElixirとSORACOM Beamを使用して、Raspberry Pi 4 と Azure IoT Hub との間でデータを送受信します せっかくなのでウェブチカします

Last updated at Posted at 2021-10-05

はじめに

スクリーンショット 2021-10-05 22.04.56.png

Azure IoT Hub と接続する

ステップ 1: Azure IoT Hub を準備する

IoT Hub を作成する

  • Azureのコンソール画面の感じが少し異なっているような気がしますがなんとなく、記事を参考に作成できました

IoT Device を作成する

  • ここも同じく記事を参考に作成できました

認証情報を確認する

  • 「1. 共有アクセスポリシーを利用する」を選択することにしました
  • Azure consoleの言語設定を日本語にしている場合は、以下の読み替えをします
記事 Azureコンソール(日本語)
Settings 設定
Shared access policies 共有アクセス ポリシー

ステップ 2: SORACOM Beam を設定する

グループを作成する

  • 記載の通り

グループで Beam を設定する

  • 基本的に記載の通り
  • 認証情報は、以下を入力しました
設定名
Access Policy Name device
Shared access key プライマリーキー(or セカンダリキー)

スクリーンショット 2021-10-05 20.12.35.png

ステップ 3: Beam を使用して Azure IoT Hub にデータを送信する

デバイスの準備

  • 記事の通り、Raspberry Pi 4にmosquitto-clientsをインストールします

送信されたデータ確認の準備

  • ここは私のmacOSでは記事の通りいきませんでした
    • 2021/10/19追記: $ az iot hub monitor-events -n ${iothub-name} -g ${resource-group}を使うように更新されています :rocket::rocket::rocket: 2
  • 記事の通り、IoT Hub Explorerなるものをインストールして実行したところ以下のエラーが発生しました
$ iothub-explorer monitor-events --login $connection_string
--------
DEPRECATION NOTICE: iothub-explorer will be retired on November 31st, 2018
It has been replaced by the Azure CLI IoT Extension (https://aka.ms/iotcli).
--------
The equivalent command in the Azure CLI is: az iot hub monitor-events
--------
Monitoring events from all devices...
/usr/local/Cellar/nvm/0.38.0/versions/node/v14.17.3/lib/node_modules/iothub-explorer/node_modules/azure-event-hubs/node_modules/azure-iot-common/lib/shared_access_signature.js:45
    throw new ReferenceError('Argument \'' + name + '\' is ' + value);
    ^
  • The equivalent command in the Azure CLI is: az iot hub monitor-eventsをたよりに、azをインストールしました
  • IoT Hub の 共有アクセスポリシー (Shared access policies) の、iothubowner 権限が必要となりますので、プライマリ接続文字列 or セカンダリー接続文字列のどちらかを使います
$ connection_string='HostName=xxxx.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXX='

$ az iot hub monitor-events --login $connection_string

AK-020の接続

pi@raspberrypi: ~$ curl -O https://soracom-files.s3.amazonaws.com/setup_air.sh
pi@raspberrypi: ~$ sudo bash setup_air.sh
pi@raspberrypi: ~$ deviceId=myDevice
pi@raspberrypi: ~$ mosquitto_pub -d -h beam.soracom.io -i $deviceId -t "devices/$deviceId/messages/events/" -m "Hello from SORACOM Beam!" -V mqttv311

output.gif

  • Raspberry Pi 4からAzure IoT Hubにデータを送ることができました :tada::tada::tada:

小話

  • Docker コンテナーで Azure CLI を実行する方法」こちらを進めましたがうまくいきませんでした
  • 「Microsoft の目標は、Azure CLI のバグをなくし、使いやすいものにすることです。 バグが見つかった場合は、GitHub で問題を報告していただきますよう、よろしくお願いいたします。」と書いてありましたので報告をしておきました
  • https://github.com/Azure/azure-cli/issues/19767
  • az feedback --verboseを実行すると、問題報告の雛形を作ってくれます
  • これを大いに活用させてもらいました!

ステップ 4: Azure IoT Hub からのデータを受信する

  • 今度はAzure IoT HubからRaspberry Pi 4にデータを送ってみます
  • 記事の通りにやるとRaspberry Pi 4で受信を確認できました :tada::tada::tada:

スクリーンショット 2021-10-05 20.47.06.png

あとはここからはいつものように同じことをElixirでやってみます :rocket::rocket::rocket:

ElixirでAzure IoT Hub と接続し、Azure IoT Hubから指定された回数分LEDを光らせる

  • ウェブチカです
$ mix new hello_mqtt
mix.exs
  defp deps do
     [
       # {:dep_from_hexpm, "~> 0.3.0"},
       # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
+      {:tortoise, "~> 0.9"},
+      {:circuits_gpio, "~> 0.4"},
+      {:jason, "~> 1.2"}
     ]
   end
 end
$ mix deps.get

MyHandler

  • hello_mqtt/deps/tortoise/lib/tortoise/handler/logger.ex を参考にしています
    • というか写しています
    • 少し長いですが安心してください
    • 95%コピペです
  • 変更箇所は、handle_message/3関数を変更したのと、do_handle/1関数を追加しています
  • do_handle/1はやっつけ関数でして、{"cnt": 5}というようなデータを受け取ったときに、指定されたcnt回LEDを光らせています
hello_mqtt/lib/hello_mqtt/my_handler.ex
defmodule HelloMqtt.MyHandler do
  @moduledoc false

  require Logger

  use Tortoise.Handler

  defstruct []
  alias __MODULE__, as: State

  def init(_opts) do
    Logger.info("Initializing handler")
    {:ok, %State{}}
  end

  def connection(:up, state) do
    Logger.info("Connection has been established")
    {:ok, state}
  end

  def connection(:down, state) do
    Logger.warn("Connection has been dropped")
    {:ok, state}
  end

  def connection(:terminating, state) do
    Logger.warn("Connection is terminating")
    {:ok, state}
  end

  def subscription(:up, topic, state) do
    Logger.info("Subscribed to #{topic}")
    {:ok, state}
  end

  def subscription({:warn, [requested: req, accepted: qos]}, topic, state) do
    Logger.warn("Subscribed to #{topic}; requested #{req} but got accepted with QoS #{qos}")
    {:ok, state}
  end

  def subscription({:error, reason}, topic, state) do
    Logger.error("Error subscribing to #{topic}; #{inspect(reason)}")
    {:ok, state}
  end

  def subscription(:down, topic, state) do
    Logger.info("Unsubscribed from #{topic}")
    {:ok, state}
  end

  def handle_message(topic, publish, state) do
    Logger.info("#{Enum.join(topic, "/")} #{inspect(publish)}")
    do_handle(publish)
    {:ok, state}
  end

  def terminate(reason, _state) do
    Logger.warn("Client has been terminated with reason: #{inspect(reason)}")
    :ok
  end

  defp do_handle(publish) do
    cnt = Jason.decode!(publish) |> Map.get("cnt")
    {:ok, gpio} = Circuits.GPIO.open(25, :output)

    1..cnt
    |> Enum.each(fn _ ->
      Circuits.GPIO.write(gpio, 1)
      Process.sleep(1000)
      Circuits.GPIO.write(gpio, 0)
      Process.sleep(1000)
    end)

    Circuits.GPIO.close(gpio)
  end
end

Run

$ iex -S mix

iex> Tortoise.Supervisor.start_child(
    client_id: "myDevice",
    handler: {HelloMqtt.MyHandler, []},
    server: {Tortoise.Transport.Tcp, host: 'beam.soracom.io', port: 1883},
    subscriptions: [{"devices/myDevice/messages/devicebound/#", 0}])

まずはAzure IoT Hubにデータを送ってみます

iex> Tortoise.publish("myDevice", "devices/myDevice/messages/events/", "Hello from the World of Tomorrow !", qos: 0)
  • az iot hub monitor-eventsでデータが送られていることを確認できました

:rocket::rocket::rocket:

Azure IoT Hubからのメッセージを受け取って指定された回数分LEDを光らせてみます

スクリーンショット 2021-10-05 21.24.07.png

output.gif

ウェブチカできました:tada::tada::tada:

Wrapping Up :lgtm::lgtm::lgtm::lgtm::lgtm:

  • SORACOMさんの「Azure IoT Hub と接続する」を参考に、ElixirAzure IoT Hubとの間でデータを送受信することができました
    • ついでに私なりのはじめてのウェブチカができました
  • MQTTの通信には、Tortoiseを使いました
  • 公式ドキュメントの記載内容がわかりやすくてありがたいです!
    • $\huge{ありがとうございます!}$
  • デバイスとの間でメッセージの送受信ができるようになりましたのでいろいろ楽しみが増えそうです!
  • Enjoy Elixir:bangbang::bangbang::bangbang:

  1. @nishiuchikazuma さんの「NervesにPhoenixを入れてHTTPのGETでLEDをウェブチカ〜準備編1/3〜」によるとウェブチカとは、「とあるURLにアクセスするとNervesにつけているLEDをチカらせることを言ってます」 とのことです。まあこの記事でやっていることもなんとなく雰囲気は似ているということで、ウェブチカの末席に加えさせてください :bow::bow_tone1::bow_tone2::bow_tone3::bow_tone4::bow_tone5:  

  2. @matsujirushi さんがSORACOMさんに連絡してくださいました :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5: 。ありがとうございます。 

10
5
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5