UNPKG

prisme-flow

Version:

prisme platform flow engine

239 lines (223 loc) 8.7 kB
/** * Created by prisme.io on 09/06/2017. */ module.exports = function (RED) { 'use strict' var http = require('http') function assignmentFunction (node, msg, lat, lon, city, country, language, callback) { if (country && city) { node.country = country node.city = city } else if (lat && lon) { if (lat <= 90 && lat >= -90) { node.lat = lat } else { node.error(RED._('Invalid latitude (lat) provided'), msg) return } if (lon <= 180 && lon >= -180) { node.lon = lon } else { node.error(RED._('Invalid longitude (lon) provided'), msg) return } } node.language = language || 'en' callback() } function weatherPoll (node, msg, callback) { // wipe clear the payload if it exists, or create it if it doesn't msg.payload = {} msg.location = {} var url if (node.hasOwnProperty('credentials') && node.credentials.hasOwnProperty('apikey')) { // If there is a value missing, the URL is not initialised. if (node.wtype === 'forecast') { if (node.lat && node.lon) { url = 'http://api.openweathermap.org/data/2.5/forecast/daily?lang=' + node.language + '&cnt=5&units=metric&lat=' + node.lat + '&lon=' + node.lon + '&APPID=' + node.credentials.apikey } else if (node.city && node.country) { url = 'http://api.openweathermap.org/data/2.5/forecast/daily?lang=' + node.language + '&cnt=5&units=metric&q=' + node.city + ',' + node.country + '&APPID=' + node.credentials.apikey } } else { if (node.lat && node.lon) { url = 'http://api.openweathermap.org/data/2.5/weather?lang=' + node.language + '&lat=' + node.lat + '&lon=' + node.lon + '&APPID=' + node.credentials.apikey } else if (node.city && node.country) { url = 'http://api.openweathermap.org/data/2.5/weather?lang=' + node.language + '&q=' + node.city + ',' + node.country + '&APPID=' + node.credentials.apikey } } // If the URL is not initialised, there has been an error with the input data, // and a node.error is reported. if (url) { node.status({fill: 'blue', shape: 'dot', text: 'requesting'}) http.get(url, function (res) { var weather = '' res.on('data', function (d) { weather += d }) res.on('end', function () { var jsun if (weather.indexOf('Invalid API key') > -1) { callback(RED._('Invalid API Key provided')) return } try { jsun = JSON.parse(weather) } catch (e) { callback(RED._('The API call returned invalid JSON')) return } if (jsun) { msg.data = jsun if (jsun.hasOwnProperty('weather') && jsun.hasOwnProperty('main')) { msg.payload.weather = jsun.weather[0].main msg.payload.detail = jsun.weather[0].description msg.payload.tempk = jsun.main.temp if (jsun.main.hasOwnProperty('temp')) { msg.payload.tempc = parseInt(10 * (Number(jsun.main.temp) - 273.2)) / 10 } if (jsun.main.hasOwnProperty('temp_max')) { msg.payload.temp_maxc = parseInt(10 * (Number(jsun.main.temp_max) - 273.2)) / 10 } if (jsun.main.hasOwnProperty('temp_min')) { msg.payload.temp_minc = parseInt(10 * (Number(jsun.main.temp_min) - 273.2)) / 10 } msg.payload.humidity = jsun.main.humidity msg.payload.maxtemp = jsun.main.temp_max msg.payload.mintemp = jsun.main.temp_min msg.payload.windspeed = jsun.wind.speed msg.payload.winddirection = jsun.wind.deg msg.payload.location = jsun.name msg.payload.sunrise = jsun.sys.sunrise msg.payload.sunset = jsun.sys.sunset msg.payload.clouds = jsun.clouds.all if (jsun.hasOwnProperty('coord')) { msg.location.lon = jsun.coord.lon msg.location.lat = jsun.coord.lat } msg.location.city = jsun.name msg.location.country = jsun.sys.country if (jsun.hasOwnProperty('dt')) { msg.time = new Date(jsun.dt * 1000) } msg.title = RED._('Current Weather Information') msg.description = RED._('Current weather information at coordinates: __lat__, __lon__', {lat: msg.location.lat, lon: msg.location.lon}) msg.payload.description = (RED._('The weather in __name__ at coordinates: __lat__, __lon__ is __main__ (__description__).', {name: jsun.name, lat: jsun.coord.lat, lon: jsun.coord.lon, main: jsun.weather[0].main, description: jsun.weather[0].description})) callback() } else if (jsun.hasOwnProperty('list')) { msg.payload = jsun.list if (jsun.hasOwnProperty('city')) { msg.location.city = jsun.city.name msg.location.country = jsun.city.country if (jsun.city.hasOwnProperty('coord')) { msg.location.lat = jsun.city.coord.lat msg.location.lon = jsun.city.coord.lon } } msg.title = RED._('5 day Forecast') callback() } else { if (jsun.message === 'Error: Not found city') { callback(RED._('Invalid city/country')) } else { callback(jsun.cod + ' ' + jsun.message) } } } }) }).on('error', function (e) { callback(e) }) node.status({}) } else { callback(RED._('Invalid location information provided')) } } else { node.error(RED._('No API key set')) } } function OpenWeatherMapInputNode (n) { RED.nodes.createNode(this, n) var node = this this.repeat = 600000 // every 10 minutes this.interval_id = null var previousdata = null var city var country var language var lat var lon if ((!node.credentials) || (!node.credentials.hasOwnProperty('apikey'))) { node.error(RED._('No API key set')) } this.interval_id = setInterval(function () { node.emit('input', {}) }, this.repeat) this.on('input', function (msg) { if (n.country && n.city) { country = n.country city = n.city } else if (n.lat && n.lon) { lat = n.lat lon = n.lon } language = n.language || 'en' assignmentFunction(node, msg, lat, lon, city, country, language, function () { weatherPoll(node, msg, function (err) { if (err) { node.error(err, msg) } else { var msgString = JSON.stringify(msg) if (msgString !== previousdata) { previousdata = msgString node.send(msg) } } }) }) }) this.on('close', function () { if (this.interval_id !== null) { clearInterval(this.interval_id) } }) node.emit('input', {}) } function OpenWeatherMapQueryNode (n) { RED.nodes.createNode(this, n) this.wtype = n.wtype var node = this var city var country var language var lat var lon if ((!node.credentials) || (!node.credentials.hasOwnProperty('apikey'))) { node.error(RED._('No API key set')) } this.on('input', function (msg) { if (n.country && n.city) { country = n.country city = n.city } else if (n.lat && n.lon) { lat = n.lat lon = n.lon } else if (msg.location) { if (msg.location.lat && msg.location.lon) { lat = msg.location.lat lon = msg.location.lon } else if (msg.location.city && msg.location.country) { city = msg.location.city country = msg.location.country } } language = n.language || 'en' assignmentFunction(node, msg, lat, lon, city, country, language, function () { weatherPoll(node, msg, function (err) { if (err) { node.error(err, msg) } else { node.send(msg) } }) }) }) } RED.nodes.registerType('openweathermap', OpenWeatherMapQueryNode, { credentials: { apikey: {type: 'password'} } }) RED.nodes.registerType('openweathermap in', OpenWeatherMapInputNode, { credentials: { apikey: {type: 'password'} } }) }