Akihiron が 2021年05月16日19時38分31秒 に編集
初版
タイトルの変更
天気情報をobnizのディスプレイに表示
タグの変更
obnizIoTコンテスト
obniz
スマートホーム
IoT
本文の変更
# はじめに Obnizのディスプレイに天気情報を表示するシステムを作りました。 Obnizの左上のスイッチを押すと、天気情報を取得して、LCDに表示します。 5日分の天気を3時間ごとに、絵文字で表示します。 @[youtube](https://youtu.be/CJSSxwcSVKs) 本当は、Arducamで冷蔵庫の中身の状況をスマホから確認できるシステムを作るつもりでした。 ですが、動作不良なのか、Arducamのサンプルコードを動かそうとすると、エラーが発生して動かなかったので、今回のシステムにしました。 # システム構成 以下のような簡単なシステムです。 ![システム構成](https://camo.elchika.com/dbf79b59a6d7ffee3eb078e08e5c018453ab30ba/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f34653632336236612d376231302d343562662d383439342d6461663563653833303962342f36623832613364342d616664332d346331322d623166392d613564376538633937326237/) ## H/W 構成 obniz を電源と接続するだけです。 obnizの左上のスイッチを天気情報を取得するトリガーに使用します。 ## S/W 実装 ・前準備 楽天APIから[Open Weather Map](https://api.rakuten.net/community/api/open-weather-map?endpoint=apiendpoint_f719676c-072b-4a2d-ad2e-78f8375ea9c8)のAPIを登録します。 実装したアプリは以下です。 OBNIZ_IDとAPI_KEYの部分を、適切な値に変更してください。 # ソースコード ```javascript const Obniz = require('obniz'); const request = require('request'); const { createCanvas } = require('canvas'); const { ObnizError } = require('obniz/dist/src/obniz/ObnizError'); var is_printing = false; var obniz = new Obniz("OBNIZ_ID"); obniz.onconnect = async function(){ obniz.display.clear(); const canvas = createCanvas(128, 64); const ctx = canvas.getContext('2d'); ctx.fillStyle = "white"; ctx.font = "11px Avenir"; ctx.fillText("左上のスイッチを押すと", 0, 30); ctx.fillText("天気を表示します", 0, 50); obniz.display.draw(ctx); ctx.clearRect(0, 0, 128, 64); /* スイッチの監視 */ obniz.switch.onchange = function(state) { if(!is_printing && "push" === state){ request(options, function (error, response, body) { if (error) throw new Error(error); // obniz.display.print(body); PrintWeather(body); }); } } } const options = { method: 'GET', url: 'https://community-open-weather-map.p.rapidapi.com/forecast', qs: {q: 'san francisco,us'}, headers: { 'x-rapidapi-key': API_KEY, 'x-rapidapi-host': 'community-open-weather-map.p.rapidapi.com', useQueryString: true } }; /* 天気情報をディスプレイに表示する関数 */ async function PrintWeather(body){ is_printing = true; var body_parsed = JSON.parse(body); var result = ""; var month = "" var day = "" /* 表示する文字列を作成 */ for(var i = 0; i < body_parsed.cnt; i++){ console.log(body_parsed.list[i].dt_txt); console.log(body_parsed.list[i].weather[0].main); var month_tmp = body_parsed.list[i].dt_txt.split('-')[1]; var day_tmp = body_parsed.list[i].dt_txt.split('-')[2].split(" ")[0]; if (month_tmp != month || day_tmp != day){ month = month_tmp; day = day_tmp; result += " " + month + "/" + day + ":"; } var weather = body_parsed.list[i].weather[0].main switch(weather){ case "Clear": result += "☀"; break; case "Clouds": result += "☁"; break; case "Thunderstorm": result += "⚡"; break; case "Drizzle": result += "☂"; break; case "Rain": result += "☂"; break; case "Snow": result += "❄"; break; default: result += "?"; break; } } const canvas = createCanvas(128, 64); const ctx = canvas.getContext('2d'); ctx.fillStyle = "white"; ctx.font = "15px Avenir"; console.log(result); /* 文字をスクロールして表示 */ for(var i = 0; i < result.length*15; i++){ ctx.fillText("京都市", 0, 30); ctx.fillText(result, -i, 50); obniz.display.draw(ctx); ctx.clearRect(0, 0, 128, 64); await obniz.wait(25); } is_printing = false; } ``` 処理の流れとしては以下の通りです。 1. 起動すると左上のスイッチの入力を待機 1. スイッチが入力されると、天気情報を取得 1. 取得したデータを解析して、ディスプレイに表示する文字列を作成 1. ディスプレイに文字列を、少しずつずらしながら表示 # 工夫した点 ディスプレイに天気情報をスクロールで表示した点です。 # まとめと所感 次回は、他のセンサなどと組み合わせた作品を作りたいと思います。