APIで天気情報を取得し、obniz本体ディスプレイに情報表示、天気によりLED信号の色を変える仕組みです。
多くの先人がすでに同様の仕組みを作っていますが、苦労の末、やっと作れました。
下準備
① obnizスターターキットの用意
obnizの端子にパーツを接続
LED信号:gnd:0, green:1, yellow:2, red:3
② Visual Studio Codeの用意
初期設定
npm init -y
npm i axios
obnizとの連携の設定
npm install obniz
npm install canvas
これらをVisual Studio Codeのターミナルに入力しEnterを押してインストール
しておく。
③OpenWeatherMapのAPIキーを取得(以下のHPを参照)
https://yuukiyg.hatenablog.jp/entry/2019/11/17/182410
実行
Visual Studio Codeに、以下のコードを入力。
const axios = require('axios');
const main = async () => {
try {
const res = await axios.get('http://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&APPID={自分のAPIキー}'); // URLを書き換える
console.log(res.data); // データ全体を表示する(なくてもOK)
var Obniz = require("obniz");
var obniz = new Obniz("xxxx-xxxx"); //obninzのIDを入力
obniz.onconnect = async function () {
var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});
let currentWeather = res.data.weather[0].main;
let description = res.data.weather[0].description;
let temp = res.data.main.temp;
let temp_max = res.data.main.temp_max;
let temp_min = res.data.main.temp_min;
let city = res.data.name;
var currentDate=new Date();
var h=currentDate.getHours();
var m=currentDate.getMinutes();
var str=h+":"+m;
const RED_WEATHERS = [
"Rain",
"Snow",
"Thunderstorm",
"Drizzle",
"Fog",
"Squall"
];
const YELLOW_WEATHERS = [
"Clouds",
"Mist",
"Smoke",
"Dust",
"Haze",
"Sand",
"Ash",
"Tornado"
];
const GREEN_WEATHERS = ["Clear"];
let weather = res.data.weather[0].main;
let weather_ja = 'はれ'
switch (weather){
case 'Clear':
weather_ja = 'はれ';
break;
case 'Clouds':
weather_ja = 'くもり';
break;
case 'Mist':
weather_ja = 'もや';
break;
case 'Smoke':
weather_ja = 'けむり';
break;
case 'Dust':
weather_ja = 'ほこり';
break;
case 'Haze':
weather_ja = 'かすみ';
break;
case 'Sand':
weather_ja = 'すな';
break;
case 'Ash':
weather_ja = '灰';
break;
case 'Tornado':
weather_ja = 'たつまき';
break;
case 'Rain':
weather_ja = 'あめ';
break;
case 'Snow':
weather_ja = 'ゆき';
break;
case 'Thunderstorm':
weather_ja = 'らいう';
case 'Drizzle':
weather_ja = 'きりさめ';
break;
case 'Fog':
weather_ja = 'きり';
break;
case 'Squall':
weather_ja = 'スコール';
break;
}
if (currentWeather === undefined || currentWeather === null) {
light.green.off();
light.yellow.off();
light.red.off();
return;
}
if (RED_WEATHERS.includes(currentWeather) === true) {
light.single("red");
const { createCanvas } = require('canvas');
obniz.display.clear();
const canvas = createCanvas(128, 64);
const ctx = canvas.getContext('2d');
ctx.fillStyle = "white";
ctx.font = "15px Sans";
ctx.fillText(city, 0, 15);
ctx.fillText(weather_ja, 50, 15);
ctx.fillText(currentDate, 0, 30);
ctx.fillText(description + ' ' + str, 0, 45);
ctx.fillText(temp+'℃', 0, 60);
obniz.display.draw(ctx);
} else if (YELLOW_WEATHERS.includes(currentWeather) === true) {
light.single("yellow");
const { createCanvas } = require('canvas');
obniz.display.clear();
const canvas = createCanvas(128, 64);
const ctx = canvas.getContext('2d');
ctx.fillStyle = "white";
ctx.font = "15px Sans";
ctx.fillText(city, 0, 15);
ctx.fillText(weather_ja, 50, 15);
ctx.fillText(currentDate, 0, 30);
ctx.fillText(description + ' ' + str, 0, 45);
ctx.fillText(temp+'℃', 0, 60);
obniz.display.draw(ctx);
} else if (GREEN_WEATHERS.includes(currentWeather) === true) {
light.single("green");
const { createCanvas } = require('canvas');
obniz.display.clear();
const canvas = createCanvas(128, 64);
const ctx = canvas.getContext('2d');
ctx.fillStyle = "white";
ctx.font = "15px Sans";
ctx.fillText(city, 0, 15);
ctx.fillText(weather_ja, 50, 15);
ctx.fillText(currentDate, 0, 30);
ctx.fillText(description + ' ' + str, 0, 45);
ctx.fillText(temp+'℃', 0, 60);
obniz.display.draw(ctx);
} else {
light.green.off();
light.yellow.off();
light.red.off();
}
}
} catch (error) {
console.error(error);
}
}
main();
LED信号を光らせるだけのものはこちら。
const axios = require('axios');
const main = async () => {
try {
const res = await axios.get('http://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&APPID={取得したAPIキーを入れる}');
console.log(res.data);
var Obniz = require("obniz");
var obniz = new Obniz("{obnizのIDを入れる}");
obniz.onconnect = async function () {
var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});
let currentWeather = res.data.weather[0].main;
const RED_WEATHERS = [
"Rain",
"Snow",
"Thunderstorm",
"Drizzle",
"Fog",
"Squall"
];
const YELLOW_WEATHERS = [
"Clouds",
"Mist",
"Smoke",
"Dust",
"Haze",
"Sand",
"Ash",
"Tornado"
];
const GREEN_WEATHERS = ["Clear"];
if (currentWeather === undefined || currentWeather === null) {
light.green.off();
light.yellow.off();
light.red.off();
return;
}
if (RED_WEATHERS.includes(currentWeather) === true) {
light.single("red");
} else if (YELLOW_WEATHERS.includes(currentWeather) === true) {
light.single("yellow");
} else if (GREEN_WEATHERS.includes(currentWeather) === true) {
light.single("green");
} else {
light.green.off();
light.yellow.off();
light.red.off();
}
}
} catch (error) {
console.error(error);
}
}
main();
※LED信号の色が示す天気
青:晴れ 黄:くもり 赤:雨
工夫を要した箇所、苦労した、学習した箇所
①ネット検索にて様々なプログラム記載例があり、順次試すも動かず、試行錯誤の末に
ようやくプログラムの骨格を作ることができた。
(1)APIを取得する方法
https://yuukiyg.hatenablog.jp/entry/2019/11/17/182410
上記HPを参考にしAPIキーを取得。
(2)取得したAPIを利用して天気情報を取得する方法
・APIを読み込む為の式をネット検索して探した。幾つかあったが自分の環境
では出来ないものがほとんどだったので時間を要した。
・APIキーをどこに、どのように入れたら良いかが分からず試行錯誤を要した。
ネット検索にて大筋は理解できたが、「{取得したAPIキーを入れる}」
という部分に両端のカッコ”{ }”を残すのか要らないのかが分からず
何度か施行を要した。
(3)取得した天気データにより対応するLED信号を光らせる方法
・複数の文字列の中に、ある相当する文字列が含まれるか:includes()の使用
・includes()を利用するときに、”trueとなるとき” と表現するのに、”=”では
なく”===”とする必要があることを理解するまで時間を要した。
(4)obniz本体ディスプレイへ文字入力する方法
・obniz本体ディスプレイへの文字表示設定
obniz標準のdeveloper's consoleとは文字入力の式が違うので、
ネット検索をして取得した。
・英語情報の日本語化:switch()を利用
条件分岐する方法として、if()だけではなくswitch()という方法を
知ったので利用してみた。
②obniz本体ディスプレイへ表示できる文字数は限られているので、情報が収まるように
調整を行った。
③obniz本体ディスプレイへの情報表示は、今後も色々なものへ応用ができると考える。