「Visual Studio Codeで、obnizに天気の情報を表示させ、天気に対応するLED信号を光らせる」

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に、以下のコードを入力。

```javascript
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();

```

https://twitter.com/21HideK/status/1450849420841390085

LED信号を光らせるだけのものはこちら。

```javascript
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本体ディスプレイへの情報表示は、今後も色々なものへ応用ができると考える。