UEQareer Advent Calendar 201719日目のエントリーです。
こんにちは! レッドインパルスのインターン生、もーりーです。
前回の記事では音声認識ソフトウェアのjuliusとラズパイを使ってLチカをしましたが、
今回もjuliusを使って、micro:bitに天気や気温を表示させます!
Contents
今回用意したもの

- RaspberryPi3(普通のパソコンで構いません)
- USBマイク(前回と同じもの)
- micro:bit(実験で使わせてもらってる借り物です笑)
micro:bitは2000円ちょっとで買えちゃうので驚きですね。
小学生向けの直感的プログラミングで組めちゃいます(もちろんコード直書き[python,js]でもOK)
必要な環境
- 下記2つのAPIキー
- Node.jsの実行環境
- Pythonの実行環境
今回は,OpenWeatherMapAPIとDarkSkyAPIの2つのAPIを使って天気情報と気温情報を取得します。
コンピュータからmicro:bitへのBLEでの送信はNode.jsを使って行うので、NodeでAPIを叩いて情報をそのままmicro:bitに送るような仕組みにしました。
音声制御部分は前回同様pythonで行い、pythonファイルの中でNodeを実行するという仕組みです。
Nodeの実行環境
今回はRaspberry Pi への Node.js インストールとnvmでのバージョン管理を参考にnvmを使ってインストールしました。ちなみに自分のmacでは初期で使えました。
sudo nodeが使えればOKです。
pythonの実行環境
今回はラズパイを使用して初期でpython2系が使えたので割愛します。
api叩いてみる
無料天気予報APIのOpenWeatherMapを使ってみるを参考にapiキーを取得します。
apiキーが取得できたら実際にapiを叩いてみます。
今回OpenWeatherAPIからほしい情報は今日の天気の情報なので、今はそれだけとってきます。(DarkSkyAPIで気温情報を取得します)
micro:bitに組み込むプログラム
今回はBLEをつかって通信します。
マイクロビットのコード作成画面でbluetoothを使えるようにします。
「高度なブロック」→「パッケージを追加する」を順にクリックしbluetoothを選択します。
これが
こうなればOKです。
次にペアリングしていないデバイスとも通信できるように設定を行います。
右上の歯車マークから「プロジェクトの設定」を選択し一番上をONにします。
こんな感じ。
このプロジェクトをmicro:bitに入れて準備完了!
micro:bitに送信する
取得した情報をmicro:bitに送信してみます。今回は天気の情報を絵にしてmicro:bitに送信したいので、16進数で点灯する場所を指定して送ります。
Node.jsのモジュールnode-bbc-microbitを使用します。
pi@raspberrypi:~/develop $ npm install bbc-microbit --save
インストールします。
var http = require('http'); var BBCMicrobit = require('../../node_modules/bbc-microbit/index'); var id = '1864518'; //chofu // var id = '2128295'; //sapporo // var id = '5128581'; //new york var appid = '自分のapiキー'; var URL = 'http://api.openweathermap.org/data/2.5/weather?id='+ id +'&appid='+ appid; var R=""; http.get(URL, function(res) { var body = ''; res.setEncoding('utf8'); res.on('data', function(chunk) { body += chunk; }); res.on('data', function(chunk) { res = JSON.parse(body); R = res.weather[0].main; weather(R) }); }).on('error', function(e) { console.log(e.message); }); var PATTERNS = [ { //天気に合わせたLEDパターン name: 'Clouds', value: new Buffer('000609110E', 'hex') }, { name: 'Thunderstorm', value: new Buffer('060C060C08', 'hex') }, { name: 'Snow', value: new Buffer('150E040E15', 'hex') }, { name: 'Clear', value: new Buffer('0E1F1F1F0E', 'hex') }, { name: 'Rain', value: new Buffer('040E1F040C', 'hex') }, ]; // search for a micro:bit, to discover a particular micro:bit use: // BBCMicrobit.discoverById(id, callback); or BBCMicrobit.discoverByAddress(id, callback); function weather(str){ for(var i=0;i<PATTERNS.length;i++){ if(str==PATTERNS[i].name){ //jsonの結果からほしいパターンを取ってくる var pattern = PATTERNS[i]; } } console.log('Scanning for microbit'); BBCMicrobit.discover(function(microbit) { console.log('\tdiscovered microbit: id = %s, address = %s', microbit.id, microbit.address); microbit.on('disconnect', function() { console.log('\tmicrobit disconnected!'); process.exit(0); }); console.log('connecting to microbit'); microbit.connectAndSetUp(function() { console.log('\tconnected to microbit'); console.log('sending pattern: "%s"', pattern.name); microbit.writeLedMatrixState(pattern.value, function() { console.log('\tpattern sent'); console.log('disconnecting'); microbit.disconnect(); }); }); }); }
このプログラムを実行したらmicro:bitのLEDに天気のマークが表示されます。今回は電通大の所在地である調布の天気を取得しています。
音声で制御する
あとは、音声で制御するためにpythonファイルを作ります。
juliusのインストールや自作辞書の作成については前回の記事を参考にしてください。
以下のコードを作成します。
import os def main(): os.system('sudo node json_weather.js') if __name__ == "__main__": main()
import socket import string import subprocess import weather import temp_now as now import temp_min as min import temp_max as max import os host = 'localhost' # Raspberry PiのIPアドレス port = 10500 # juliusの待ち受けポート # パソコンからTCP/IPで、自分PCのjuliusサーバに接続 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) data = "" while True: # "/RECOGOUT"を受信するまで、一回分の音声データを全部読み込む。 while (string.find(data, "\n.") == -1): data = data + sock.recv(1024) # 音声XMLデータから、<WORD>を抽出して音声テキスト文に連結する。 strTemp = "" for line in data.split('\n'): index = line.find('WORD="') if index != -1: line = line[index + 6:line.find('"', index + 6)] if line != "[s]": strTemp = strTemp + line if strTemp != "": print("結果:" + strTemp) if strTemp == "きょうのてんき": # if you say Hikaregoma, led will turn on #os.system('sudo python ~/irmcli/irmcli.py -p -f ~/irmcli/light_on.json') weather.main() if strTemp == "さいこうきおん": #os.system('sudo python ~/irmcli/irmcli.py -p -f ~/irmcli/light_off.json') max.main() if strTemp == "さいていきおん": min.main() if strTemp == "いまのきおん": now.main() data = ""
temp_now,temp_min,temp_maxはDarkSkyAPIをつかって気温情報を取得するプログラムです。
自分のgithubにあるので参考にしてください。
実際に実行した結果こんな感じになりました!!