0
0

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-10-20

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0