Nervesを使って毎朝天気予報をRaspberry Pi 2にしゃべらせる(できた!)
(この記事は、「#NervesJP Advent Calendar 2019」の10日目です)
昨日は私の「Nervesを使ってRaspberry Pi 2でLEDをチカチカさせる 〜クリスマスの飾り付けをしよう〜」です!こちらもぜひぜひ!
2020/11/04 追記
- 記事中で紹介している、livedoor様のお天気Webサービス はサービスが終了しております
- 代わりにOpenWeatherを利用する記事を書いております
はじめに
まとめ
- Raspberry Pi 2にスピーカーをとりつける
-
nerves-project/nerves_system_rpi2 に書いてある! 通りにやる
iex(1)> :os.cmd('espeak -ven+f5 -k5 -w /tmp/out.wav IwasWornToLoveElixir')
iex(2)> :os.cmd('aplay -q /tmp/out.wav')
- これでできたも同然でしょう!
- 天気予報を取得して、音声合成してファイルに保存して、
aplay
コマンドを実行するのみです
まとめ
- Raspberry Pi 2にスピーカーをとりつける
-
nerves-project/nerves_system_rpi2 に書いてある! 通りにやる
iex(1)> :os.cmd('espeak -ven+f5 -k5 -w /tmp/out.wav IwasWornToLoveElixir')
iex(2)> :os.cmd('aplay -q /tmp/out.wav')
- これでできたも同然でしょう!
- 天気予報を取得して、音声合成してファイルに保存して、
aplay
コマンドを実行するのみです
iex(1)> :os.cmd('espeak -ven+f5 -k5 -w /tmp/out.wav IwasWornToLoveElixir')
iex(2)> :os.cmd('aplay -q /tmp/out.wav')
aplay
コマンドを実行するのみです
感謝
-
livedoor様のお天気Webサービス ありがとうございます!
-
docomo Developer support様の 音声合成【Powered by NTTテクノクロス】 ありがとうございます!
-
Nerves ありがとうございます!
-
Elixir ありがとうございます!
-
Erlang ありがとうございます!
- あなたはまだ直接書いたことがありません
- Raspberry Pi 2 ありがとうございます!
-
アドミラル・グレース・マーレー・ホッパー ありがとうございます!
-
アラン・チューリング ありがとうございます!
-
ジョン・フォン・ノイマン ありがとうございます!
- 私の知識不足によりここにあげられていない数多くの発明があることでしょう
- 感謝します!
- 私にプログラミングの楽しさを教えてくれたすべてのコト、モノ、人に感謝します!
- 一見何も関係なかったようにみえる出来事もきっと私がプログラムを少しだけ書けるようになったことに関係しているのでしょう
- ひとつとして欠けると私には何もできなかったことでしょう
- あなたがいて、私がいる。私がいてあなたがいる。すべてに感謝ーーすべてはつながっているーー縁起
作品
音声サンプル
- audio_sample.exs
- これをダウンロードして
iex
で
iex(1)> c "audio_sample.exs"
iex(2)> AudioSample.create
- とやってみてください。.wavファイルが2つできているので再生プレイヤーで再生してみてください。
- macOS 10.14.6では再生(iTunes)できました
-
Elixirは、
Elixir 1.9.4 (compiled with Erlang/OTP 22)
を使いました
関連記事
対応内容
- https://github.com/TORIFUKUKaiou/hello_nerves/commit/e2c3e171f2eeb55e8d05c1824db410fd94408813
- 以下、ポイント部分のみ記載します
天気予報取得
-
livedoor様のお天気Webサービス を利用させていただいております
- HTTP Getして返されたJSONから、
"description" |> "text"
とたどって値を取得しています
Weather.Forecast.text()
lib/weather/forecast.ex
defmodule Weather.Forecast do
def text(city) do
"http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city}"
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Map.get("description")
|> Map.get("text")
end
音声合成
Torifuku.TextToSpeech.text_to_speech()
-
docomo Developer support様の音声合成【Powered by NTTテクノクロス】 を利用させていただいております
- 文字列を音声データに変換します
- やっていることはAPIの仕様に従ってHTTP Postしているだけです
lib/torifuku/text_to_speech.ex
defmodule Torifuku.TextToSpeech do
# Please refer to https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=text_to_speech&p_name=api_7#tag01 .
def text_to_speech(
text,
speaker_id \\ 1,
style_id \\ 1,
speech_rate \\ 1.0,
power_rate \\ 1.0,
voice_type \\ 1.0,
audio_file_format \\ 2
) do
url =
"https://api.apigw.smt.docomo.ne.jp/crayon/v1/textToSpeech?APIKEY=#{
Application.get_env(:hello_nerves, :text_to_speech_api_key)
}"
headers = [{"Content-Type", "application/json"}]
json_data =
%{
Command: "AP_Synth",
SpeakerID: speaker_id,
StyleID: style_id,
TextData: text,
SpeechRate: speech_rate,
PowerRate: power_rate,
VoiceType: voice_type,
AudioFileFormat: audio_file_format
}
|> Poison.encode!()
HTTPoison.post!(url, json_data, headers) |> Map.get(:body)
end
end
組み合わせる
- 天気情報文字列の取得と音声データに変換 はできたのであとは部品を組み合わせます
- もちろん
|>
で組み合わせましょう!
-
Nervesで動かす場合、
/tmp
配下にファイルを書き込めるようです
- ファイルを書き込む位置と音声ファイルの再生につかうコマンドを if macroで場合わけしていますが、Nervesじゃないときの動作はmacOSでしか確認していないです
HelloNerves.sound_forecast
lib/hello_nerves.ex
defmodule HelloNerves do
def sound_forecast(city) do
content =
Weather.Forecast.text(city)
|> String.split()
|> Enum.take(2)
|> Enum.join()
|> Torifuku.TextToSpeech.text_to_speech()
if Application.get_env(:hello_nerves, :target) != :host do
File.write("/tmp/output.wav", content)
:os.cmd('aplay -q /tmp/output.wav')
else
# macOS
File.write("output.wav", content)
:os.cmd('afplay output.wav')
end
end
- 毎朝実行させる方法は下記の記事をご参照ください
焼き込む
$ export MIX_TARGET=rpi2
$ export NERVES_NETWORK_SSID=ssid
$ export NERVES_NETWORK_PSK=secret
$ export TWITTER_CONSUMER_KEY=xxx
$ export TWITTER_CONSUMER_SECRET=yyy
$ export TWITTER_ACCESS_TOKEN=zzz
$ export TWITTER_ACCESS_TOKEN_SECRET=aaa
$ export TEXT_TO_SPEECH_API_KEY=ttt
$ mix deps.get
$ mix firmware
$ mix firmware.burn
WiFi越しにfirmware updateできます!
-
pojiroさんの作って学ぶNerves、BBBでCO2計測の記事で知りました!
- ありがとうございます!
- つい先日までこれを知らなくて、毎回、Raspberry Pi 2からmicroSDカードを抜いて、macに挿して焼いて、macから抜いて、Raspberry Pi 2に挿して電源ONを毎回繰り返していました
$ mix firmware.gen.script # upload.shができています
$ mix firmware
$ ./upload.sh 192.168.1.10
-
192.168.1.10
は私の家のRaspberry Pi 2の話です
- これは便利なのでぜひ使うといいとおもいます!
- Pushing firmware updates to devices
次回
- 明日はzacky1972先生のNerves の可能性は IoT だけじゃない(前編)〜ElixirとPelemayで世界の消費電力を抑えるです
- こちらもぜひぜひ!
- あなたはまだ直接書いたことがありません
- 一見何も関係なかったようにみえる出来事もきっと私がプログラムを少しだけ書けるようになったことに関係しているのでしょう
音声サンプル
- audio_sample.exs
- これをダウンロードして
iex
で
iex(1)> c "audio_sample.exs"
iex(2)> AudioSample.create
- とやってみてください。.wavファイルが2つできているので再生プレイヤーで再生してみてください。
- macOS 10.14.6では再生(iTunes)できました
-
Elixirは、
Elixir 1.9.4 (compiled with Erlang/OTP 22)
を使いました
関連記事
対応内容
- https://github.com/TORIFUKUKaiou/hello_nerves/commit/e2c3e171f2eeb55e8d05c1824db410fd94408813
- 以下、ポイント部分のみ記載します
天気予報取得
-
livedoor様のお天気Webサービス を利用させていただいております
- HTTP Getして返されたJSONから、
"description" |> "text"
とたどって値を取得しています
Weather.Forecast.text()
lib/weather/forecast.ex
defmodule Weather.Forecast do
def text(city) do
"http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city}"
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Map.get("description")
|> Map.get("text")
end
音声合成
Torifuku.TextToSpeech.text_to_speech()
-
docomo Developer support様の音声合成【Powered by NTTテクノクロス】 を利用させていただいております
- 文字列を音声データに変換します
- やっていることはAPIの仕様に従ってHTTP Postしているだけです
lib/torifuku/text_to_speech.ex
defmodule Torifuku.TextToSpeech do
# Please refer to https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=text_to_speech&p_name=api_7#tag01 .
def text_to_speech(
text,
speaker_id \\ 1,
style_id \\ 1,
speech_rate \\ 1.0,
power_rate \\ 1.0,
voice_type \\ 1.0,
audio_file_format \\ 2
) do
url =
"https://api.apigw.smt.docomo.ne.jp/crayon/v1/textToSpeech?APIKEY=#{
Application.get_env(:hello_nerves, :text_to_speech_api_key)
}"
headers = [{"Content-Type", "application/json"}]
json_data =
%{
Command: "AP_Synth",
SpeakerID: speaker_id,
StyleID: style_id,
TextData: text,
SpeechRate: speech_rate,
PowerRate: power_rate,
VoiceType: voice_type,
AudioFileFormat: audio_file_format
}
|> Poison.encode!()
HTTPoison.post!(url, json_data, headers) |> Map.get(:body)
end
end
組み合わせる
- 天気情報文字列の取得と音声データに変換 はできたのであとは部品を組み合わせます
- もちろん
|>
で組み合わせましょう!
-
Nervesで動かす場合、
/tmp
配下にファイルを書き込めるようです
- ファイルを書き込む位置と音声ファイルの再生につかうコマンドを if macroで場合わけしていますが、Nervesじゃないときの動作はmacOSでしか確認していないです
HelloNerves.sound_forecast
lib/hello_nerves.ex
defmodule HelloNerves do
def sound_forecast(city) do
content =
Weather.Forecast.text(city)
|> String.split()
|> Enum.take(2)
|> Enum.join()
|> Torifuku.TextToSpeech.text_to_speech()
if Application.get_env(:hello_nerves, :target) != :host do
File.write("/tmp/output.wav", content)
:os.cmd('aplay -q /tmp/output.wav')
else
# macOS
File.write("output.wav", content)
:os.cmd('afplay output.wav')
end
end
- 毎朝実行させる方法は下記の記事をご参照ください
焼き込む
$ export MIX_TARGET=rpi2
$ export NERVES_NETWORK_SSID=ssid
$ export NERVES_NETWORK_PSK=secret
$ export TWITTER_CONSUMER_KEY=xxx
$ export TWITTER_CONSUMER_SECRET=yyy
$ export TWITTER_ACCESS_TOKEN=zzz
$ export TWITTER_ACCESS_TOKEN_SECRET=aaa
$ export TEXT_TO_SPEECH_API_KEY=ttt
$ mix deps.get
$ mix firmware
$ mix firmware.burn
WiFi越しにfirmware updateできます!
-
pojiroさんの作って学ぶNerves、BBBでCO2計測の記事で知りました!
- ありがとうございます!
- つい先日までこれを知らなくて、毎回、Raspberry Pi 2からmicroSDカードを抜いて、macに挿して焼いて、macから抜いて、Raspberry Pi 2に挿して電源ONを毎回繰り返していました
$ mix firmware.gen.script # upload.shができています
$ mix firmware
$ ./upload.sh 192.168.1.10
-
192.168.1.10
は私の家のRaspberry Pi 2の話です
- これは便利なのでぜひ使うといいとおもいます!
- Pushing firmware updates to devices
次回
- 明日はzacky1972先生のNerves の可能性は IoT だけじゃない(前編)〜ElixirとPelemayで世界の消費電力を抑えるです
- こちらもぜひぜひ!
iex
でiex(1)> c "audio_sample.exs"
iex(2)> AudioSample.create
Elixir 1.9.4 (compiled with Erlang/OTP 22)
を使いました
対応内容
- https://github.com/TORIFUKUKaiou/hello_nerves/commit/e2c3e171f2eeb55e8d05c1824db410fd94408813
- 以下、ポイント部分のみ記載します
天気予報取得
-
livedoor様のお天気Webサービス を利用させていただいております
- HTTP Getして返されたJSONから、
"description" |> "text"
とたどって値を取得しています
Weather.Forecast.text()
lib/weather/forecast.ex
defmodule Weather.Forecast do
def text(city) do
"http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city}"
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Map.get("description")
|> Map.get("text")
end
音声合成
Torifuku.TextToSpeech.text_to_speech()
-
docomo Developer support様の音声合成【Powered by NTTテクノクロス】 を利用させていただいております
- 文字列を音声データに変換します
- やっていることはAPIの仕様に従ってHTTP Postしているだけです
lib/torifuku/text_to_speech.ex
defmodule Torifuku.TextToSpeech do
# Please refer to https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=text_to_speech&p_name=api_7#tag01 .
def text_to_speech(
text,
speaker_id \\ 1,
style_id \\ 1,
speech_rate \\ 1.0,
power_rate \\ 1.0,
voice_type \\ 1.0,
audio_file_format \\ 2
) do
url =
"https://api.apigw.smt.docomo.ne.jp/crayon/v1/textToSpeech?APIKEY=#{
Application.get_env(:hello_nerves, :text_to_speech_api_key)
}"
headers = [{"Content-Type", "application/json"}]
json_data =
%{
Command: "AP_Synth",
SpeakerID: speaker_id,
StyleID: style_id,
TextData: text,
SpeechRate: speech_rate,
PowerRate: power_rate,
VoiceType: voice_type,
AudioFileFormat: audio_file_format
}
|> Poison.encode!()
HTTPoison.post!(url, json_data, headers) |> Map.get(:body)
end
end
組み合わせる
- 天気情報文字列の取得と音声データに変換 はできたのであとは部品を組み合わせます
- もちろん
|>
で組み合わせましょう!
-
Nervesで動かす場合、
/tmp
配下にファイルを書き込めるようです
- ファイルを書き込む位置と音声ファイルの再生につかうコマンドを if macroで場合わけしていますが、Nervesじゃないときの動作はmacOSでしか確認していないです
HelloNerves.sound_forecast
lib/hello_nerves.ex
defmodule HelloNerves do
def sound_forecast(city) do
content =
Weather.Forecast.text(city)
|> String.split()
|> Enum.take(2)
|> Enum.join()
|> Torifuku.TextToSpeech.text_to_speech()
if Application.get_env(:hello_nerves, :target) != :host do
File.write("/tmp/output.wav", content)
:os.cmd('aplay -q /tmp/output.wav')
else
# macOS
File.write("output.wav", content)
:os.cmd('afplay output.wav')
end
end
- 毎朝実行させる方法は下記の記事をご参照ください
焼き込む
$ export MIX_TARGET=rpi2
$ export NERVES_NETWORK_SSID=ssid
$ export NERVES_NETWORK_PSK=secret
$ export TWITTER_CONSUMER_KEY=xxx
$ export TWITTER_CONSUMER_SECRET=yyy
$ export TWITTER_ACCESS_TOKEN=zzz
$ export TWITTER_ACCESS_TOKEN_SECRET=aaa
$ export TEXT_TO_SPEECH_API_KEY=ttt
$ mix deps.get
$ mix firmware
$ mix firmware.burn
WiFi越しにfirmware updateできます!
-
pojiroさんの作って学ぶNerves、BBBでCO2計測の記事で知りました!
- ありがとうございます!
- つい先日までこれを知らなくて、毎回、Raspberry Pi 2からmicroSDカードを抜いて、macに挿して焼いて、macから抜いて、Raspberry Pi 2に挿して電源ONを毎回繰り返していました
$ mix firmware.gen.script # upload.shができています
$ mix firmware
$ ./upload.sh 192.168.1.10
-
192.168.1.10
は私の家のRaspberry Pi 2の話です
- これは便利なのでぜひ使うといいとおもいます!
- Pushing firmware updates to devices
次回
- 明日はzacky1972先生のNerves の可能性は IoT だけじゃない(前編)〜ElixirとPelemayで世界の消費電力を抑えるです
- こちらもぜひぜひ!
"description" |> "text"
とたどって値を取得していますlib/weather/forecast.ex
defmodule Weather.Forecast do
def text(city) do
"http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city}"
|> HTTPoison.get!()
|> Map.get(:body)
|> Poison.decode!()
|> Map.get("description")
|> Map.get("text")
end
lib/torifuku/text_to_speech.ex
defmodule Torifuku.TextToSpeech do
# Please refer to https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=text_to_speech&p_name=api_7#tag01 .
def text_to_speech(
text,
speaker_id \\ 1,
style_id \\ 1,
speech_rate \\ 1.0,
power_rate \\ 1.0,
voice_type \\ 1.0,
audio_file_format \\ 2
) do
url =
"https://api.apigw.smt.docomo.ne.jp/crayon/v1/textToSpeech?APIKEY=#{
Application.get_env(:hello_nerves, :text_to_speech_api_key)
}"
headers = [{"Content-Type", "application/json"}]
json_data =
%{
Command: "AP_Synth",
SpeakerID: speaker_id,
StyleID: style_id,
TextData: text,
SpeechRate: speech_rate,
PowerRate: power_rate,
VoiceType: voice_type,
AudioFileFormat: audio_file_format
}
|> Poison.encode!()
HTTPoison.post!(url, json_data, headers) |> Map.get(:body)
end
end
|>
で組み合わせましょう!/tmp
配下にファイルを書き込めるようですlib/hello_nerves.ex
defmodule HelloNerves do
def sound_forecast(city) do
content =
Weather.Forecast.text(city)
|> String.split()
|> Enum.take(2)
|> Enum.join()
|> Torifuku.TextToSpeech.text_to_speech()
if Application.get_env(:hello_nerves, :target) != :host do
File.write("/tmp/output.wav", content)
:os.cmd('aplay -q /tmp/output.wav')
else
# macOS
File.write("output.wav", content)
:os.cmd('afplay output.wav')
end
end
$ export MIX_TARGET=rpi2
$ export NERVES_NETWORK_SSID=ssid
$ export NERVES_NETWORK_PSK=secret
$ export TWITTER_CONSUMER_KEY=xxx
$ export TWITTER_CONSUMER_SECRET=yyy
$ export TWITTER_ACCESS_TOKEN=zzz
$ export TWITTER_ACCESS_TOKEN_SECRET=aaa
$ export TEXT_TO_SPEECH_API_KEY=ttt
$ mix deps.get
$ mix firmware
$ mix firmware.burn
WiFi越しにfirmware updateできます!
-
pojiroさんの作って学ぶNerves、BBBでCO2計測の記事で知りました!
- ありがとうございます!
- つい先日までこれを知らなくて、毎回、Raspberry Pi 2からmicroSDカードを抜いて、macに挿して焼いて、macから抜いて、Raspberry Pi 2に挿して電源ONを毎回繰り返していました
$ mix firmware.gen.script # upload.shができています
$ mix firmware
$ ./upload.sh 192.168.1.10
-
192.168.1.10
は私の家のRaspberry Pi 2の話です - これは便利なのでぜひ使うといいとおもいます!
- Pushing firmware updates to devices
次回
- 明日はzacky1972先生のNerves の可能性は IoT だけじゃない(前編)〜ElixirとPelemayで世界の消費電力を抑えるです
- こちらもぜひぜひ!
今年あらかじめ事前登録していた分はすべて書ききりました!
Author And Source
この問題について(Nervesを使って毎朝天気予報をRaspberry Pi 2にしゃべらせる(できた!)), 我々は、より多くの情報をここで見つけました https://qiita.com/torifukukaiou/items/795ee5a112845dbf7730著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .