micro:bit に天気情報を表示する方法は検索するといくつか見つかるのだが、ラズベリーパイ(RSコンポーネンツ のページなどから購入できる)、さらに ScratchX を使った方法はみつからなかったので調べてみた。
※補足:RSコンポーネンツは、Raspberry Piの国内総代理店です。電子工作にも使われる加速度センサ などの部品等を50万点超取り扱っており、世界32ヵ国へオンライン販売をしています。
ラズベリーパイ上の ScratchX と micro:bit をつなげるには、
» micro:bit を Scratch から操作できる s2m が日本語に対応しました
で紹介した s2m などがあるが、今回は、ワイヤレスで接続することができる jaafreitas/scratch-microbit-extension: BBC micro:bit Scratch extension を使う。
ラズベリーパイでは Raspbian OS を使っているものとし、ターミナルを立ち上げ、
$ sudo apt install nodejs npm
を実行して、Node.js と npm をインストールする。
次に、scratch-microbit-extension のソースをダウンロードし、解凍する。
$ wget https://github.com/jaafreitas/scratch-microbit-extension/archive/master.zip
$ unzip master.zip
以下の通り実行して、extension を起動するまでの準備をおこなっておく。
$ cd scratch-microbit-extension-master
$ npm install
scratch-microbit-extension と micro:bit とが通信できるように、micro:bit 側には専用の hex ファイルをインストールする。
micro:bit に USB ケーブルをつなげ、ケーブルをラズベリーパイの USB ポートに挿す。micro:bit は /media/pi/MICROBIT にマウントされるので、以下のコマンドを実行して、firmware フォルダ以下の makecode-microbit-scratch-extension.hex ファイルを micro:bit にコピーする。
cp firmware/makecode-microbit-scratch-extension.hex /media/pi/MICROBIT/
コピーしたあと、micro:bit のリセットボタンを一度押しておくと、extension と接続しやすくなるようだ。
次に、ラズベリーパイ上で Chronium Web Browser を起動し、アドレス欄に
http://scratchx.org/?url=https://jaafreitas.github.io/scratch-microbit-extension/scratch_microbit.js&lang=en
を貼り付けて、ScratchX の extension を読み込む。
Extension を読み込んでよいのか許可を求めるダイアログが表示されるので、緑のボタンを押して許可すると、More Blocks カテゴリに、BBC micro:bit 用のブロックが追加される。
BBC micro:bit の横に赤丸が表示されており、まだ micro:bit との接続が確立されていないことを示している。
ターミナルに戻り、
$ sudo node index.js
を実行する。以下のキャプチャのように、ターミナル上に connected true と表示され、ScratchX 上では先ほどの BBC micro:bit の横の赤丸が緑色に変われば、接続がうまくいったことを示している。
接続がうまくいかないときには micro:bit のリセットボタンを押すとうまくいくことが多い。
ScratchX 上の「clear display」ブロックをクリックすると micro:bit の LED がまっさらになり、「display ?」のブロックをクリックすれば ? と LED 上に表示されることを確かめる。
micro:bit を USB ケーブルの代わりに電池ボックスなどで給電すれば、ScratchX 上から micro:bit をワイヤレスで操作できるようになった。
次に天気情報を取得するために、天気情報APIに接続する ScratchX エクステンションを読み込む。
» ScratchXを使って天気を取得するブロックを作成
で紹介されていた OpenWeatherMap API から天気情報を取得する ScratchX エクステンションを使わせてもらう。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(ext) {
ext._shutdown = function() {};
ext._getStatus = function() {
return {status: 2, msg: 'Ready'};
};
ext.get_weather = function(callback) {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=Kashiwa,%20JP&units=imperial&APPID=fa4bc3cd05fcedff03fcec2db6bb2a4f',
dataType: 'jsonp',
success: function(data) {
if (data.cod == 200) {
console.log(data);
var main = data.weather[0].main;
if (main == undefined) {
callback('');
} else {
callback(main);
}
} else {
callback('');
}
}
});
};
ext.get_location_wather = function(loc, callback) {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=' + encodeURIComponent(loc) + '&units=imperial&APPID=fa4bc3cd05fcedff03fcec2db6bb2a4f',
dataType: 'jsonp',
success: function(data) {
if (data.cod == 200) {
console.log(data);
var main = data.weather[0].main;
if (main == undefined) {
callback('');
} else {
callback(main);
}
} else {
callback('');
}
}
});
};
ext.get_location_temp = function(loc, callback) {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=' + encodeURIComponent(loc) + '&units=imperial&APPID=fa4bc3cd05fcedff03fcec2db6bb2a4f',
dataType: 'jsonp',
success: function(data) {
if (data.cod == 200) {
console.log(data);
var temp = data.main.temp;
if (temp == undefined) {
callback('');
} else {
callback((5/9)*(temp-32));
}
} else {
callback('');
}
}
});
};
ext.get_location_temp = function(loc, callback) {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=' + encodeURIComponent(loc) + '&units=imperial&APPID=fa4bc3cd05fcedff03fcec2db6bb2a4f',
dataType: 'jsonp',
success: function(data) {
if (data.cod == 200) {
console.log(data);
var temp = data.main.temp;
if (temp == undefined) {
callback('');
} else {
callback((5/9)*(temp-32));
}
} else {
callback('');
}
}
});
};
var forecast = [];
var pointer = 0;
ext.retrive_forcast = function(loc, callback) {
forecast = [];
pointer = 0;
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/forecast?q=' + encodeURIComponent(loc) + '&units=imperial&APPID=fa4bc3cd05fcedff03fcec2db6bb2a4f',
dataType: 'jsonp',
success: function(data) {
if (data.cod == 200) {
forecast = data.list;
callback();
} else {
callback();
}
}
});
};
ext.get_forcast_temp = function() {
if (forecast.length <= 0) {
return '';
}
if (pointer >= forecast.length) {
return '';
}
var f = forecast[pointer];
pointer++;
return (5/9)*(f.main.temp-32);
}
var descriptor = {
blocks: [
['R', '天気を取得', 'get_weather'],
['R', '%s の天気を取得', 'get_location_wather'],
['R', '%s の気温を取得', 'get_location_temp'],
['w', '%s の予報を取得', 'retrive_forcast'],
['r', '予報から気温を1つ取得', 'get_forcast_temp']
]
};
ScratchExtensions.register('お天気拡張', descriptor, ext);
})({});
上記スクリプトを ScratchX から読み込めるように Web サーバーに置く必要があるのだが、ローカルの Web サーバーでもよいので、Node.js の http-server を使う。
scratch-microbit-extension を起動しているターミナルとは別のターミナルを開き、
$ sudo npm install -g http-server
で http-server をインストールする。
適当な場所に myscript.js というファイルを用意し、先述したスクリプトの内容を貼り付ける。ファイルが置かれているディレクトリで、
$ http-server
を実行すれば、localhost:8080/myscript.js で天気情報取得エクステンションにアクセスできる。
ScratchX 上の More Blocks カテゴリを選び、Load Experimental Extension ボタンをクリックして、localhost:8080/myscript.js を Extension URL として入力すれば、以下のように天気情報を取得できるブロックが追加される。
「[ ]の天気を取得」ブロックの [ ] にアルファベットで地名を入力し、クリックすれば、その場所の天気の情報を取得できる。
以下のようなスクリプトを用意すれば、micro:bit の A ボタンを押せば、好きな場所の天気の情報が micro:bit の LED に表示される。
本日の調布の天気は雨、Rain と表示されるようになりました。
たとえば予報を取得するようにエクステンションを改造して、常に表示するようにした micro:bit を傘立ての近くに置いておけば役に立ちそうだ。(ScratchX とそのエクステンションの作り方については、スクラッチャーのためのScratchX入門 - その1 ScratchXとは? で解説している)
ScratchX のエクステンションはいくつも読み込むことができるので、組み合わせればいろいろなことができるし、ラズベリーパイならばどこにでも置いておくことができるので、様々な応用が考えられそうです。