(この記事は、「#NervesJP Advent Calendar 2019」の7日目です)
昨日はYoosukeさんの「Nerves と GraphQLsever の組み合わせを考える「ポエム」」です!こちらもぜひぜひ!
はじめに
- お天気Webサービス(Livedoor Weather Web Service / LWWS)を使わせていただいて天気予報の情報を取得してTwitterにつぶやくことをNervesでやってみました
- これをやるときに開発途中で、いちいちmicroSDカードに焼き込んでNerves上で動かすことは面倒だとおもいました
- ちょっとだけ困ったことがありました
ちょっとだけ困ったことの具体例
-
Nervesから動かしていることをアピールするために
"I use Nerves. I like it!"
を差し込みたいとします
lib/weather/forecast.ex
defmodule Weather.Forecast do
def run({city, name}) do
description =
"http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city}"
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Map.get("description")
|> Map.get("text")
|> String.split()
|> Enum.reduce_while("#{name}\n", fn s, acc ->
if String.length(acc <> "#{s}\n") < 140 - String.length(i_use_nerves()),
do: {:cont, acc <> "#{s}\n"},
else: {:halt, acc}
end)
|> Kernel.<>(i_use_nerves())
end
def run do
cities() |> Enum.random() |> run
end
defp i_use_nerves do
"I use Nerves. I like it!"
end
- こう書くと、microSDカードに焼き込んでNervesで動かしいているときは問題ないのですが、開発の途中にhost(macOS等)で動かしているときは、
"I use Nerves. I like it!"
といれたくありません - 結局最後は、Nervesで動かすのですから、そんな些細なこと気にしなくてもいいのかもしれません
- このままの状態で、Twitterに投稿するまでをテストしたいときには、
"I use Nerves. I like it!"
が入ってしまうので、ちょっとだけうそつきになります - なにかコンパイルスイッチというかそういうもので、 target(Raspberry Pi等)で動かすときはこっち、host(macOS等)で動かすときはそっち ができないものかと調べてみました
Mix.target() => (使えません)
-
mix nerves.new hello_nerves
したときにできるconfig/config.exs
にMix.target()
なる記述がありました
config/config.exs
if Mix.target() != :host do
import_config "target.exs"
end
- これを使って、
lib/weather/forecast.ex
defp i_use_nerves do
if Mix.target() != :host do
"I use Nerves. I like it!"
else
""
end
end
- なんてやると動くのかなと最初はおもいました
- しかしこれをmicroSDカードに焼き込んでRaspberry Pi2で動かしてみても動きません
- Mix.target()なんて使えないよ的なエラーがでます
解決策
lib/weather/forecast.ex
defp i_use_nerves do
if Application.get_env(:hello_nerves, :target) != :host do
"I use Nerves. I like it!"
else
""
end
end
- 他にもいい方法があるのかもしれません
- ここで得た知識はjbernardo95/cronexをNervesアプリケーションで使おうとしたときに、
Mix.env
が使えないよ的なエラーに遭遇したことがありましてそのエラーを調査する際にどこかで聞いた話だなとピンときました
if(condition, clauses) のconditionを !=
じゃなくて ==
で書きたい
- 2019/12/22 追記
-
if Application.get_env(:hello_nerves, :target) != :host
の部分 - Nerves on Raspberry Pi 2で動かしてみました
iex> Application.get_env(:hello_nerves, :target)
:rpi2
-
MIX_TARGET
に設定したTargets TAGが返ってくるようです -
if Application.get_env(:hello_nerves, :target) == :rpi2
と書けないわけではないですが、他のTargetでも動かすことを考える(もっていないけど)と、!=
の書き方のほうがいいかなあとおもっています
まとめ
- Leap before you look
次回
次回はpojiroさんの「作って学ぶNerves、BBBでCO2計測」です!こちらも是非どうぞ~