[Elixir]Nervesのweatherでお近くの天気情報を得る


はじめに

ハイライト

iex> weather
Weather report: Xxxxx, Japan

   _`/"".-.     Patchy rain possible
    ,\_(   ).   22..25 °C      
     /(___(__)   3 km/h       
            9 km           
            2.0 mm   
  • お近くの天気情報が得られることでしょう!

準備

1. プロジェクトの作成(からのいつもの景色)

$ mix nerves.new hello_nerves
$ cd hello_nerves
$ export MIX_TARGET=rpi2
$ mix deps.get
  • MIX_TARGETに指定できるものはSupported Targets and Systemsからお選びください
  • 私は令和2年ですがいまだにRaspberry Pi 2を使っています

2. 少し書き換え

mix.exs
  def application do
    [
      mod: {HelloNerves.Application, []},
      extra_applications: [:logger, :runtime_tools, :inets] # :inetsを追加
    ]
  end
  • :inetsの指定は指定をせずに実行しようとすると怒られて、そのとき追加するといいよというようなメッセージをみて気づいた次第です

Wi-Fiを使う場合(オプション)

  • 私はWi-Fiでネットワークに接続しているので設定を書き換えます
  • $ mix nerves.new hello_nervesしたときにこんなふうになっている箇所があるとおもいます
config/target.exs
config :vintage_net,
  regulatory_domain: "US",
  config: [
    {"eth0", %{type: VintageNetEthernet, ipv4: %{method: :dhcp}}},
    {"wlan0", %{type: VintageNetWiFi}}
  ]

↓↓↓↓

config/target.exs
config :vintage_net,
  regulatory_domain: "US",
  config: [
    {"usb0", %{type: VintageNetDirect}},
    {"eth0",
     %{
       type: VintageNetEthernet,
       ipv4: %{method: :dhcp}
     }},
    {"wlan0",
     %{
       type: VintageNetWiFi,
       vintage_net_wifi: %{
         networks: [
           %{
             key_mgmt: :wpa_psk,
             ssid: "your_ssid", # ※ここにSSIDを追記
             psk: "your_psk" # ※ここにパスフレーズを追記
           }
         ]
       },
       ipv4: %{method: :dhcp}
     }}
  ]

3. ビルド〜microSDへの焼き込み

$ mix firmware
  • 👆これでBuild a firmware bundleが行われます
  • 成功したら、microSDカードをPCに挿してmicroSDカードにfirmwareを焼き込みます
$ mix burn
  • 👆これでWrite a firmware image to an SDCardが行われます

4. 実行

  • こんがり焼き上がったmicroSDカードをRaspberry Pi 2に挿して電源を投入します
  • 少し待つと(10〜15秒くらい?)、pingが通るようになるとおもいます
$ ping nerves.local
  • pingが通ったらsshしましょう
$ ssh nerves.local
Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help)
Toolshed imported. Run h(Toolshed) for more info.
RingLogger is collecting log messages from Elixir and Linux. To see the
messages, either attach the current IEx session to the logger:

  RingLogger.attach

or print the next messages in the log:

  RingLogger.next

iex(1)> 
  • IExが使えるようになっているので使っていきます
iex> use Toolshed
Toolshed imported. Run h(Toolshed) for more info.
:ok

iex> weather
Weather report: Xxxxx, Japan

   _`/"".-.     Patchy rain possible
    ,\_(   ).   22..25 °C      
     /(___(__)   3 km/h       
            9 km           
            2.0 mm   
  • お近くの天気情報が表示されることでしょう
  • Toolshedには他にも使えるのものがあります h(Toolshed)でご確認ください
  • weather関数の実体はココです
    • http://wttr.in/?An0にHTTP Getしています
    • どういう仕組みなのかはわかっていませんがサーバー側で判定してお近くの天気情報を返してくれているようです
lib/toolshed/http.ex
  @doc """
  Display the local weather

  See http://wttr.in/:help for more information.
  """
  @spec weather() :: :"do not show this result in output"
  def weather() do
    check_inets()

    {:ok, {_status, _headers, body}} = :httpc.request('http://wttr.in/?An0')

    body |> :binary.list_to_bin() |> IO.puts()
    IEx.dont_display_result()
  end

Wrapping Up

  • extra_applications: [:logger, :runtime_tools, :inets]:inetsを追加すると、weatherでお近くの天気予報を取得することができます
  • Enjoy Elixir!