自分の居場所を OpenWeatherMap に投げて直近の天気予報を表示するくそアプリ。
- シンプルイズベスト。
- 居場所は、 GeoLocation を使用。
- 天気予報は、 OpenWeatherMap から取得。
- 天候は、次の4タイプのみとした。 晴れ/曇り/雨/雪
できた!
▼ Flow をエクスポート
- OpenWeatherMap の API Key は書き換えないと動作しない。
[{"id":"34c5cf5.5aa2fb","type":"http in","z":"f582755b.efeaf8","name":"request weather app","url":"/weather","method":"get","swaggerDoc":"","x":150,"y":80,"wires":[["2d6206d5.b21842"]]},{"id":"c56f0360.c2cce8","type":"template","z":"f582755b.efeaf8","name":"html","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n <head>\n <link href=\"//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css\" rel=\"stylesheet\" />\n <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js\"></script>\n <style type=\"text/css\">\n {{{css}}}\n </style>\n <script type=\"text/javascript\">\n {{{js}}}\n </script>\n </head>\n <body>\n <div id=\"weather\">\n <i id=\"icon\" class=\"fa weathericon\" aria-hidden=\"true\"></i>\n </div>\n </body>\n</html>","x":610,"y":80,"wires":[["4708a4b4.ab6014"]]},{"id":"4708a4b4.ab6014","type":"http response","z":"f582755b.efeaf8","name":"response","x":760,"y":80,"wires":[]},{"id":"f089755f.8069c8","type":"http in","z":"f582755b.efeaf8","name":"get weather","url":"/get","method":"get","swaggerDoc":"","x":130,"y":160,"wires":[["6ef16af5.167c9c"]]},{"id":"6ef16af5.167c9c","type":"function","z":"f582755b.efeaf8","name":"make url","func":"var lat = msg.payload.lat;\nvar lon = msg.payload.lon;\nvar baseurl = \"http://api.openweathermap.org/data/2.5/weather\";\nvar appid = \"e4157daxxxxxxxxxxxxxxxxxxb9baf14\";\n\nmsg.url = baseurl + \"?lat=\" + lat + \"&lon=\" + lon + \"&APPID=\" + appid;\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":160,"wires":[["26258434.060ae4"]]},{"id":"c473b665.a208e","type":"http response","z":"f582755b.efeaf8","name":"response","x":880,"y":160,"wires":[]},{"id":"26258434.060ae4","type":"http request","z":"f582755b.efeaf8","name":"call OpenWeatherMap","method":"GET","ret":"obj","url":"","x":500,"y":160,"wires":[["2ecd2991.4b7996"]]},{"id":"2ecd2991.4b7996","type":"function","z":"f582755b.efeaf8","name":"set weather","func":"var weather = msg.payload.weather[0].icon.substr(0, 2);\nvar weatherstring = \"\";\nswitch (weather) {\n case \"01\":\n weatherstring = \"sun\";\n break;\n case \"02\":\n case \"03\":\n case \"04\":\n weatherstring = \"cloud\";\n break;\n case \"09\":\n case \"10\":\n case \"11\":\n weatherstring = \"rain\";\n break;\n case \"13\":\n weatherstring = \"snow\";\n break;\n default:\n weatherstring = \"cloud\";\n break;\n}\nmsg.payload = weatherstring;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":160,"wires":[["c473b665.a208e"]]},{"id":"2d6206d5.b21842","type":"template","z":"f582755b.efeaf8","name":"css","field":"css","fieldType":"msg","format":"handlebars","syntax":"plain","template":"html, body {\n padding: 0;\n margin: 0;\n height: 100%;\n background-color: black;\n}\n#weather {\n position: relative;\n height: 100%;\n}\n.weathericon {\n font-size: 400px;\n display: block;\n text-align: center;\n position: absolute;\n top: 50%;\n margin: -200px 0 0 0;\n width: 100%;\n}\n.cloudy {\n color: white;\n background-color: #99a3a4;\n}\n.rainy {\n color: white;\n background-color: #85c1e9;\n}\n.sunny {\n color: white;\n background-color: #f39c12;\n}\n.snowy {\n color: white;\n background-color: #e5e8e8;\n}","x":330,"y":80,"wires":[["9ec2db8a.eb3238"]]},{"id":"9ec2db8a.eb3238","type":"template","z":"f582755b.efeaf8","name":"js","field":"js","fieldType":"msg","format":"handlebars","syntax":"plain","template":"$(function(){\n var baseurl = \"https://nodered-pro2-35hshwv45.herokuapp.com\";\n\tif( navigator.geolocation ) {\n\t\tnavigator.geolocation.getCurrentPosition(\n\t\t\tfunction( position ){\n\t\t\t\tvar data = position.coords ;\n\t\t\t\tvar lat = data.latitude ;\n\t\t\t\tvar lon = data.longitude ;\n\t\t\t\tconsole.log(lat + \",\" + lon);\n $.ajax({\n type: \"GET\",\n url: baseurl + '/get?lat=' + lat + '&lon=' + lon,\n dataType: 'text',\n cache: true,\n timeout: 10000\n }).done(function(response, textStatus, jqXHR) {\n console.log(response);\n var wt = '';\n var cl = '';\n switch (response) {\n case \"sun\":\n wt = 'fa-sun-o sunny';\n cl = 'sunny';\n break;\n case \"cloud\":\n wt = 'fa-cloud cloudy';\n cl = 'cloudy';\n break;\n case \"rain\":\n wt = 'fa-tint rainy';\n cl = 'rainy';\n break;\n case \"snow\":\n wt = 'fa-snowflake-o snowy';\n cl = 'snowy';\n break;\n }\n $(\"body\").addClass(cl);\n $(\"#icon\").addClass(wt);\n }).fail(function(jqXHR, textStatus, errorThrown ) {\n console.error(\"ajax\");\n });\n\t\t\t},\n\t\t\tfunction( error ){\n\t\t\t console.error(error.code);\n\t\t\t} ,\n\t\t\t{\n\t\t\t\t\"enableHighAccuracy\": false,\n\t\t\t\t\"timeout\": 8000,\n\t\t\t\t\"maximumAge\": 2000,\n\t\t\t}\n\t\t) ;\n\t} else {\n\t console.error('geolocation');\n\t};\n});\n","x":470,"y":80,"wires":[["c56f0360.c2cce8"]]}]
▼ こんな Flow
- UI の流れ
- 天気予報APIのラッパーAPI的な流れ
▼ こんなアプリ
まずは準備(OpenWeatherMap の Key を取得)
- OpenWeatherMap のAPI利用にはユーザ登録が必要。
▼ サインアップ。
▼ API Key のページを開いて、API Key をゲット。
そして enebular
▼ enebular でログイン。
▼ [ +New Project ] ボタンで新規プロジェクトを作成。
▼ [ New Flow ] ボタンで新規フローを作成。
UI の Flow 作成へ
▼ http ノードはこんな感じ。これでアプリのURLが決まる。
▼ アプリはこんなURLになる
▼ ドメイン部分はココ!
▼ template ノード(css)はこんな感じ。
- 今回はtemplateノードを、css用、js用、html用の3つに分割。
html, body {
padding: 0;
margin: 0;
height: 100%;
background-color: black;
}
#weather {
position: relative;
height: 100%;
}
.weathericon {
font-size: 400px;
display: block;
text-align: center;
position: absolute;
top: 50%;
margin: -200px 0 0 0;
width: 100%;
}
.cloudy {
color: white;
background-color: #99a3a4;
}
.rainy {
color: white;
background-color: #85c1e9;
}
.sunny {
color: white;
background-color: #f39c12;
}
.snowy {
color: white;
background-color: #e5e8e8;
}
▼ template ノード(js)はこんな感じ。
- html用のノードでjquery読み込んでるので、jqueryで書く。このjsはhtmlに展開される。
- navigator.geolocation で、現在位置を取得。
- 取得した位置情報をパラメータにくっつけて天気予報APIをコール。
$(function(){
var baseurl = "https://nodered-pro2-35hshwv45.herokuapp.com";
if( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(
function( position ){
var data = position.coords ;
var lat = data.latitude ;
var lon = data.longitude ;
console.log(lat + "," + lon);
$.ajax({
type: "GET",
url: baseurl + '/get?lat=' + lat + '&lon=' + lon,
dataType: 'text',
cache: true,
timeout: 10000
}).done(function(response, textStatus, jqXHR) {
console.log(response);
var wt = '';
var cl = '';
switch (response) {
case "sun":
wt = 'fa-sun-o sunny';
cl = 'sunny';
break;
case "cloud":
wt = 'fa-cloud cloudy';
cl = 'cloudy';
break;
case "rain":
wt = 'fa-tint rainy';
cl = 'rainy';
break;
case "snow":
wt = 'fa-snowflake-o snowy';
cl = 'snowy';
break;
}
$("body").addClass(cl);
$("#icon").addClass(wt);
}).fail(function(jqXHR, textStatus, errorThrown ) {
console.error("ajax");
});
},
function( error ){
console.error(error.code);
} ,
{
"enableHighAccuracy": false,
"timeout": 8000,
"maximumAge": 2000,
}
) ;
} else {
console.error('geolocation');
};
});
▼ template ノード(HTML)はこんな感じ。矢印の部分の括弧に注意。
- cssとjsを展開するとこだけ注意。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style type="text/css">
{{{css}}}
</style>
<script type="text/javascript">
{{{js}}}
</script>
</head>
<body>
<div id="weather">
<i id="icon" class="fa weathericon" aria-hidden="true"></i>
</div>
</body>
</html>
▼ http request ノード(response)はこんな感じ。
天気予報 API を呼び出す API のフロー。
▼ API のエンドポイントのノードはこんな感じ。
▼ Function ノード(make url)はこんな感じ。
- http in ノードで受け取ったパラメータを処理。
- OpenWeatherMap をコールするURLの作成。
var lat = msg.payload.lat;
var lon = msg.payload.lon;
var baseurl = "http://api.openweathermap.org/data/2.5/weather";
var appid = "e4157daxxxxxxxxxxxxxxxxxxb9baf14";
msg.url = baseurl + "?lat=" + lat + "&lon=" + lon + "&APPID=" + appid;
return msg;
▼ http request ノード(make url)はこんな感じ。
▼ Function ノード(set weather)はこんな感じ。
- 天気を4パターンに集約。
var weather = msg.payload.weather[0].icon.substr(0, 2);
var weatherstring = "";
switch (weather) {
case "01":
weatherstring = "sun";
break;
case "02":
case "03":
case "04":
weatherstring = "cloud";
break;
case "09":
case "10":
case "11":
weatherstring = "rain";
break;
case "13":
weatherstring = "snow";
break;
default:
weatherstring = "cloud";
break;
}
msg.payload = weatherstring;
return msg;
▼ Function ノード(response)はこんな感じ。
以上