diff --git a/README.md b/README.md index 39fe213..a6f99f4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Coverage Status](https://coveralls.io/repos/github/farahat80/react-open-weather/badge.png?branch=master)](https://coveralls.io/github/farahat80/react-open-weather?branch=master) [![Code Climate](https://codeclimate.com/github/farahat80/react-open-weather/badges/gpa.svg)](https://codeclimate.com/github/farahat80/react-open-weather) -React open weather is a React Component loading forecast data from [Open Weather Map](https://openweathermap.org/). +React open weather is a React Component loading forecast data from [ApiXU](https://www.apixu.com/). Features Implemented: @@ -19,7 +19,7 @@ The Component development is in progress and will contain more features in the f ### Installation ------------- -First you will need to register and account on open weather map website and obtain an [API key](http://openweathermap.org/appid) +First you will need to register and account on ApiXu website and obtain an [API key](https://www.apixu.com/pricing.aspx) Next, in your project directory run: ```sh @@ -77,6 +77,14 @@ require('react-open-weather/lib/css/ReactWeather.css'); lon="11.5820" /> ``` +### 3-Loading today data based on the current IP address (default) +```html + +``` ### 3-Loading 5 days forecast ```html @@ -100,7 +108,7 @@ require('react-open-weather/lib/css/ReactWeather.css'); ## Props Options | Props | Options | Default | Description | |----------|-----------------------|---------|-------------| -| **type** | 'city', 'geo' | geo | Determine the data should be loaded by city name or longitude and latitude | +| **type** | 'city', 'geo', 'auto' | auto | Determine the data should be loaded by city name or longitude and latitude | | **city** | | | Name of the city to show forecast for, must be provided if the type='city'| | **lon** | | | Longitude value, must be provided if the type='geo' | | **lat** | | | latitude value, must be provided if the type='geo' | diff --git a/docs/_includes/head.html b/docs/_includes/head.html index 4e9a122..deb9383 100644 --- a/docs/_includes/head.html +++ b/docs/_includes/head.html @@ -9,10 +9,10 @@ - + - + \ No newline at end of file diff --git a/docs/assets/css/app.css b/docs/assets/css/component.css similarity index 93% rename from docs/assets/css/app.css rename to docs/assets/css/component.css index e6bc556..7a92708 100644 --- a/docs/assets/css/app.css +++ b/docs/assets/css/component.css @@ -36,7 +36,11 @@ .rw-main .rw-today .date { color: #B5DEF4; } .rw-main .rw-today .current { - font-size: 50px; } + font-size: 45px; } + .rw-main .rw-today .range { + color: #B5DEF4; + font-size: 12px; + margin: 0 0 5px 2px; } .rw-main .rw-today .desc { color: #B5DEF4; font-size: 16px; } @@ -67,11 +71,8 @@ font-size: 11px; font-weight: bold; } .rw-box-days .rw-desc { - margin-top: 20px; + margin: 10px 0 10px 0; font-size: 12px; } - .rw-box-days .rw-current { - margin-top: 10px; - font-size: 20px; } .rw-box-days .rw-range { font-size: 11px; } .rw-box-days .rw-info { diff --git a/docs/assets/js/app.js b/docs/assets/js/component.js similarity index 95% rename from docs/assets/js/app.js rename to docs/assets/js/component.js index 9ddc2ba..66686b7 100644 --- a/docs/assets/js/app.js +++ b/docs/assets/js/component.js @@ -66,9 +66,9 @@ return /******/ (function(modules) { // webpackBootstrap var _react2 = _interopRequireDefault(_react); - var _OWApi = __webpack_require__(2); + var _XuApi = __webpack_require__(2); - var _OWApi2 = _interopRequireDefault(_OWApi); + var _XuApi2 = _interopRequireDefault(_XuApi); var _utils = __webpack_require__(33); @@ -98,7 +98,7 @@ return /******/ (function(modules) { // webpackBootstrap var propTypes = { unit: _react.PropTypes.oneOf(['metric', 'imperial']), - type: _react.PropTypes.oneOf(['geo', 'city']), + type: _react.PropTypes.oneOf(['geo', 'city', 'auto']), lat: _react.PropTypes.string, lon: _react.PropTypes.string, city: _react.PropTypes.string, @@ -108,7 +108,7 @@ return /******/ (function(modules) { // webpackBootstrap var defaultProps = { unit: 'metric', - type: 'geo', + type: 'auto', forecast: 'today' }; @@ -120,7 +120,7 @@ return /******/ (function(modules) { // webpackBootstrap var _this = _possibleConstructorReturn(this, (ReactWeather.__proto__ || Object.getPrototypeOf(ReactWeather)).call(this, props)); - _this.api = new _OWApi2['default'](props.unit, props.apikey); + _this.api = new _XuApi2['default'](props.unit, props.apikey); _this.state = { data: null }; @@ -139,7 +139,7 @@ return /******/ (function(modules) { // webpackBootstrap if (data) { var days = data.days; var today = days[0]; - var todayIcon = _utils2['default'].getIcon(today.weather.icon); + var todayIcon = _utils2['default'].getIcon(today.icon); return _react2['default'].createElement( 'div', { className: 'rw-box' }, @@ -152,7 +152,7 @@ return /******/ (function(modules) { // webpackBootstrap _react2['default'].createElement( 'h2', null, - data.city.name + data.location.name ), _react2['default'].createElement(_TodayForecast2['default'], { todayData: today, unit: unit }) ), @@ -178,25 +178,20 @@ return /******/ (function(modules) { // webpackBootstrap key: 'componentDidMount', value: function () { function componentDidMount() { - this.getWeatherData(); + this.getForecastData(); } return componentDidMount; }() }, { - key: 'getWeatherData', + key: 'getForecastData', value: function () { - function getWeatherData() { + function getForecastData() { var self = this; var forecast = self.props.forecast; var params = self._getParams(); var promise = null; - if (forecast === 'today') { - promise = self.api.getWeatherData(params); - } else if (forecast === '5days') { - params.cnt = 5; - promise = self.api.getForecastData(params); - } + promise = self.api.getForecast(params); promise.then(function (data) { self.setState({ data: data @@ -204,7 +199,7 @@ return /******/ (function(modules) { // webpackBootstrap }); } - return getWeatherData; + return getForecastData; }() }, { key: '_getParams', @@ -219,8 +214,14 @@ return /******/ (function(modules) { // webpackBootstrap switch (type) { case 'city': return { q: city }; + case 'geo': + return { + q: lat + ',' + lon + }; default: - return { lon: lon, lat: lat }; + return { + q: 'auto:ip' + }; } } @@ -284,130 +285,93 @@ return /******/ (function(modules) { // webpackBootstrap function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var OWApi = function () { - function OWApi(unit, apiKey) { - _classCallCheck(this, OWApi); + var FIELDS = { + metric: { + temperature: { + current: 'temp_c', + min: 'mintemp_c', + max: 'maxtemp_c' + }, + wind: 'maxwind_kph' + }, + imperial: { + temperature: { + current: 'temp_f', + min: 'mintemp_f', + max: 'maxtemp_f' + }, + wind: 'maxwind_mph' + } + }; + + var XuApi = function () { + function XuApi(unit, apiKey) { + _classCallCheck(this, XuApi); this.unit = unit; - this.baseApiUrl = '//api.openweathermap.org/data/2.5/'; this.apiKey = apiKey; + this.baseApiUrl = '//api.apixu.com/v1/forecast.json'; } - _createClass(OWApi, [{ - key: 'getWeatherData', + _createClass(XuApi, [{ + key: 'getForecast', value: function () { - function getWeatherData(args) { + function getForecast(args) { var self = this; - var endpoint = self.baseApiUrl + 'weather'; + var endpoint = self.baseApiUrl; var params = Object.assign({ - units: self.unit, - APPID: self.apiKey + key: self.apiKey, + days: 5 }, args); var promise = _axios2['default'].get(endpoint, { params: params }).then(function (response) { var data = response.data; if (data) { - return self._mapWeatherData(data); + return self._map(data); } return {}; }); return promise; } - return getWeatherData; + return getForecast; }() }, { - key: 'getForecastData', + key: '_map', value: function () { - function getForecastData(args) { + function _map(data) { var self = this; - var endpoint = self.baseApiUrl + 'forecast/daily'; - var params = Object.assign({ - units: self.unit, - APPID: self.apiKey - }, args); - return _axios2['default'].get(endpoint, { - params: params - }).then(function (response) { - var data = response.data; - if (data) { - return self._mapForecastData(data); - } - return {}; - }); - } - - return getForecastData; - }() - }, { - key: '_mapWeatherData', - value: function () { - function _mapWeatherData(data) { + var daysData = data.forecast.forecastday; var mapped = {}; - mapped = { - city: { - name: data.name, - id: data.id, - lng: data.coord.lon, - lat: data.coord.lat - }, - days: [] - }; - mapped.days.push({ - date: _utils2['default'].formatDate(data.dt), - temprature: _utils2['default'].getTemperatureObject(data.main.temp, data.main.temp_min, data.main.temp_max), - weather: _utils2['default'].getWeatherObject(data.weather[0]), - wind: { - speed: data.wind.speed, - degree: data.wind.deg - }, - pressure: data.main.pressure, - humidity: data.main.humidity - }); - return mapped; - } - - return _mapWeatherData; - }() - }, { - key: '_mapForecastData', - value: function () { - function _mapForecastData(data) { - var mapped = {}; - mapped = { - city: { - name: data.city.name, - id: data.city.id, - lng: data.city.coord.lon, - lat: data.city.coord.lat - }, - days: [] - }; - data.list.forEach(function (day) { - mapped.days.push({ - date: _utils2['default'].formatDate(day.dt), - temprature: _utils2['default'].getTemperatureObject(day.temp.day, day.temp.min, day.temp.max), - weather: _utils2['default'].getWeatherObject(day.weather[0]), - wind: { - speed: Math.round(day.speed), - degree: null + mapped.location = data.location; + mapped.days = daysData.map(function (item) { + return { + date: _utils2['default'].formatDate(item.date), + description: item.day.condition.text, + icon: item.day.condition.code, + temperature: { + min: item.day[FIELDS[self.unit].temperature.min].toFixed(0), + max: item.day[FIELDS[self.unit].temperature.max].toFixed(0) }, - pressure: day.pressure, - humidity: day.humidity - }); + wind: item.day[FIELDS[self.unit].wind].toFixed(0), + humidity: item.day.avghumidity + }; }); + if (mapped.days.length > 0) { + mapped.days[0].temperature.current = data.current[FIELDS[self.unit].temperature.current]; + } return mapped; } - return _mapForecastData; + return _map; }() }]); - return OWApi; + return XuApi; }(); - var _default = OWApi; + var _default = XuApi; exports['default'] = _default; ; @@ -416,9 +380,11 @@ return /******/ (function(modules) { // webpackBootstrap return; } - __REACT_HOT_LOADER__.register(OWApi, 'OWApi', '/Users/farahat/work/codelab/react-weather/src/js/OWApi.js'); + __REACT_HOT_LOADER__.register(XuApi, 'XuApi', '/Users/farahat/work/codelab/react-weather/src/js/XuApi.js'); - __REACT_HOT_LOADER__.register(_default, 'default', '/Users/farahat/work/codelab/react-weather/src/js/OWApi.js'); + __REACT_HOT_LOADER__.register(FIELDS, 'FIELDS', '/Users/farahat/work/codelab/react-weather/src/js/XuApi.js'); + + __REACT_HOT_LOADER__.register(_default, 'default', '/Users/farahat/work/codelab/react-weather/src/js/XuApi.js'); }(); ; @@ -4150,28 +4116,38 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = { icons: { - '01d': 'wi-day-sunny', - '01n': 'wi-night-clear', - '02d': 'wi-day-cloudy', - '02n': 'wi-night-alt-cloudy', - '03d': 'wi-cloudy', - '03n': 'wi-cloudy', - '04d': 'wi-cloudy', - '04n': 'wi-cloudy', - '09d': 'wi-day-showers', - '09n': 'wi-night-alt-showers', - '10d': 'wi-day-rain', - '10n': 'wi-night-alt-rain-wind', - '11d': 'wi-day-thunderstorm', - '11n': 'wi-night-alt-thunderstorm', - '13d': 'wi-day-snow-wind', - '13n': 'wi-night-alt-snow', - '50d': 'wi-day-fog', - '50n': 'wi-night-fog' + day: { + '1009': 'wi-cloud', + '1063': 'wi-day-sleet-storm', + '1000': 'wi-day-sunny', + '1003': 'wi-day-cloudy', + '1006': 'wi-cloudy', + '1240': 'wi-day-showers', + '1195': 'wi-day-rain', + '1087': 'wi-day-thunderstorm', + '1225': 'wi-day-snow-wind', + '1135': 'wi-day-fog' + }, + night: { + '1009': 'wi-cloud', + '1063': 'wi-night-alt-sleet-storm', + '1000': 'wi-night-clear', + '1003': 'wi-night-alt-cloudy', + '1006': 'wi-cloudy', + '1240': 'wi-night-alt-showers', + '1195': 'wi-night-alt-rain-wind', + '1087': 'wi-night-alt-thunderstorm', + '1225': 'wi-night-alt-snow', + '1135': 'wi-night-fog' + } }, getIcon: function () { function getIcon(icon) { - var icoClass = this.icons[icon]; + if (!icon) { + return 'na'; + } + var time = 'day'; + var icoClass = this.icons[time][icon]; if (icoClass) { return icoClass; } @@ -4185,12 +4161,12 @@ return /******/ (function(modules) { // webpackBootstrap if (unit === 'metric') { return { temp: 'C', - speed: 'Meter/Sec' + speed: 'kph' }; } else if (unit === 'imperial') { return { temp: 'F', - speed: 'Miles/Hour' + speed: 'mph' }; } return { temp: '', speed: '' }; @@ -4198,46 +4174,15 @@ return /******/ (function(modules) { // webpackBootstrap return getUnits; }(), - toTitleCase: function () { - function toTitleCase(str) { - return str.replace(/\b\w/g, function (txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); - } - - return toTitleCase; - }(), formatDate: function () { - function formatDate(unixStr) { - if (unixStr && _moment2['default'].unix(unixStr).isValid()) { - return _moment2['default'].unix(unixStr).format('ddd D MMM'); + function formatDate(dte) { + if (dte && (0, _moment2['default'])(dte).isValid()) { + return (0, _moment2['default'])(dte).format('ddd D MMM'); } return ''; } return formatDate; - }(), - getWeatherObject: function () { - function getWeatherObject(weather) { - return { - group: weather.main, - description: weather.description, - icon: weather.icon - }; - } - - return getWeatherObject; - }(), - getTemperatureObject: function () { - function getTemperatureObject(current, min, max) { - return { - current: Math.round(current), - min: Math.round(min), - max: Math.round(max) - }; - } - - return getTemperatureObject; }() }; ; @@ -4288,7 +4233,7 @@ return /******/ (function(modules) { // webpackBootstrap var todayData = props.todayData, unit = props.unit; - var todayIcon = _utils2['default'].getIcon(todayData.weather.icon); + var todayIcon = _utils2['default'].getIcon(todayData.icon); var units = _utils2['default'].getUnits(unit); return _react2['default'].createElement( 'div', @@ -4302,7 +4247,16 @@ return /******/ (function(modules) { // webpackBootstrap _react2['default'].createElement( 'div', { className: 'current' }, - todayData.temprature.current, + todayData.temperature.current, + ' ', + units.temp + ), + _react2['default'].createElement( + 'div', + { className: 'range' }, + todayData.temperature.max, + ' / ', + todayData.temperature.min, ' ', units.temp ), @@ -4311,7 +4265,7 @@ return /******/ (function(modules) { // webpackBootstrap { className: 'desc' }, _react2['default'].createElement('i', { className: 'wicon wi ' + todayIcon }), '\xA0', - _utils2['default'].toTitleCase(todayData.weather.description) + todayData.description ), _react2['default'].createElement('div', { className: 'hr' }), _react2['default'].createElement( @@ -4324,7 +4278,7 @@ return /******/ (function(modules) { // webpackBootstrap _react2['default'].createElement( 'b', null, - todayData.wind.speed + todayData.wind ), ' ', units.speed @@ -4418,7 +4372,7 @@ return /******/ (function(modules) { // webpackBootstrap { className: 'rw-box-days' }, daysData.map(function (day, i) { if (i > 0) { - var iconCls = _utils2['default'].getIcon(day.weather.icon); + var iconCls = _utils2['default'].getIcon(day.icon); return _react2['default'].createElement( 'div', { key: 'day-' + i, className: 'rw-day' }, @@ -4430,22 +4384,17 @@ return /******/ (function(modules) { // webpackBootstrap _react2['default'].createElement(_WeatherIcon2['default'], { name: iconCls }), _react2['default'].createElement( 'div', - { className: 'rw-current' }, - day.temprature.current, - ' ', - units.temp + { className: 'rw-desc' }, + day.description ), _react2['default'].createElement( 'div', { className: 'rw-range' }, - day.temprature.min, - ' ', - units.temp, + day.temperature.max, ' / ', - day.temprature.max, + day.temperature.min, ' ', - units.temp, - ' ' + units.temp ) ); } diff --git a/docs/assets/js/demo.js b/docs/assets/js/demo.js index ebd6d4e..3eb56c8 100644 --- a/docs/assets/js/demo.js +++ b/docs/assets/js/demo.js @@ -1,5 +1,5 @@ var ReactWeather = window.ReactWeather.default; -var API_KEY = "7ad07aac9b0943040a4abdd2c23dfc4e" +var API_KEY = "5a9719b325d148eda80141801170606" var rwTodayEl = React.createElement(ReactWeather, { apikey: API_KEY, type: "city", diff --git a/docs/index.html b/docs/index.html index 74293dc..66d92be 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,7 +5,7 @@

React Open Weather

- React open weather is a React Component loading forecast data from Open Weather Map API. + React open weather is a React Component loading forecast data from ApiXu. It also depends on the weather icons library

Features Implemented: diff --git a/package.json b/package.json index 02b8f42..1eef86f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "scripts": { "build": "./node_modules/webpack/bin/webpack.js --config webpack.config.build.js", "start": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --hot --progress --colors --inline --config webpack.config.dev.js", - "test": "mocha --recursive", + "test": "mocha test/*.spec.js --recursive", "tdd": "npm test -- --watch", "lint": "./node_modules/.bin/eslint ./src/js ;exit 0", "coverage": "node_modules/.bin/babel-node node_modules/.bin/babel-istanbul cover node_modules/.bin/_mocha" diff --git a/src/css/components/DaysForecast.scss b/src/css/components/DaysForecast.scss index bc87d38..d06d8c0 100644 --- a/src/css/components/DaysForecast.scss +++ b/src/css/components/DaysForecast.scss @@ -23,13 +23,9 @@ font-weight: bold; } .rw-desc{ - margin-top:20px; + margin:10px 0 10px 0; font-size:12px; } - .rw-current{ - margin-top:10px; - font-size:20px; - } .rw-range{ font-size:11px; } diff --git a/src/css/components/TodayForecast.scss b/src/css/components/TodayForecast.scss index 2a0b973..61df132 100644 --- a/src/css/components/TodayForecast.scss +++ b/src/css/components/TodayForecast.scss @@ -49,7 +49,12 @@ color:$rw-text-secondary-color; } .current{ - font-size:50px; + font-size:45px; + } + .range{ + color:$rw-text-secondary-color; + font-size: 12px; + margin: 0 0 5px 2px; } .desc{ color:$rw-text-secondary-color; diff --git a/src/js/OWApi.js b/src/js/OWApi.js deleted file mode 100644 index 4c4f28e..0000000 --- a/src/js/OWApi.js +++ /dev/null @@ -1,95 +0,0 @@ -import axios from 'axios'; -import utils from './utils'; - -export default class OWApi { - constructor(unit, apiKey) { - this.unit = unit; - this.baseApiUrl = '//api.openweathermap.org/data/2.5/'; - this.apiKey = apiKey; - } - getWeatherData(args) { - const self = this; - const endpoint = `${self.baseApiUrl}weather`; - const params = Object.assign({ - units: self.unit, - APPID: self.apiKey - }, args); - const promise = axios.get(endpoint, { - params - }).then((response) => { - const data = response.data; - if (data) { - return self._mapWeatherData(data); - } - return {}; - }); - return promise; - } - getForecastData(args) { - const self = this; - const endpoint = `${self.baseApiUrl}forecast/daily`; - const params = Object.assign({ - units: self.unit, - APPID: self.apiKey - }, args); - return axios.get(endpoint, { - params - }).then((response) => { - const data = response.data; - if (data) { - return self._mapForecastData(data); - } - return {}; - }); - } - _mapWeatherData(data) { - let mapped = {}; - mapped = { - city: { - name: data.name, - id: data.id, - lng: data.coord.lon, - lat: data.coord.lat - }, - days: [] - }; - mapped.days.push({ - date: utils.formatDate(data.dt), - temprature: utils.getTemperatureObject(data.main.temp, data.main.temp_min, data.main.temp_max), - weather: utils.getWeatherObject(data.weather[0]), - wind: { - speed: data.wind.speed, - degree: data.wind.deg - }, - pressure: data.main.pressure, - humidity: data.main.humidity - }); - return mapped; - } - _mapForecastData(data) { - let mapped = {}; - mapped = { - city: { - name: data.city.name, - id: data.city.id, - lng: data.city.coord.lon, - lat: data.city.coord.lat - }, - days: [] - }; - data.list.forEach((day) => { - mapped.days.push({ - date: utils.formatDate(day.dt), - temprature: utils.getTemperatureObject(day.temp.day, day.temp.min, day.temp.max), - weather: utils.getWeatherObject(day.weather[0]), - wind: { - speed: Math.round(day.speed), - degree: null - }, - pressure: day.pressure, - humidity: day.humidity - }); - }); - return mapped; - } -} diff --git a/src/js/XuApi.js b/src/js/XuApi.js new file mode 100644 index 0000000..77caae3 --- /dev/null +++ b/src/js/XuApi.js @@ -0,0 +1,70 @@ +import axios from 'axios'; +import utils from './utils' + +const FIELDS = { + metric: { + temperature: { + current: 'temp_c', + min: 'mintemp_c', + max: 'maxtemp_c' + }, + wind: 'maxwind_kph' + }, + imperial: { + temperature: { + current: 'temp_f', + min: 'mintemp_f', + max: 'maxtemp_f' + }, + wind: 'maxwind_mph' + } +} + +export default class XuApi { + constructor(unit, apiKey) { + this.unit = unit; + this.apiKey = apiKey; + this.baseApiUrl = '//api.apixu.com/v1/forecast.json'; + } + getForecast(args) { + const self = this; + const endpoint = self.baseApiUrl; + const params = Object.assign({ + key: self.apiKey, + days: 5 + }, args); + const promise = axios.get(endpoint, { + params + }).then((response) => { + const data = response.data; + if (data) { + return self._map(data); + } + return {}; + }); + return promise; + } + _map(data) { + let self = this; + let daysData = data.forecast.forecastday; + let mapped = {} + mapped.location = data.location; + mapped.days = daysData.map((item) => { + return { + date: utils.formatDate(item.date), + description: item.day.condition.text, + icon: item.day.condition.code, + temperature: { + min: item.day[FIELDS[self.unit].temperature.min].toFixed(0), + max: item.day[FIELDS[self.unit].temperature.max].toFixed(0) + }, + wind: item.day[FIELDS[self.unit].wind].toFixed(0), + humidity: item.day.avghumidity + } + }); + if (mapped.days.length > 0) { + mapped.days[0].temperature.current = data.current[FIELDS[self.unit].temperature.current]; + } + return mapped; + } +} \ No newline at end of file diff --git a/src/js/components/DaysForecast.js b/src/js/components/DaysForecast.js index b80cc0d..174ad90 100644 --- a/src/js/components/DaysForecast.js +++ b/src/js/components/DaysForecast.js @@ -18,13 +18,13 @@ const DaysForecast = (props) => { { daysData.map((day, i) => { if (i > 0) { - const iconCls = utils.getIcon(day.weather.icon); + const iconCls = utils.getIcon(day.icon); return (
{day.date}
-
{day.temprature.current} {units.temp}
-
{day.temprature.min} {units.temp} / {day.temprature.max} {units.temp}
+
{day.description}
+
{day.temperature.max} / {day.temperature.min} {units.temp}
); } diff --git a/src/js/components/ReactWeather.js b/src/js/components/ReactWeather.js index 6de59cf..75b32b2 100644 --- a/src/js/components/ReactWeather.js +++ b/src/js/components/ReactWeather.js @@ -1,5 +1,5 @@ import React, { PropTypes } from 'react'; -import OWApi from '../OWApi'; +import XuApi from '../XuApi'; import utils from '../utils'; import TodayForecast from './TodayForecast'; import DaysForecast from './DaysForecast'; @@ -8,7 +8,7 @@ import '../../css/components/ReactWeather.scss'; const propTypes = { unit: PropTypes.oneOf(['metric', 'imperial']), - type: PropTypes.oneOf(['geo', 'city']), + type: PropTypes.oneOf(['geo', 'city', 'auto']), lat: PropTypes.string, lon: PropTypes.string, city: PropTypes.string, @@ -18,14 +18,14 @@ const propTypes = { const defaultProps = { unit: 'metric', - type: 'geo', + type: 'auto', forecast: 'today' }; class ReactWeather extends React.Component { constructor(props) { super(props); - this.api = new OWApi(props.unit, props.apikey); + this.api = new XuApi(props.unit, props.apikey); this.state = { data: null }; @@ -36,12 +36,12 @@ class ReactWeather extends React.Component { if (data) { const days = data.days; const today = days[0]; - const todayIcon = utils.getIcon(today.weather.icon); + const todayIcon = utils.getIcon(today.icon); return (
-

{data.city.name}

+

{data.location.name}

@@ -55,19 +55,14 @@ class ReactWeather extends React.Component { return (
Loading...
); } componentDidMount() { - this.getWeatherData(); + this.getForecastData(); } - getWeatherData() { + getForecastData() { const self = this; const forecast = self.props.forecast; const params = self._getParams(); let promise = null; - if (forecast === 'today') { - promise = self.api.getWeatherData(params); - } else if (forecast === '5days') { - params.cnt = 5; - promise = self.api.getForecastData(params); - } + promise = self.api.getForecast(params); promise.then((data) => { self.setState({ data @@ -79,8 +74,14 @@ class ReactWeather extends React.Component { switch (type) { case 'city': return { q: city }; + case 'geo': + return { + q: `${lat},${lon}` + }; default: - return { lon, lat }; + return { + q: 'auto:ip' + } } } } diff --git a/src/js/components/TodayForecast.js b/src/js/components/TodayForecast.js index 15f572c..95c1089 100644 --- a/src/js/components/TodayForecast.js +++ b/src/js/components/TodayForecast.js @@ -9,20 +9,21 @@ const propTypes = { const TodayForecast = (props) => { const { todayData, unit } = props; - const todayIcon = utils.getIcon(todayData.weather.icon); + const todayIcon = utils.getIcon(todayData.icon); const units = utils.getUnits(unit); return (
{todayData.date}
-
{todayData.temprature.current} {units.temp}
+
{todayData.temperature.current} {units.temp}
+
{todayData.temperature.max} / {todayData.temperature.min} {units.temp}
-  {utils.toTitleCase(todayData.weather.description)} +  {todayData.description}
-
Wind Speed: {todayData.wind.speed} {units.speed}
+
Wind Speed: {todayData.wind} {units.speed}
Humidity: {todayData.humidity} %
diff --git a/src/js/main.js b/src/js/main.js index 0e578e5..d035b98 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,11 +1,11 @@ import React from 'react'; import { render } from 'react-dom'; import ReactWeather from './components/ReactWeather'; - +import XuApi from './XuApi'; render( , diff --git a/src/js/utils.js b/src/js/utils.js index 14195e8..8a4c285 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -2,27 +2,35 @@ import moment from 'moment'; module.exports = { icons: { - '01d': 'wi-day-sunny', - '01n': 'wi-night-clear', - '02d': 'wi-day-cloudy', - '02n': 'wi-night-alt-cloudy', - '03d': 'wi-cloudy', - '03n': 'wi-cloudy', - '04d': 'wi-cloudy', - '04n': 'wi-cloudy', - '09d': 'wi-day-showers', - '09n': 'wi-night-alt-showers', - '10d': 'wi-day-rain', - '10n': 'wi-night-alt-rain-wind', - '11d': 'wi-day-thunderstorm', - '11n': 'wi-night-alt-thunderstorm', - '13d': 'wi-day-snow-wind', - '13n': 'wi-night-alt-snow', - '50d': 'wi-day-fog', - '50n': 'wi-night-fog' + day: { + '1009': 'wi-cloud', + '1063': 'wi-day-sleet-storm', + '1000': 'wi-day-sunny', + '1003': 'wi-day-cloudy', + '1006': 'wi-cloudy', + '1240': 'wi-day-showers', + '1195': 'wi-day-rain', + '1087': 'wi-day-thunderstorm', + '1225': 'wi-day-snow-wind', + '1135': 'wi-day-fog', + }, + night: { + '1009': 'wi-cloud', + '1063': 'wi-night-alt-sleet-storm', + '1000': 'wi-night-clear', + '1003': 'wi-night-alt-cloudy', + '1006': 'wi-cloudy', + '1240': 'wi-night-alt-showers', + '1195': 'wi-night-alt-rain-wind', + '1087': 'wi-night-alt-thunderstorm', + '1225': 'wi-night-alt-snow', + '1135': 'wi-night-fog' + } }, getIcon(icon) { - const icoClass = this.icons[icon]; + if (!icon) { return 'na'; } + let time = 'day'; + const icoClass = this.icons[time][icon]; if (icoClass) { return icoClass; } @@ -32,37 +40,20 @@ module.exports = { if (unit === 'metric') { return { temp: 'C', - speed: 'Meter/Sec' + speed: 'kph' }; } else if (unit === 'imperial') { return { temp: 'F', - speed: 'Miles/Hour' + speed: 'mph' }; } return { temp: '', speed: '' }; }, - toTitleCase(str) { - return str.replace(/\b\w/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()); - }, - formatDate(unixStr) { - if (unixStr && moment.unix(unixStr).isValid()) { - return moment.unix(unixStr).format('ddd D MMM'); + formatDate(dte) { + if (dte && moment(dte).isValid()) { + return moment(dte).format('ddd D MMM'); } return ''; - }, - getWeatherObject(weather) { - return { - group: weather.main, - description: weather.description, - icon: weather.icon - }; - }, - getTemperatureObject(current, min, max) { - return { - current: Math.round(current), - min: Math.round(min), - max: Math.round(max) - }; } }; diff --git a/test/DaysForecast.spec.js b/test/DaysForecast.spec.js index 397584c..51790a9 100644 --- a/test/DaysForecast.spec.js +++ b/test/DaysForecast.spec.js @@ -19,22 +19,22 @@ describe('DaysForecast Component Shallow', () => { it('should render 4 days weather blocks', () => { expect(wrapper.find('.rw-day')).to.have.length(4); }); - it('should render the current temprature and unit for 4 days ahead', () => { - expect(wrapper.find('.rw-current').at(0).text()).to.equal('8 C'); - expect(wrapper.find('.rw-current').at(1).text()).to.equal('14 C'); - expect(wrapper.find('.rw-current').at(2).text()).to.equal('19 C'); - expect(wrapper.find('.rw-current').at(3).text()).to.equal('12 C'); + it('should render the temprature range and unit for 4 days ahead', () => { + expect(wrapper.find('.rw-range').at(0).text()).to.equal('25 / 15 C'); + expect(wrapper.find('.rw-range').at(1).text()).to.equal('22 / 13 C'); + expect(wrapper.find('.rw-range').at(2).text()).to.equal('28 / 15 C'); + expect(wrapper.find('.rw-range').at(3).text()).to.equal('27 / 17 C'); }); it('should render the date for 4 days ahead', () => { - expect(wrapper.find('.rw-date').at(0).text()).to.equal('Sun 23 Apr'); - expect(wrapper.find('.rw-date').at(1).text()).to.equal('Mon 24 Apr'); - expect(wrapper.find('.rw-date').at(2).text()).to.equal('Tue 25 Apr'); - expect(wrapper.find('.rw-date').at(3).text()).to.equal('Wed 26 Apr'); + expect(wrapper.find('.rw-date').at(0).text()).to.equal('Fri 9 Jun'); + expect(wrapper.find('.rw-date').at(1).text()).to.equal('Sat 10 Jun'); + expect(wrapper.find('.rw-date').at(2).text()).to.equal('Sun 11 Jun'); + expect(wrapper.find('.rw-date').at(3).text()).to.equal('Mon 12 Jun'); }); it('should render the icon component for 4 days ahead', () => { - expect(wrapper.find(WeatherIcon).at(0).props().name).to.equal("wi-day-snow-wind"); - expect(wrapper.find(WeatherIcon).at(1).props().name).to.equal("wi-day-sunny"); - expect(wrapper.find(WeatherIcon).at(2).props().name).to.equal("wi-day-cloudy"); - expect(wrapper.find(WeatherIcon).at(3).props().name).to.equal("wi-day-rain"); + expect(wrapper.find(WeatherIcon).at(0).props().name).to.equal("wi-day-cloudy"); + expect(wrapper.find(WeatherIcon).at(1).props().name).to.equal("wi-day-showers"); + expect(wrapper.find(WeatherIcon).at(2).props().name).to.equal("wi-day-sunny"); + expect(wrapper.find(WeatherIcon).at(3).props().name).to.equal("wi-day-sunny"); }); }); \ No newline at end of file diff --git a/test/OWApi.spec.js b/test/OWApi.spec.js deleted file mode 100644 index 5a43812..0000000 --- a/test/OWApi.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import moxios from 'moxios'; -import OWApi from '../src/js/OWApi'; -import { dayData, mappedDayData } from './fixtures/daydata.js'; -import { forecastData, mappedForecastData } from './fixtures/forecastdata.js'; - -describe("Testing API calls", function () { - - beforeEach(function () { - moxios.install() - }); - afterEach(function () { - moxios.uninstall() - }); - - it("should make an api call to weather data", function (done) { - var api = new OWApi("metric", "test"); - var params = { - q: "munich" - } - var fulfilled = spy() - api.getWeatherData(params).then(fulfilled) - moxios.wait(function () { - var request = moxios.requests.mostRecent() - request.respondWith({ - status: 200, - response: dayData - }).then(function (response) { - expect(fulfilled.called).to.equal(true); - expect(response.data).to.equal(dayData); - }).then(done, done) - }); - }); - - it("should make an api call to forecast data", function (done) { - var api = new OWApi("metric", "test"); - var params = { - q: "munich" - } - var fulfilled = spy() - api.getForecastData(params).then(fulfilled) - moxios.wait(function () { - var request = moxios.requests.mostRecent() - request.respondWith({ - status: 200, - response: forecastData - }).then(function (response) { - expect(fulfilled.called).to.equal(true); - expect(response.data).to.equal(forecastData); - }).then(done, done) - }); - }); -}); - -describe("Testing data mapping", function () { - - it("should map weather data", function () { - var api = new OWApi(); - var mapped = api._mapWeatherData(dayData); - expect(mapped).to.deep.equal(mappedDayData); - }); - - it("should map forecast data", function () { - var api = new OWApi(); - var mapped = api._mapForecastData(forecastData); - expect(mapped).to.deep.equal(mappedForecastData); - }); - -}); diff --git a/test/ReactWeather.spec.js b/test/ReactWeather.spec.js index 5eb1ffc..b76e28b 100644 --- a/test/ReactWeather.spec.js +++ b/test/ReactWeather.spec.js @@ -3,7 +3,7 @@ import ReactWeather from '../src/js/components/ReactWeather'; import TodayForecast from '../src/js/components/TodayForecast'; import WeatherIcon from '../src/js/components/WeatherIcon'; import DaysForecast from '../src/js/components/DaysForecast'; -import { dayData, mappedDayData } from './fixtures/daydata.js'; +import { forecastData, mappedForecastData } from './fixtures/forecastdata.js'; describe('ReactWeather Component Shallow', () => { let wrapper; @@ -13,7 +13,7 @@ describe('ReactWeather Component Shallow', () => { type="city" city="Munich" />); - wrapper.setState({ data: mappedDayData }); + wrapper.setState({ data: mappedForecastData }); }); afterEach(function () { @@ -31,7 +31,7 @@ describe('ReactWeather Component Shallow', () => { expect(wrapper.find(DaysForecast)).to.have.length(1); }); it('should render city title', () => { - expect(wrapper.find('.rw-box-left h2').text()).to.equal('Altstadt'); + expect(wrapper.find('.rw-box-left h2').text()).to.equal('Munich'); }); }); @@ -49,6 +49,6 @@ describe('ReactWeather Component Render', () => { const wrapper = mount(); expect(wrapper.props().unit).to.equal("metric"); expect(wrapper.props().forecast).to.equal("today"); - expect(wrapper.props().type).to.equal("geo"); + expect(wrapper.props().type).to.equal("auto"); }); }); \ No newline at end of file diff --git a/test/TodayForecast.spec.js b/test/TodayForecast.spec.js index d6e407b..9e2ff5d 100644 --- a/test/TodayForecast.spec.js +++ b/test/TodayForecast.spec.js @@ -1,5 +1,5 @@ import React from 'react'; -import { dayData, mappedDayData } from './fixtures/daydata.js'; +import { forecastData, mappedForecastData } from './fixtures/forecastdata.js'; import TodayForecast from '../src/js/components/TodayForecast'; describe('TodayForecast Component Shallow', () => { @@ -7,7 +7,7 @@ describe('TodayForecast Component Shallow', () => { beforeEach(function () { wrapper = shallow(); }); afterEach(function () { }); @@ -15,12 +15,9 @@ describe('TodayForecast Component Shallow', () => { expect(wrapper.find('.rw-today')).to.have.length(1); }); it('should render the date', () => { - expect(wrapper.find('.date').text()).to.equal('Sat 22 Apr'); + expect(wrapper.find('.date').text()).to.equal('Thu 8 Jun'); }); it('should render the current temprature and unit', () => { - expect(wrapper.find('.current').text()).to.equal('7 C'); - }); - it('should render the current temprature and unit', () => { - expect(wrapper.find('.current').text()).to.equal('7 C'); + expect(wrapper.find('.current').text()).to.equal('17 C'); }); }); \ No newline at end of file diff --git a/test/XuApi.spec.js b/test/XuApi.spec.js new file mode 100644 index 0000000..eae6e21 --- /dev/null +++ b/test/XuApi.spec.js @@ -0,0 +1,41 @@ +import moxios from 'moxios'; +import XuApi from '../src/js/XuApi'; +import { forecastData, mappedForecastData } from './fixtures/forecastdata.js'; + +describe("Testing API calls", function () { + + beforeEach(function () { + moxios.install() + }); + afterEach(function () { + moxios.uninstall() + }); + + it("should make an api call to weather data", function (done) { + var api = new XuApi("metric", "test"); + var params = { + q: "munich" + } + var fulfilled = spy() + api.getForecast(params).then(fulfilled) + moxios.wait(function () { + var request = moxios.requests.mostRecent() + request.respondWith({ + status: 200, + response: forecastData + }).then(function (response) { + expect(fulfilled.called).to.equal(true); + expect(response.data).to.equal(forecastData); + }).then(done, done) + }); + }); +}); + +describe("Testing data mapping", function () { + + it("should map weather data", function () { + var api = new XuApi("metric", "test"); + var mapped = api._map(forecastData); + expect(mapped).to.deep.equal(mappedForecastData); + }); +}); \ No newline at end of file diff --git a/test/fixtures/forecastdata.js b/test/fixtures/forecastdata.js index b95546c..b2546ba 100644 --- a/test/fixtures/forecastdata.js +++ b/test/fixtures/forecastdata.js @@ -1,227 +1,4349 @@ var forecastData = { - "city": { - "id": 6940463, - "name": "Altstadt", - "coord": { - "lon": 11.5752, - "lat": 48.137 + "location": { + "name": "Munich", + "region": "Bayern", + "country": "Germany", + "lat": 48.15, + "lon": 11.58, + "tz_id": "Europe/Berlin", + "localtime_epoch": 1496915947, + "localtime": "2017-06-08 11:59" + }, + "current": { + "last_updated_epoch": 1496915109, + "last_updated": "2017-06-08 11:45", + "temp_c": 17, + "temp_f": 62.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 }, - "country": "DE", - "population": 0 + "wind_mph": 0, + "wind_kph": 0, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 48, + "cloud": 0, + "feelslike_c": 17, + "feelslike_f": 62.6, + "vis_km": 10, + "vis_miles": 6 }, - "cod": "200", - "message": 0.3061192, - "cnt": 5, - "list": [{ - "dt": 1492858800, - "temp": { - "day": 6.75, - "min": 3.76, - "max": 6.75, - "night": 3.76, - "eve": 5.59, - "morn": 6.75 - }, - "pressure": 963, - "humidity": 85, - "weather": [{ - "id": 501, - "main": "Rain", - "description": "moderate rain", - "icon": "10d" - }], - "speed": 5.21, - "deg": 286, - "clouds": 92, - "rain": 6.14 - }, { - "dt": 1492945200, - "temp": { - "day": 7.52, - "min": -1.57, - "max": 8.82, - "night": -1.57, - "eve": 6.14, - "morn": 2.84 - }, - "pressure": 965.28, - "humidity": 80, - "weather": [{ - "id": 600, - "main": "Snow", - "description": "light snow", - "icon": "13d" - }], - "speed": 3.16, - "deg": 290, - "clouds": 12, - "rain": 0.26, - "snow": 0.19 - }, { - "dt": 1493031600, - "temp": { - "day": 13.87, - "min": 1.35, - "max": 16.03, - "night": 4.94, - "eve": 12.9, - "morn": 1.35 - }, - "pressure": 957.89, - "humidity": 65, - "weather": [{ - "id": 800, - "main": "Clear", - "description": "sky is clear", - "icon": "01d" - }], - "speed": 1.42, - "deg": 237, - "clouds": 0 - }, { - "dt": 1493118000, - "temp": { - "day": 18.51, - "min": 5.88, - "max": 19.48, - "night": 8.95, - "eve": 16.19, - "morn": 5.88 - }, - "pressure": 947.04, - "humidity": 54, - "weather": [{ - "id": 801, - "main": "Clouds", - "description": "few clouds", - "icon": "02d" - }], - "speed": 2.3, - "deg": 132, - "clouds": 12 - }, { - "dt": 1493204400, - "temp": { - "day": 12.35, - "min": 5.56, - "max": 12.35, - "night": 7.18, - "eve": 11.16, - "morn": 5.56 - }, - "pressure": 931.5, - "humidity": 0, - "weather": [{ - "id": 501, - "main": "Rain", - "description": "moderate rain", - "icon": "10d" - }], - "speed": 2.66, - "deg": 253, - "clouds": 68, - "rain": 5.1 - }] + "forecast": { + "forecastday": [ + { + "date": "2017-06-08", + "date_epoch": 1496880000, + "day": { + "maxtemp_c": 25.2, + "maxtemp_f": 77.4, + "mintemp_c": 11.2, + "mintemp_f": 52.2, + "avgtemp_c": 15.6, + "avgtemp_f": 60, + "maxwind_mph": 6.5, + "maxwind_kph": 10.4, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "avgvis_km": 18.8, + "avgvis_miles": 11, + "avghumidity": 54, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + } + }, + "astro": { + "sunrise": "05:14 AM", + "sunset": "09:12 PM", + "moonrise": "07:59 PM", + "moonset": "04:57 AM" + }, + "hour": [ + { + "time_epoch": 1496876400, + "time": "2017-06-08 00:00", + "temp_c": 10.9, + "temp_f": 51.6, + "is_day": 0, + "condition": { + "text": "Partly cloudy", + "icon": "//cdn.apixu.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 220, + "wind_dir": "SW", + "pressure_mb": 1023, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 65, + "cloud": 9, + "feelslike_c": 11.7, + "feelslike_f": 53.1, + "windchill_c": 11.7, + "windchill_f": 53.1, + "heatindex_c": 11.7, + "heatindex_f": 53.1, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.2, + "vis_miles": 11 + }, + { + "time_epoch": 1496880000, + "time": "2017-06-08 01:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.4, + "wind_kph": 8.6, + "wind_degree": 217, + "wind_dir": "SW", + "pressure_mb": 1024, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 69, + "cloud": 0, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 11, + "heatindex_f": 51.8, + "dewpoint_c": 6, + "dewpoint_f": 42.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.4, + "vis_miles": 11 + }, + { + "time_epoch": 1496883600, + "time": "2017-06-08 02:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 212, + "wind_dir": "SSW", + "pressure_mb": 1024, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 71, + "cloud": 0, + "feelslike_c": 10.3, + "feelslike_f": 50.5, + "windchill_c": 10.3, + "windchill_f": 50.5, + "heatindex_c": 10.3, + "heatindex_f": 50.5, + "dewpoint_c": 6, + "dewpoint_f": 42.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.9, + "vis_miles": 11 + }, + { + "time_epoch": 1496887200, + "time": "2017-06-08 03:00", + "temp_c": 8.9, + "temp_f": 48, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 207, + "wind_dir": "SSW", + "pressure_mb": 1024, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 73, + "cloud": 0, + "feelslike_c": 9.7, + "feelslike_f": 49.5, + "windchill_c": 9.7, + "windchill_f": 49.5, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6, + "dewpoint_f": 42.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.5, + "vis_miles": 12 + }, + { + "time_epoch": 1496890800, + "time": "2017-06-08 04:00", + "temp_c": 8.2, + "temp_f": 46.8, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 202, + "wind_dir": "SSW", + "pressure_mb": 1024, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 75, + "cloud": 0, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 9, + "heatindex_f": 48.2, + "dewpoint_c": 6, + "dewpoint_f": 42.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496894400, + "time": "2017-06-08 05:00", + "temp_c": 8.9, + "temp_f": 48, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4, + "wind_kph": 6.5, + "wind_degree": 187, + "wind_dir": "S", + "pressure_mb": 1024, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 74, + "cloud": 0, + "feelslike_c": 9.7, + "feelslike_f": 49.5, + "windchill_c": 9.7, + "windchill_f": 49.5, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6.3, + "dewpoint_f": 43.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496898000, + "time": "2017-06-08 06:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 172, + "wind_dir": "S", + "pressure_mb": 1023, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 73, + "cloud": 0, + "feelslike_c": 10.3, + "feelslike_f": 50.5, + "windchill_c": 10.3, + "windchill_f": 50.5, + "heatindex_c": 10.3, + "heatindex_f": 50.5, + "dewpoint_c": 6.7, + "dewpoint_f": 44.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496901600, + "time": "2017-06-08 07:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 3.4, + "wind_kph": 5.4, + "wind_degree": 157, + "wind_dir": "SSE", + "pressure_mb": 1023, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 72, + "cloud": 0, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 11, + "heatindex_f": 51.8, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496905200, + "time": "2017-06-08 08:00", + "temp_c": 12.2, + "temp_f": 54, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 3.8, + "wind_kph": 6.1, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1023, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 64, + "cloud": 0, + "feelslike_c": 13, + "feelslike_f": 55.4, + "windchill_c": 13, + "windchill_f": 55.4, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 6.7, + "dewpoint_f": 44.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496908800, + "time": "2017-06-08 09:00", + "temp_c": 14.2, + "temp_f": 57.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 124, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 56, + "cloud": 0, + "feelslike_c": 15, + "feelslike_f": 59, + "windchill_c": 15, + "windchill_f": 59, + "heatindex_c": 15, + "heatindex_f": 59, + "dewpoint_c": 6.3, + "dewpoint_f": 43.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496912400, + "time": "2017-06-08 10:00", + "temp_c": 16.2, + "temp_f": 61.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 107, + "wind_dir": "ESE", + "pressure_mb": 1022, + "pressure_in": 30.7, + "precip_mm": 0, + "precip_in": 0, + "humidity": 48, + "cloud": 0, + "feelslike_c": 17, + "feelslike_f": 62.6, + "windchill_c": 17, + "windchill_f": 62.6, + "heatindex_c": 17, + "heatindex_f": 62.6, + "dewpoint_c": 6, + "dewpoint_f": 42.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496916000, + "time": "2017-06-08 11:00", + "temp_c": 17.9, + "temp_f": 64.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 100, + "wind_dir": "E", + "pressure_mb": 1021, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 45, + "cloud": 0, + "feelslike_c": 18.7, + "feelslike_f": 65.7, + "windchill_c": 18.7, + "windchill_f": 65.7, + "heatindex_c": 18.7, + "heatindex_f": 65.7, + "dewpoint_c": 6.3, + "dewpoint_f": 43.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496919600, + "time": "2017-06-08 12:00", + "temp_c": 19.5, + "temp_f": 67.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 92, + "wind_dir": "E", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 42, + "cloud": 0, + "feelslike_c": 20.3, + "feelslike_f": 68.5, + "windchill_c": 20.3, + "windchill_f": 68.5, + "heatindex_c": 20.3, + "heatindex_f": 68.5, + "dewpoint_c": 6.7, + "dewpoint_f": 44.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496923200, + "time": "2017-06-08 13:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 85, + "wind_dir": "E", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 39, + "cloud": 0, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496926800, + "time": "2017-06-08 14:00", + "temp_c": 22.5, + "temp_f": 72.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 79, + "wind_dir": "E", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 36, + "cloud": 0, + "feelslike_c": 23.3, + "feelslike_f": 73.9, + "windchill_c": 23.3, + "windchill_f": 73.9, + "heatindex_c": 23.3, + "heatindex_f": 73.9, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496930400, + "time": "2017-06-08 15:00", + "temp_c": 23.9, + "temp_f": 75, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 74, + "wind_dir": "ENE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 33, + "cloud": 0, + "feelslike_c": 24.7, + "feelslike_f": 76.5, + "windchill_c": 24.7, + "windchill_f": 76.5, + "heatindex_c": 24.7, + "heatindex_f": 76.5, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496934000, + "time": "2017-06-08 16:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 68, + "wind_dir": "ENE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 30, + "cloud": 0, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496937600, + "time": "2017-06-08 17:00", + "temp_c": 23.9, + "temp_f": 75, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4, + "wind_kph": 6.5, + "wind_degree": 78, + "wind_dir": "ENE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 35, + "cloud": 0, + "feelslike_c": 24.7, + "feelslike_f": 76.5, + "windchill_c": 24.7, + "windchill_f": 76.5, + "heatindex_c": 24.7, + "heatindex_f": 76.5, + "dewpoint_c": 8, + "dewpoint_f": 46.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496941200, + "time": "2017-06-08 18:00", + "temp_c": 22.5, + "temp_f": 72.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 88, + "wind_dir": "E", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 40, + "cloud": 0, + "feelslike_c": 23.3, + "feelslike_f": 73.9, + "windchill_c": 23.3, + "windchill_f": 73.9, + "heatindex_c": 23.3, + "heatindex_f": 73.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496944800, + "time": "2017-06-08 19:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 97, + "wind_dir": "E", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 45, + "cloud": 0, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 10, + "dewpoint_f": 50, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496948400, + "time": "2017-06-08 20:00", + "temp_c": 19.9, + "temp_f": 67.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 107, + "wind_dir": "ESE", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 51, + "cloud": 0, + "feelslike_c": 20.4, + "feelslike_f": 68.7, + "windchill_c": 20.4, + "windchill_f": 68.7, + "heatindex_c": 21.1, + "heatindex_f": 70, + "dewpoint_c": 10, + "dewpoint_f": 50, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.7, + "vis_miles": 12 + }, + { + "time_epoch": 1496952000, + "time": "2017-06-08 21:00", + "temp_c": 18.5, + "temp_f": 65.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 117, + "wind_dir": "ESE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 57, + "cloud": 0, + "feelslike_c": 18.8, + "feelslike_f": 65.8, + "windchill_c": 18.8, + "windchill_f": 65.8, + "heatindex_c": 20.1, + "heatindex_f": 68.2, + "dewpoint_c": 10, + "dewpoint_f": 50, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.3, + "vis_miles": 11 + }, + { + "time_epoch": 1496955600, + "time": "2017-06-08 22:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 127, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 63, + "cloud": 0, + "feelslike_c": 17.2, + "feelslike_f": 63, + "windchill_c": 17.2, + "windchill_f": 63, + "heatindex_c": 19.2, + "heatindex_f": 66.6, + "dewpoint_c": 10, + "dewpoint_f": 50, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19, + "vis_miles": 11 + }, + { + "time_epoch": 1496959200, + "time": "2017-06-08 23:00", + "temp_c": 15.9, + "temp_f": 60.6, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 132, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 67, + "cloud": 0, + "feelslike_c": 16.1, + "feelslike_f": 61, + "windchill_c": 16.1, + "windchill_f": 61, + "heatindex_c": 17.5, + "heatindex_f": 63.5, + "dewpoint_c": 9.7, + "dewpoint_f": 49.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19, + "vis_miles": 11 + } + ] + }, + { + "date": "2017-06-09", + "date_epoch": 1496966400, + "day": { + "maxtemp_c": 25.2, + "maxtemp_f": 77.4, + "mintemp_c": 15.2, + "mintemp_f": 59.4, + "avgtemp_c": 18.3, + "avgtemp_f": 65, + "maxwind_mph": 7.4, + "maxwind_kph": 11.9, + "totalprecip_mm": 6.4, + "totalprecip_in": 0.25, + "avgvis_km": 18, + "avgvis_miles": 11, + "avghumidity": 59, + "condition": { + "text": "Partly cloudy", + "icon": "//cdn.apixu.com/weather/64x64/day/116.png", + "code": 1003 + } + }, + "astro": { + "sunrise": "05:14 AM", + "sunset": "09:13 PM", + "moonrise": "08:55 PM", + "moonset": "05:32 AM" + }, + "hour": [ + { + "time_epoch": 1496962800, + "time": "2017-06-09 00:00", + "temp_c": 14.5, + "temp_f": 58.1, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 71, + "cloud": 0, + "feelslike_c": 15.1, + "feelslike_f": 59.2, + "windchill_c": 15.1, + "windchill_f": 59.2, + "heatindex_c": 15.7, + "heatindex_f": 60.3, + "dewpoint_c": 9.3, + "dewpoint_f": 48.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.1, + "vis_miles": 11 + }, + { + "time_epoch": 1496966400, + "time": "2017-06-09 01:00", + "temp_c": 13.2, + "temp_f": 55.8, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 75, + "cloud": 0, + "feelslike_c": 14, + "feelslike_f": 57.2, + "windchill_c": 14, + "windchill_f": 57.2, + "heatindex_c": 14, + "heatindex_f": 57.2, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.1, + "vis_miles": 11 + }, + { + "time_epoch": 1496970000, + "time": "2017-06-09 02:00", + "temp_c": 12.9, + "temp_f": 55.2, + "is_day": 0, + "condition": { + "text": "Cloudy", + "icon": "//cdn.apixu.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 158, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 24, + "feelslike_c": 13.7, + "feelslike_f": 56.7, + "windchill_c": 13.7, + "windchill_f": 56.7, + "heatindex_c": 13.7, + "heatindex_f": 56.7, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.4, + "vis_miles": 12 + }, + { + "time_epoch": 1496973600, + "time": "2017-06-09 03:00", + "temp_c": 12.5, + "temp_f": 54.5, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 172, + "wind_dir": "S", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 78, + "cloud": 48, + "feelslike_c": 13.3, + "feelslike_f": 55.9, + "windchill_c": 13.3, + "windchill_f": 55.9, + "heatindex_c": 13.3, + "heatindex_f": 55.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.6, + "vis_miles": 12 + }, + { + "time_epoch": 1496977200, + "time": "2017-06-09 04:00", + "temp_c": 12.2, + "temp_f": 54, + "is_day": 0, + "condition": { + "text": "Cloudy", + "icon": "//cdn.apixu.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 186, + "wind_dir": "S", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 79, + "cloud": 72, + "feelslike_c": 13, + "feelslike_f": 55.4, + "windchill_c": 13, + "windchill_f": 55.4, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1496980800, + "time": "2017-06-09 05:00", + "temp_c": 12.9, + "temp_f": 55.2, + "is_day": 0, + "condition": { + "text": "Clear", + "icon": "//cdn.apixu.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 199, + "wind_dir": "SSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 78, + "cloud": 48, + "feelslike_c": 13.7, + "feelslike_f": 56.7, + "windchill_c": 13.7, + "windchill_f": 56.7, + "heatindex_c": 13.7, + "heatindex_f": 56.7, + "dewpoint_c": 9.7, + "dewpoint_f": 49.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1496984400, + "time": "2017-06-09 06:00", + "temp_c": 13.5, + "temp_f": 56.3, + "is_day": 1, + "condition": { + "text": "Cloudy", + "icon": "//cdn.apixu.com/weather/64x64/day/119.png", + "code": 1006 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 212, + "wind_dir": "SSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 24, + "feelslike_c": 14.3, + "feelslike_f": 57.7, + "windchill_c": 14.3, + "windchill_f": 57.7, + "heatindex_c": 14.3, + "heatindex_f": 57.7, + "dewpoint_c": 10.3, + "dewpoint_f": 50.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496988000, + "time": "2017-06-09 07:00", + "temp_c": 14.2, + "temp_f": 57.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 226, + "wind_dir": "SW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 75, + "cloud": 0, + "feelslike_c": 15, + "feelslike_f": 59, + "windchill_c": 15, + "windchill_f": 59, + "heatindex_c": 15, + "heatindex_f": 59, + "dewpoint_c": 11, + "dewpoint_f": 51.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1496991600, + "time": "2017-06-09 08:00", + "temp_c": 16.5, + "temp_f": 61.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 237, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 67, + "cloud": 0, + "feelslike_c": 17.3, + "feelslike_f": 63.1, + "windchill_c": 17.3, + "windchill_f": 63.1, + "heatindex_c": 17.3, + "heatindex_f": 63.1, + "dewpoint_c": 11.3, + "dewpoint_f": 52.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1496995200, + "time": "2017-06-09 09:00", + "temp_c": 18.9, + "temp_f": 66, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 249, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 60, + "cloud": 0, + "feelslike_c": 19.7, + "feelslike_f": 67.5, + "windchill_c": 19.7, + "windchill_f": 67.5, + "heatindex_c": 19.7, + "heatindex_f": 67.5, + "dewpoint_c": 11.7, + "dewpoint_f": 53.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.7, + "vis_miles": 12 + }, + { + "time_epoch": 1496998800, + "time": "2017-06-09 10:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.4, + "wind_kph": 8.6, + "wind_degree": 261, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 52, + "cloud": 0, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 12, + "dewpoint_f": 53.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.6, + "vis_miles": 12 + }, + { + "time_epoch": 1497002400, + "time": "2017-06-09 11:00", + "temp_c": 22.2, + "temp_f": 72, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 272, + "wind_dir": "W", + "pressure_mb": 1017, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 51, + "cloud": 0, + "feelslike_c": 23, + "feelslike_f": 73.4, + "windchill_c": 23, + "windchill_f": 73.4, + "heatindex_c": 23, + "heatindex_f": 73.4, + "dewpoint_c": 12.3, + "dewpoint_f": 54.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.2, + "vis_miles": 11 + }, + { + "time_epoch": 1497006000, + "time": "2017-06-09 12:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 49, + "cloud": 0, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 12.7, + "dewpoint_f": 54.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.9, + "vis_miles": 11 + }, + { + "time_epoch": 1497009600, + "time": "2017-06-09 13:00", + "temp_c": 24.2, + "temp_f": 75.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 294, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 0, + "precip_in": 0, + "humidity": 48, + "cloud": 0, + "feelslike_c": 25, + "feelslike_f": 77, + "windchill_c": 25, + "windchill_f": 77, + "heatindex_c": 25, + "heatindex_f": 77, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.5, + "vis_miles": 11 + }, + { + "time_epoch": 1497013200, + "time": "2017-06-09 14:00", + "temp_c": 24.9, + "temp_f": 76.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 302, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 30.4, + "precip_mm": 0, + "precip_in": 0, + "humidity": 46, + "cloud": 0, + "feelslike_c": 25.7, + "feelslike_f": 78.3, + "windchill_c": 25.7, + "windchill_f": 78.3, + "heatindex_c": 25.7, + "heatindex_f": 78.3, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.4, + "vis_miles": 11 + }, + { + "time_epoch": 1497016800, + "time": "2017-06-09 15:00", + "temp_c": 25.5, + "temp_f": 77.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 309, + "wind_dir": "NW", + "pressure_mb": 1011, + "pressure_in": 30.3, + "precip_mm": 0, + "precip_in": 0, + "humidity": 44, + "cloud": 0, + "feelslike_c": 26.3, + "feelslike_f": 79.3, + "windchill_c": 26.3, + "windchill_f": 79.3, + "heatindex_c": 26.3, + "heatindex_f": 79.3, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.4, + "vis_miles": 11 + }, + { + "time_epoch": 1497020400, + "time": "2017-06-09 16:00", + "temp_c": 26.2, + "temp_f": 79.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 316, + "wind_dir": "NW", + "pressure_mb": 1009, + "pressure_in": 30.3, + "precip_mm": 0, + "precip_in": 0, + "humidity": 42, + "cloud": 0, + "feelslike_c": 27, + "feelslike_f": 80.6, + "windchill_c": 27, + "windchill_f": 80.6, + "heatindex_c": 27, + "heatindex_f": 80.6, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.3, + "vis_miles": 11 + }, + { + "time_epoch": 1497024000, + "time": "2017-06-09 17:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 328, + "wind_dir": "NNW", + "pressure_mb": 1012, + "pressure_in": 30.4, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 45, + "cloud": 8, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.8, + "vis_miles": 11 + }, + { + "time_epoch": 1497027600, + "time": "2017-06-09 18:00", + "temp_c": 24.2, + "temp_f": 75.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 341, + "wind_dir": "NNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 49, + "cloud": 16, + "feelslike_c": 25, + "feelslike_f": 77, + "windchill_c": 25, + "windchill_f": 77, + "heatindex_c": 25, + "heatindex_f": 77, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.3, + "vis_miles": 10 + }, + { + "time_epoch": 1497031200, + "time": "2017-06-09 19:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 3.8, + "wind_kph": 6.1, + "wind_degree": 353, + "wind_dir": "N", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 52, + "cloud": 23, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 16.8, + "vis_miles": 10 + }, + { + "time_epoch": 1497034800, + "time": "2017-06-09 20:00", + "temp_c": 21.9, + "temp_f": 71.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 3.1, + "wind_kph": 5, + "wind_degree": 295, + "wind_dir": "WNW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 57, + "cloud": 45, + "feelslike_c": 22.7, + "feelslike_f": 72.9, + "windchill_c": 22.7, + "windchill_f": 72.9, + "heatindex_c": 22.7, + "heatindex_f": 72.9, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 16.5, + "vis_miles": 10 + }, + { + "time_epoch": 1497038400, + "time": "2017-06-09 21:00", + "temp_c": 20.5, + "temp_f": 68.9, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 2.7, + "wind_kph": 4.3, + "wind_degree": 237, + "wind_dir": "WSW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 61, + "cloud": 67, + "feelslike_c": 21.3, + "feelslike_f": 70.3, + "windchill_c": 21.3, + "windchill_f": 70.3, + "heatindex_c": 21.3, + "heatindex_f": 70.3, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.1, + "vis_miles": 10 + }, + { + "time_epoch": 1497042000, + "time": "2017-06-09 22:00", + "temp_c": 19.2, + "temp_f": 66.6, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2, + "wind_kph": 3.2, + "wind_degree": 178, + "wind_dir": "S", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 66, + "cloud": 89, + "feelslike_c": 20, + "feelslike_f": 68, + "windchill_c": 20, + "windchill_f": 68, + "heatindex_c": 20, + "heatindex_f": 68, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.8, + "vis_miles": 9 + }, + { + "time_epoch": 1497045600, + "time": "2017-06-09 23:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2, + "wind_kph": 3.2, + "wind_degree": 192, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 70, + "cloud": 90, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 13.3, + "dewpoint_f": 55.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.9, + "vis_miles": 9 + } + ] + }, + { + "date": "2017-06-10", + "date_epoch": 1497052800, + "day": { + "maxtemp_c": 22.2, + "maxtemp_f": 72, + "mintemp_c": 13.2, + "mintemp_f": 55.8, + "avgtemp_c": 18, + "avgtemp_f": 64.3, + "maxwind_mph": 6.9, + "maxwind_kph": 11.2, + "totalprecip_mm": 1.7, + "totalprecip_in": 0.07, + "avgvis_km": 17.4, + "avgvis_miles": 10, + "avghumidity": 68, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + } + }, + "astro": { + "sunrise": "05:14 AM", + "sunset": "09:13 PM", + "moonrise": "09:47 PM", + "moonset": "06:12 AM" + }, + "hour": [ + { + "time_epoch": 1497049200, + "time": "2017-06-10 00:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2.2, + "wind_kph": 3.6, + "wind_degree": 205, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 75, + "cloud": 92, + "feelslike_c": 18, + "feelslike_f": 64.4, + "windchill_c": 18, + "windchill_f": 64.4, + "heatindex_c": 18, + "heatindex_f": 64.4, + "dewpoint_c": 13.7, + "dewpoint_f": 56.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.9, + "vis_miles": 9 + }, + { + "time_epoch": 1497052800, + "time": "2017-06-10 01:00", + "temp_c": 16.2, + "temp_f": 61.2, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2.2, + "wind_kph": 3.6, + "wind_degree": 218, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 79, + "cloud": 93, + "feelslike_c": 17, + "feelslike_f": 62.6, + "windchill_c": 17, + "windchill_f": 62.6, + "heatindex_c": 17, + "heatindex_f": 62.6, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16, + "vis_miles": 9 + }, + { + "time_epoch": 1497056400, + "time": "2017-06-10 02:00", + "temp_c": 15.9, + "temp_f": 60.6, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2.5, + "wind_kph": 4, + "wind_degree": 221, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 81, + "cloud": 91, + "feelslike_c": 16.7, + "feelslike_f": 62.1, + "windchill_c": 16.7, + "windchill_f": 62.1, + "heatindex_c": 16.7, + "heatindex_f": 62.1, + "dewpoint_c": 13.7, + "dewpoint_f": 56.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.5, + "vis_miles": 9 + }, + { + "time_epoch": 1497060000, + "time": "2017-06-10 03:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2.7, + "wind_kph": 4.3, + "wind_degree": 224, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 83, + "cloud": 89, + "feelslike_c": 16.3, + "feelslike_f": 61.3, + "windchill_c": 16.3, + "windchill_f": 61.3, + "heatindex_c": 16.3, + "heatindex_f": 61.3, + "dewpoint_c": 13.3, + "dewpoint_f": 55.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 14.9, + "vis_miles": 9 + }, + { + "time_epoch": 1497063600, + "time": "2017-06-10 04:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 228, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 85, + "cloud": 86, + "feelslike_c": 16, + "feelslike_f": 60.8, + "windchill_c": 16, + "windchill_f": 60.8, + "heatindex_c": 16, + "heatindex_f": 60.8, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 14.4, + "vis_miles": 8 + }, + { + "time_epoch": 1497067200, + "time": "2017-06-10 05:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/night/266.png", + "code": 1153 + }, + "wind_mph": 3.4, + "wind_kph": 5.4, + "wind_degree": 226, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 84, + "cloud": 84, + "feelslike_c": 16.3, + "feelslike_f": 61.3, + "windchill_c": 16.3, + "windchill_f": 61.3, + "heatindex_c": 16.3, + "heatindex_f": 61.3, + "dewpoint_c": 13.3, + "dewpoint_f": 55.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 14.7, + "vis_miles": 9 + }, + { + "time_epoch": 1497070800, + "time": "2017-06-10 06:00", + "temp_c": 15.9, + "temp_f": 60.6, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 4, + "wind_kph": 6.5, + "wind_degree": 225, + "wind_dir": "SW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 84, + "cloud": 81, + "feelslike_c": 16.7, + "feelslike_f": 62.1, + "windchill_c": 16.7, + "windchill_f": 62.1, + "heatindex_c": 16.7, + "heatindex_f": 62.1, + "dewpoint_c": 13.7, + "dewpoint_f": 56.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.1, + "vis_miles": 9 + }, + { + "time_epoch": 1497074400, + "time": "2017-06-10 07:00", + "temp_c": 16.2, + "temp_f": 61.2, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 223, + "wind_dir": "SW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 83, + "cloud": 78, + "feelslike_c": 17, + "feelslike_f": 62.6, + "windchill_c": 17, + "windchill_f": 62.6, + "heatindex_c": 17, + "heatindex_f": 62.6, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.4, + "vis_miles": 9 + }, + { + "time_epoch": 1497078000, + "time": "2017-06-10 08:00", + "temp_c": 17.9, + "temp_f": 64.2, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 235, + "wind_dir": "SW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 75, + "cloud": 60, + "feelslike_c": 18.7, + "feelslike_f": 65.7, + "windchill_c": 18.7, + "windchill_f": 65.7, + "heatindex_c": 18.7, + "heatindex_f": 65.7, + "dewpoint_c": 13.7, + "dewpoint_f": 56.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.2, + "vis_miles": 10 + }, + { + "time_epoch": 1497081600, + "time": "2017-06-10 09:00", + "temp_c": 19.5, + "temp_f": 67.1, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 247, + "wind_dir": "WSW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 68, + "cloud": 43, + "feelslike_c": 20.3, + "feelslike_f": 68.5, + "windchill_c": 20.3, + "windchill_f": 68.5, + "heatindex_c": 20.3, + "heatindex_f": 68.5, + "dewpoint_c": 13.3, + "dewpoint_f": 55.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17, + "vis_miles": 10 + }, + { + "time_epoch": 1497085200, + "time": "2017-06-10 10:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 260, + "wind_dir": "W", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 60, + "cloud": 26, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.8, + "vis_miles": 11 + }, + { + "time_epoch": 1497088800, + "time": "2017-06-10 11:00", + "temp_c": 21.9, + "temp_f": 71.4, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 270, + "wind_dir": "W", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 55, + "cloud": 32, + "feelslike_c": 22.7, + "feelslike_f": 72.9, + "windchill_c": 22.7, + "windchill_f": 72.9, + "heatindex_c": 22.7, + "heatindex_f": 72.9, + "dewpoint_c": 12.7, + "dewpoint_f": 54.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.6, + "vis_miles": 10 + }, + { + "time_epoch": 1497092400, + "time": "2017-06-10 12:00", + "temp_c": 22.5, + "temp_f": 72.5, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.3, + "wind_kph": 10.1, + "wind_degree": 280, + "wind_dir": "W", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 50, + "cloud": 39, + "feelslike_c": 23.3, + "feelslike_f": 73.9, + "windchill_c": 23.3, + "windchill_f": 73.9, + "heatindex_c": 23.3, + "heatindex_f": 73.9, + "dewpoint_c": 12.3, + "dewpoint_f": 54.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.3, + "vis_miles": 10 + }, + { + "time_epoch": 1497096000, + "time": "2017-06-10 13:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 291, + "wind_dir": "WNW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 45, + "cloud": 45, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 12, + "dewpoint_f": 53.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.1, + "vis_miles": 10 + }, + { + "time_epoch": 1497099600, + "time": "2017-06-10 14:00", + "temp_c": 23.9, + "temp_f": 75, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 294, + "wind_dir": "WNW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 45, + "cloud": 44, + "feelslike_c": 24.7, + "feelslike_f": 76.5, + "windchill_c": 24.7, + "windchill_f": 76.5, + "heatindex_c": 24.7, + "heatindex_f": 76.5, + "dewpoint_c": 12.3, + "dewpoint_f": 54.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.7, + "vis_miles": 10 + }, + { + "time_epoch": 1497103200, + "time": "2017-06-10 15:00", + "temp_c": 24.5, + "temp_f": 76.1, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 298, + "wind_dir": "WNW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0.7, + "precip_in": 0.03, + "humidity": 44, + "cloud": 43, + "feelslike_c": 25.3, + "feelslike_f": 77.5, + "windchill_c": 25.3, + "windchill_f": 77.5, + "heatindex_c": 25.3, + "heatindex_f": 77.5, + "dewpoint_c": 12.7, + "dewpoint_f": 54.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.3, + "vis_miles": 10 + }, + { + "time_epoch": 1497106800, + "time": "2017-06-10 16:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.5, + "wind_kph": 10.4, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1017, + "pressure_in": 30.5, + "precip_mm": 0.8, + "precip_in": 0.03, + "humidity": 44, + "cloud": 42, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 13, + "dewpoint_f": 55.4, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.9, + "vis_miles": 9 + }, + { + "time_epoch": 1497110400, + "time": "2017-06-10 17:00", + "temp_c": 24.9, + "temp_f": 76.8, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.4, + "wind_kph": 8.6, + "wind_degree": 304, + "wind_dir": "NW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 1, + "precip_in": 0.04, + "humidity": 47, + "cloud": 40, + "feelslike_c": 25.7, + "feelslike_f": 78.3, + "windchill_c": 25.7, + "windchill_f": 78.3, + "heatindex_c": 25.7, + "heatindex_f": 78.3, + "dewpoint_c": 13.3, + "dewpoint_f": 55.9, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.6, + "vis_miles": 9 + }, + { + "time_epoch": 1497114000, + "time": "2017-06-10 18:00", + "temp_c": 24.5, + "temp_f": 76.1, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 306, + "wind_dir": "NW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 1.3, + "precip_in": 0.05, + "humidity": 50, + "cloud": 38, + "feelslike_c": 25.3, + "feelslike_f": 77.5, + "windchill_c": 25.3, + "windchill_f": 77.5, + "heatindex_c": 25.3, + "heatindex_f": 77.5, + "dewpoint_c": 13.7, + "dewpoint_f": 56.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.3, + "vis_miles": 9 + }, + { + "time_epoch": 1497117600, + "time": "2017-06-10 19:00", + "temp_c": 24.2, + "temp_f": 75.6, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 3.1, + "wind_kph": 5, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 1.5, + "precip_in": 0.06, + "humidity": 53, + "cloud": 36, + "feelslike_c": 25, + "feelslike_f": 77, + "windchill_c": 25, + "windchill_f": 77, + "heatindex_c": 25, + "heatindex_f": 77, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 15, + "vis_miles": 9 + }, + { + "time_epoch": 1497121200, + "time": "2017-06-10 20:00", + "temp_c": 22.9, + "temp_f": 73.2, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 3.8, + "wind_kph": 6.1, + "wind_degree": 272, + "wind_dir": "W", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 1.1, + "precip_in": 0.04, + "humidity": 58, + "cloud": 41, + "feelslike_c": 23.7, + "feelslike_f": 74.7, + "windchill_c": 23.7, + "windchill_f": 74.7, + "heatindex_c": 23.7, + "heatindex_f": 74.7, + "dewpoint_c": 14.3, + "dewpoint_f": 57.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 15.9, + "vis_miles": 9 + }, + { + "time_epoch": 1497124800, + "time": "2017-06-10 21:00", + "temp_c": 21.5, + "temp_f": 70.7, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 236, + "wind_dir": "WSW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.6, + "precip_in": 0.02, + "humidity": 64, + "cloud": 46, + "feelslike_c": 22.3, + "feelslike_f": 72.1, + "windchill_c": 22.3, + "windchill_f": 72.1, + "heatindex_c": 22.3, + "heatindex_f": 72.1, + "dewpoint_c": 14.7, + "dewpoint_f": 58.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.8, + "vis_miles": 10 + }, + { + "time_epoch": 1497128400, + "time": "2017-06-10 22:00", + "temp_c": 20.2, + "temp_f": 68.4, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 201, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.6, + "precip_mm": 0.2, + "precip_in": 0.01, + "humidity": 69, + "cloud": 51, + "feelslike_c": 21, + "feelslike_f": 69.8, + "windchill_c": 21, + "windchill_f": 69.8, + "heatindex_c": 21, + "heatindex_f": 69.8, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.7, + "vis_miles": 10 + }, + { + "time_epoch": 1497132000, + "time": "2017-06-10 23:00", + "temp_c": 19.2, + "temp_f": 66.6, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 211, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 72, + "cloud": 40, + "feelslike_c": 20, + "feelslike_f": 68, + "windchill_c": 20, + "windchill_f": 68, + "heatindex_c": 20, + "heatindex_f": 68, + "dewpoint_c": 14.7, + "dewpoint_f": 58.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.6, + "vis_miles": 10 + } + ] + }, + { + "date": "2017-06-11", + "date_epoch": 1497139200, + "day": { + "maxtemp_c": 28.2, + "maxtemp_f": 82.8, + "mintemp_c": 15.2, + "mintemp_f": 59.4, + "avgtemp_c": 20.5, + "avgtemp_f": 68.8, + "maxwind_mph": 8.5, + "maxwind_kph": 13.7, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "avgvis_km": 20, + "avgvis_miles": 12, + "avghumidity": 63, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + } + }, + "astro": { + "sunrise": "05:14 AM", + "sunset": "09:14 PM", + "moonrise": "10:34 PM", + "moonset": "06:58 AM" + }, + "hour": [ + { + "time_epoch": 1497135600, + "time": "2017-06-11 00:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 3.1, + "wind_kph": 5, + "wind_degree": 222, + "wind_dir": "SW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 75, + "cloud": 29, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 14.3, + "dewpoint_f": 57.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.4, + "vis_miles": 10 + }, + { + "time_epoch": 1497139200, + "time": "2017-06-11 01:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 2.2, + "wind_kph": 3.6, + "wind_degree": 232, + "wind_dir": "SW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 78, + "cloud": 19, + "feelslike_c": 18, + "feelslike_f": 64.4, + "windchill_c": 18, + "windchill_f": 64.4, + "heatindex_c": 18, + "heatindex_f": 64.4, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 17.3, + "vis_miles": 10 + }, + { + "time_epoch": 1497142800, + "time": "2017-06-11 02:00", + "temp_c": 16.9, + "temp_f": 62.4, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 2.2, + "wind_kph": 3.6, + "wind_degree": 235, + "wind_dir": "SW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 79, + "cloud": 22, + "feelslike_c": 17.7, + "feelslike_f": 63.9, + "windchill_c": 17.7, + "windchill_f": 63.9, + "heatindex_c": 17.7, + "heatindex_f": 63.9, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18.2, + "vis_miles": 11 + }, + { + "time_epoch": 1497146400, + "time": "2017-06-11 03:00", + "temp_c": 16.5, + "temp_f": 61.7, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 2, + "wind_kph": 3.2, + "wind_degree": 237, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 80, + "cloud": 25, + "feelslike_c": 17.3, + "feelslike_f": 63.1, + "windchill_c": 17.3, + "windchill_f": 63.1, + "heatindex_c": 17.3, + "heatindex_f": 63.1, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.1, + "vis_miles": 11 + }, + { + "time_epoch": 1497150000, + "time": "2017-06-11 04:00", + "temp_c": 16.2, + "temp_f": 61.2, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 2, + "wind_kph": 3.2, + "wind_degree": 240, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 81, + "cloud": 29, + "feelslike_c": 17, + "feelslike_f": 62.6, + "windchill_c": 17, + "windchill_f": 62.6, + "heatindex_c": 17, + "heatindex_f": 62.6, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497153600, + "time": "2017-06-11 05:00", + "temp_c": 16.5, + "temp_f": 61.7, + "is_day": 0, + "condition": { + "text": "Partly cloudy", + "icon": "//cdn.apixu.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 3.1, + "wind_kph": 5, + "wind_degree": 247, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 80, + "cloud": 28, + "feelslike_c": 17.3, + "feelslike_f": 63.1, + "windchill_c": 17.3, + "windchill_f": 63.1, + "heatindex_c": 17.3, + "heatindex_f": 63.1, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497157200, + "time": "2017-06-11 06:00", + "temp_c": 16.9, + "temp_f": 62.4, + "is_day": 1, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/day/143.png", + "code": 1030 + }, + "wind_mph": 4, + "wind_kph": 6.5, + "wind_degree": 255, + "wind_dir": "WSW", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 80, + "cloud": 27, + "feelslike_c": 17.7, + "feelslike_f": 63.9, + "windchill_c": 17.7, + "windchill_f": 63.9, + "heatindex_c": 17.7, + "heatindex_f": 63.9, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1497160800, + "time": "2017-06-11 07:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 1, + "condition": { + "text": "Partly cloudy", + "icon": "//cdn.apixu.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 263, + "wind_dir": "W", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 79, + "cloud": 26, + "feelslike_c": 18, + "feelslike_f": 64.4, + "windchill_c": 18, + "windchill_f": 64.4, + "heatindex_c": 18, + "heatindex_f": 64.4, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1497164400, + "time": "2017-06-11 08:00", + "temp_c": 19.2, + "temp_f": 66.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.5, + "wind_kph": 7.2, + "wind_degree": 267, + "wind_dir": "W", + "pressure_mb": 1019, + "pressure_in": 30.6, + "precip_mm": 0, + "precip_in": 0, + "humidity": 71, + "cloud": 17, + "feelslike_c": 20, + "feelslike_f": 68, + "windchill_c": 20, + "windchill_f": 68, + "heatindex_c": 20, + "heatindex_f": 68, + "dewpoint_c": 14.3, + "dewpoint_f": 57.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1497168000, + "time": "2017-06-11 09:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 1, + "condition": { + "text": "Partly cloudy", + "icon": "//cdn.apixu.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 272, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 63, + "cloud": 9, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 14.7, + "dewpoint_f": 58.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497171600, + "time": "2017-06-11 10:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 277, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 55, + "cloud": 0, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497175200, + "time": "2017-06-11 11:00", + "temp_c": 24.2, + "temp_f": 75.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 280, + "wind_dir": "W", + "pressure_mb": 1017, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 52, + "cloud": 0, + "feelslike_c": 25, + "feelslike_f": 77, + "windchill_c": 25, + "windchill_f": 77, + "heatindex_c": 25, + "heatindex_f": 77, + "dewpoint_c": 14.7, + "dewpoint_f": 58.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.7, + "vis_miles": 12 + }, + { + "time_epoch": 1497178800, + "time": "2017-06-11 12:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 284, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 49, + "cloud": 0, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 14.3, + "dewpoint_f": 57.7, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.5, + "vis_miles": 12 + }, + { + "time_epoch": 1497182400, + "time": "2017-06-11 13:00", + "temp_c": 26.2, + "temp_f": 79.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 287, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 46, + "cloud": 0, + "feelslike_c": 27, + "feelslike_f": 80.6, + "windchill_c": 27, + "windchill_f": 80.6, + "heatindex_c": 27, + "heatindex_f": 80.6, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.2, + "vis_miles": 11 + }, + { + "time_epoch": 1497186000, + "time": "2017-06-11 14:00", + "temp_c": 26.9, + "temp_f": 80.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 289, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 44, + "cloud": 0, + "feelslike_c": 27.7, + "feelslike_f": 81.9, + "windchill_c": 27.7, + "windchill_f": 81.9, + "heatindex_c": 27.7, + "heatindex_f": 81.9, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.4, + "vis_miles": 12 + }, + { + "time_epoch": 1497189600, + "time": "2017-06-11 15:00", + "temp_c": 27.5, + "temp_f": 81.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 292, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 41, + "cloud": 0, + "feelslike_c": 28.3, + "feelslike_f": 82.9, + "windchill_c": 28.3, + "windchill_f": 82.9, + "heatindex_c": 28.3, + "heatindex_f": 82.9, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.7, + "vis_miles": 12 + }, + { + "time_epoch": 1497193200, + "time": "2017-06-11 16:00", + "temp_c": 28.2, + "temp_f": 82.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 294, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 39, + "cloud": 0, + "feelslike_c": 29, + "feelslike_f": 84.2, + "windchill_c": 29, + "windchill_f": 84.2, + "heatindex_c": 29, + "heatindex_f": 84.2, + "dewpoint_c": 14, + "dewpoint_f": 57.2, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1497196800, + "time": "2017-06-11 17:00", + "temp_c": 27.9, + "temp_f": 82.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 6.3, + "wind_kph": 10.1, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 41, + "cloud": 0, + "feelslike_c": 28.7, + "feelslike_f": 83.7, + "windchill_c": 28.7, + "windchill_f": 83.7, + "heatindex_c": 28.7, + "heatindex_f": 83.7, + "dewpoint_c": 14.7, + "dewpoint_f": 58.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 19.9, + "vis_miles": 12 + }, + { + "time_epoch": 1497200400, + "time": "2017-06-11 18:00", + "temp_c": 27.5, + "temp_f": 81.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 44, + "cloud": 0, + "feelslike_c": 28.3, + "feelslike_f": 82.9, + "windchill_c": 28.3, + "windchill_f": 82.9, + "heatindex_c": 28.3, + "heatindex_f": 82.9, + "dewpoint_c": 15.3, + "dewpoint_f": 59.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497204000, + "time": "2017-06-11 19:00", + "temp_c": 27.2, + "temp_f": 81, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 315, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 46, + "cloud": 0, + "feelslike_c": 28, + "feelslike_f": 82.4, + "windchill_c": 28, + "windchill_f": 82.4, + "heatindex_c": 28, + "heatindex_f": 82.4, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497207600, + "time": "2017-06-11 20:00", + "temp_c": 25.9, + "temp_f": 78.6, + "is_day": 1, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/day/143.png", + "code": 1030 + }, + "wind_mph": 6.5, + "wind_kph": 10.4, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 26.7, + "feelslike_f": 80.1, + "windchill_c": 26.7, + "windchill_f": 80.1, + "heatindex_c": 26.7, + "heatindex_f": 80.1, + "dewpoint_c": 16.3, + "dewpoint_f": 61.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497211200, + "time": "2017-06-11 21:00", + "temp_c": 24.5, + "temp_f": 76.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 288, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 59, + "cloud": 45, + "feelslike_c": 25.3, + "feelslike_f": 77.5, + "windchill_c": 25.3, + "windchill_f": 77.5, + "heatindex_c": 25.3, + "heatindex_f": 77.5, + "dewpoint_c": 16.7, + "dewpoint_f": 62.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497214800, + "time": "2017-06-11 22:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 275, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 65, + "cloud": 67, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 17, + "dewpoint_f": 62.6, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497218400, + "time": "2017-06-11 23:00", + "temp_c": 22.2, + "temp_f": 72, + "is_day": 0, + "condition": { + "text": "Fog", + "icon": "//cdn.apixu.com/weather/64x64/night/248.png", + "code": 1135 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 268, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0, + "precip_in": 0, + "humidity": 69, + "cloud": 78, + "feelslike_c": 23, + "feelslike_f": 73.4, + "windchill_c": 23, + "windchill_f": 73.4, + "heatindex_c": 23, + "heatindex_f": 73.4, + "dewpoint_c": 16.7, + "dewpoint_f": 62.1, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + } + ] + }, + { + "date": "2017-06-12", + "date_epoch": 1497225600, + "day": { + "maxtemp_c": 27.2, + "maxtemp_f": 81, + "mintemp_c": 17.2, + "mintemp_f": 63, + "avgtemp_c": 21.5, + "avgtemp_f": 70.6, + "maxwind_mph": 9.4, + "maxwind_kph": 15.1, + "totalprecip_mm": 4.3, + "totalprecip_in": 0.17, + "avgvis_km": 16.7, + "avgvis_miles": 10, + "avghumidity": 64, + "condition": { + "text": "Sunny", + "icon": "//cdn.apixu.com/weather/64x64/day/113.png", + "code": 1000 + } + }, + "astro": { + "sunrise": "05:13 AM", + "sunset": "09:14 PM", + "moonrise": "11:16 PM", + "moonset": "07:49 AM" + }, + "hour": [ + { + "time_epoch": 1497222000, + "time": "2017-06-12 00:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 260, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 74, + "cloud": 89, + "feelslike_c": 22, + "feelslike_f": 71.6, + "windchill_c": 22, + "windchill_f": 71.6, + "heatindex_c": 22, + "heatindex_f": 71.6, + "dewpoint_c": 16.3, + "dewpoint_f": 61.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497225600, + "time": "2017-06-12 01:00", + "temp_c": 20.2, + "temp_f": 68.4, + "is_day": 0, + "condition": { + "text": "Fog", + "icon": "//cdn.apixu.com/weather/64x64/night/248.png", + "code": 1135 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 253, + "wind_dir": "WSW", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 78, + "cloud": 100, + "feelslike_c": 21, + "feelslike_f": 69.8, + "windchill_c": 21, + "windchill_f": 69.8, + "heatindex_c": 21, + "heatindex_f": 69.8, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 20, + "vis_miles": 12 + }, + { + "time_epoch": 1497229200, + "time": "2017-06-12 02:00", + "temp_c": 19.5, + "temp_f": 67.1, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 260, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 80, + "cloud": 100, + "feelslike_c": 20.3, + "feelslike_f": 68.5, + "windchill_c": 20.3, + "windchill_f": 68.5, + "heatindex_c": 20.3, + "heatindex_f": 68.5, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 18, + "vis_miles": 11 + }, + { + "time_epoch": 1497232800, + "time": "2017-06-12 03:00", + "temp_c": 18.9, + "temp_f": 66, + "is_day": 0, + "condition": { + "text": "Fog", + "icon": "//cdn.apixu.com/weather/64x64/night/248.png", + "code": 1135 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 268, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 81, + "cloud": 100, + "feelslike_c": 19.7, + "feelslike_f": 67.5, + "windchill_c": 19.7, + "windchill_f": 67.5, + "heatindex_c": 19.7, + "heatindex_f": 67.5, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 16.1, + "vis_miles": 10 + }, + { + "time_epoch": 1497236400, + "time": "2017-06-12 04:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 0, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/night/143.png", + "code": 1030 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 275, + "wind_dir": "W", + "pressure_mb": 1015, + "pressure_in": 30.5, + "precip_mm": 0.1, + "precip_in": 0, + "humidity": 83, + "cloud": 100, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 14.1, + "vis_miles": 8 + }, + { + "time_epoch": 1497240000, + "time": "2017-06-12 05:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 0, + "condition": { + "text": "Light rain", + "icon": "//cdn.apixu.com/weather/64x64/night/296.png", + "code": 1183 + }, + "wind_mph": 4.3, + "wind_kph": 6.8, + "wind_degree": 286, + "wind_dir": "WNW", + "pressure_mb": 1015, + "pressure_in": 30.4, + "precip_mm": 0.9, + "precip_in": 0.04, + "humidity": 83, + "cloud": 100, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 12.6, + "vis_miles": 7 + }, + { + "time_epoch": 1497243600, + "time": "2017-06-12 06:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 1, + "condition": { + "text": "Mist", + "icon": "//cdn.apixu.com/weather/64x64/day/143.png", + "code": 1030 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 297, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 1.7, + "precip_in": 0.07, + "humidity": 82, + "cloud": 100, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 11.2, + "vis_miles": 6 + }, + { + "time_epoch": 1497247200, + "time": "2017-06-12 07:00", + "temp_c": 18.2, + "temp_f": 64.8, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.apixu.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 2.9, + "wind_kph": 4.7, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 2.5, + "precip_in": 0.1, + "humidity": 82, + "cloud": 100, + "feelslike_c": 19, + "feelslike_f": 66.2, + "windchill_c": 19, + "windchill_f": 66.2, + "heatindex_c": 19, + "heatindex_f": 66.2, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 9.7, + "vis_miles": 6 + }, + { + "time_epoch": 1497250800, + "time": "2017-06-12 08:00", + "temp_c": 19.5, + "temp_f": 67.1, + "is_day": 1, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.apixu.com/weather/64x64/day/302.png", + "code": 1189 + }, + "wind_mph": 4.7, + "wind_kph": 7.6, + "wind_degree": 298, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 2.6, + "precip_in": 0.1, + "humidity": 76, + "cloud": 92, + "feelslike_c": 20.3, + "feelslike_f": 68.5, + "windchill_c": 20.3, + "windchill_f": 68.5, + "heatindex_c": 20.3, + "heatindex_f": 68.5, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 8.8, + "vis_miles": 5 + }, + { + "time_epoch": 1497254400, + "time": "2017-06-12 09:00", + "temp_c": 20.9, + "temp_f": 69.6, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.apixu.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 6.3, + "wind_kph": 10.1, + "wind_degree": 289, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 2.6, + "precip_in": 0.1, + "humidity": 70, + "cloud": 84, + "feelslike_c": 21.7, + "feelslike_f": 71.1, + "windchill_c": 21.7, + "windchill_f": 71.1, + "heatindex_c": 21.7, + "heatindex_f": 71.1, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 7.9, + "vis_miles": 4 + }, + { + "time_epoch": 1497258000, + "time": "2017-06-12 10:00", + "temp_c": 22.2, + "temp_f": 72, + "is_day": 1, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.apixu.com/weather/64x64/day/302.png", + "code": 1189 + }, + "wind_mph": 8.1, + "wind_kph": 13, + "wind_degree": 279, + "wind_dir": "W", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 2.7, + "precip_in": 0.11, + "humidity": 64, + "cloud": 76, + "feelslike_c": 23, + "feelslike_f": 73.4, + "windchill_c": 23, + "windchill_f": 73.4, + "heatindex_c": 23, + "heatindex_f": 73.4, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 7, + "vis_miles": 4 + }, + { + "time_epoch": 1497261600, + "time": "2017-06-12 11:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 1, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/day/263.png", + "code": 1150 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 1.9, + "precip_in": 0.07, + "humidity": 60, + "cloud": 67, + "feelslike_c": 24, + "feelslike_f": 75.2, + "windchill_c": 24, + "windchill_f": 75.2, + "heatindex_c": 24, + "heatindex_f": 75.2, + "dewpoint_c": 15.7, + "dewpoint_f": 60.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 6.3, + "vis_miles": 3 + }, + { + "time_epoch": 1497265200, + "time": "2017-06-12 12:00", + "temp_c": 24.2, + "temp_f": 75.6, + "is_day": 1, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.apixu.com/weather/64x64/day/302.png", + "code": 1189 + }, + "wind_mph": 6.5, + "wind_kph": 10.4, + "wind_degree": 286, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 30.4, + "precip_mm": 1.1, + "precip_in": 0.04, + "humidity": 56, + "cloud": 59, + "feelslike_c": 25, + "feelslike_f": 77, + "windchill_c": 25, + "windchill_f": 77, + "heatindex_c": 25, + "heatindex_f": 77, + "dewpoint_c": 15.3, + "dewpoint_f": 59.5, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 5.7, + "vis_miles": 3 + }, + { + "time_epoch": 1497268800, + "time": "2017-06-12 13:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/day/263.png", + "code": 1150 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 290, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 30.4, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 52, + "cloud": 50, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 5, + "vis_miles": 3 + }, + { + "time_epoch": 1497272400, + "time": "2017-06-12 14:00", + "temp_c": 25.5, + "temp_f": 77.9, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 293, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 30.4, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 51, + "cloud": 40, + "feelslike_c": 26.3, + "feelslike_f": 79.3, + "windchill_c": 26.3, + "windchill_f": 79.3, + "heatindex_c": 26.3, + "heatindex_f": 79.3, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 6.3, + "vis_miles": 3 + }, + { + "time_epoch": 1497276000, + "time": "2017-06-12 15:00", + "temp_c": 25.9, + "temp_f": 78.6, + "is_day": 1, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.apixu.com/weather/64x64/day/263.png", + "code": 1150 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 296, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.2, + "precip_in": 0.01, + "humidity": 49, + "cloud": 29, + "feelslike_c": 26.7, + "feelslike_f": 80.1, + "windchill_c": 26.7, + "windchill_f": 80.1, + "heatindex_c": 26.7, + "heatindex_f": 80.1, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 7.7, + "vis_miles": 4 + }, + { + "time_epoch": 1497279600, + "time": "2017-06-12 16:00", + "temp_c": 26.2, + "temp_f": 79.2, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 299, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.2, + "precip_in": 0.01, + "humidity": 48, + "cloud": 18, + "feelslike_c": 27, + "feelslike_f": 80.6, + "windchill_c": 27, + "windchill_f": 80.6, + "heatindex_c": 27, + "heatindex_f": 80.6, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 9, + "vis_miles": 5 + }, + { + "time_epoch": 1497283200, + "time": "2017-06-12 17:00", + "temp_c": 25.9, + "temp_f": 78.6, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.3, + "wind_kph": 10.1, + "wind_degree": 299, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 50, + "cloud": 15, + "feelslike_c": 26.7, + "feelslike_f": 80.1, + "windchill_c": 26.7, + "windchill_f": 80.1, + "heatindex_c": 26.7, + "heatindex_f": 80.1, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 9.3, + "vis_miles": 5 + }, + { + "time_epoch": 1497286800, + "time": "2017-06-12 18:00", + "temp_c": 25.5, + "temp_f": 77.9, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.5, + "wind_kph": 10.4, + "wind_degree": 299, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.3, + "precip_in": 0.01, + "humidity": 51, + "cloud": 13, + "feelslike_c": 26.3, + "feelslike_f": 79.3, + "windchill_c": 26.3, + "windchill_f": 79.3, + "heatindex_c": 26.3, + "heatindex_f": 79.3, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 9.7, + "vis_miles": 6 + }, + { + "time_epoch": 1497290400, + "time": "2017-06-12 19:00", + "temp_c": 25.2, + "temp_f": 77.4, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 300, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 53, + "cloud": 10, + "feelslike_c": 26, + "feelslike_f": 78.8, + "windchill_c": 26, + "windchill_f": 78.8, + "heatindex_c": 26, + "heatindex_f": 78.8, + "dewpoint_c": 15, + "dewpoint_f": 59, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 10, + "vis_miles": 6 + }, + { + "time_epoch": 1497294000, + "time": "2017-06-12 20:00", + "temp_c": 24.5, + "temp_f": 76.1, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 289, + "wind_dir": "WNW", + "pressure_mb": 1013, + "pressure_in": 30.4, + "precip_mm": 0.4, + "precip_in": 0.02, + "humidity": 59, + "cloud": 19, + "feelslike_c": 26.4, + "feelslike_f": 79.5, + "windchill_c": 25.1, + "windchill_f": 77.2, + "heatindex_c": 26.4, + "heatindex_f": 79.5, + "dewpoint_c": 15.3, + "dewpoint_f": 59.5, + "will_it_rain": 1, + "will_it_snow": 0, + "vis_km": 9.7, + "vis_miles": 6 + }, + { + "time_epoch": 1497297600, + "time": "2017-06-12 21:00", + "temp_c": 23.9, + "temp_f": 75, + "is_day": 1, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 279, + "wind_dir": "W", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 65, + "cloud": 29, + "feelslike_c": 26.8, + "feelslike_f": 80.2, + "windchill_c": 24.1, + "windchill_f": 75.4, + "heatindex_c": 26.8, + "heatindex_f": 80.2, + "dewpoint_c": 15.7, + "dewpoint_f": 60.3, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 9.3, + "vis_miles": 5 + }, + { + "time_epoch": 1497301200, + "time": "2017-06-12 22:00", + "temp_c": 23.2, + "temp_f": 73.8, + "is_day": 0, + "condition": { + "text": "Patchy rain possible", + "icon": "//cdn.apixu.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 268, + "wind_dir": "W", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 0.5, + "precip_in": 0.02, + "humidity": 71, + "cloud": 38, + "feelslike_c": 27.2, + "feelslike_f": 81, + "windchill_c": 23.2, + "windchill_f": 73.8, + "heatindex_c": 27.2, + "heatindex_f": 81, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 9, + "vis_miles": 5 + }, + { + "time_epoch": 1497304800, + "time": "2017-06-12 23:00", + "temp_c": 21.2, + "temp_f": 70.2, + "is_day": 0, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.apixu.com/weather/64x64/night/353.png", + "code": 1240 + }, + "wind_mph": 5.8, + "wind_kph": 9.4, + "wind_degree": 273, + "wind_dir": "W", + "pressure_mb": 1014, + "pressure_in": 30.4, + "precip_mm": 0.6, + "precip_in": 0.02, + "humidity": 75, + "cloud": 55, + "feelslike_c": 21.5, + "feelslike_f": 70.7, + "windchill_c": 21.5, + "windchill_f": 70.7, + "heatindex_c": 24.1, + "heatindex_f": 75.4, + "dewpoint_c": 16, + "dewpoint_f": 60.8, + "will_it_rain": 0, + "will_it_snow": 0, + "vis_km": 9.3, + "vis_miles": 5 + } + ] + } + ] + } } var mappedForecastData = { - "city": { - "name": "Altstadt", - "id": 6940463, - "lng": 11.5752, - "lat": 48.137 - }, - "days": [{ - "date": "Sat 22 Apr", - "temprature": { - "current": 7, - "min": 4, - "max": 7 - }, - "weather": { - "group": "Rain", - "description": "moderate rain", - "icon": "10d" - }, - "wind": { - "speed": 5, - "degree": null - }, - "pressure": 963, - "humidity": 85 - }, { - "date": "Sun 23 Apr", - "temprature": { - "current": 8, - "min": -2, - "max": 9 - }, - "weather": { - "group": "Snow", - "description": "light snow", - "icon": "13d" - }, - "wind": { - "speed": 3, - "degree": null - }, - "pressure": 965.28, - "humidity": 80 - }, { - "date": "Mon 24 Apr", - "temprature": { - "current": 14, - "min": 1, - "max": 16 - }, - "weather": { - "group": "Clear", - "description": "sky is clear", - "icon": "01d" - }, - "wind": { - "speed": 1, - "degree": null - }, - "pressure": 957.89, - "humidity": 65 - }, { - "date": "Tue 25 Apr", - "temprature": { - "current": 19, - "min": 6, - "max": 19 - }, - "weather": { - "group": "Clouds", - "description": "few clouds", - "icon": "02d" - }, - "wind": { - "speed": 2, - "degree": null - }, - "pressure": 947.04, - "humidity": 54 - }, { - "date": "Wed 26 Apr", - "temprature": { - "current": 12, - "min": 6, - "max": 12 - }, - "weather": { - "group": "Rain", - "description": "moderate rain", - "icon": "10d" - }, - "wind": { - "speed": 3, - "degree": null - }, - "pressure": 931.5, - "humidity": 0 - }] + "location": { + "name": "Munich", + "region": "Bayern", + "country": "Germany", + "lat": 48.15, + "lon": 11.58, + "tz_id": "Europe/Berlin", + "localtime_epoch": 1496915947, + "localtime": "2017-06-08 11:59" + }, + "days": [{ + "date": "Thu 8 Jun", + "description": "Sunny", + "icon": 1000, + "temperature": { + "min": "11", + "max": "25", + "current": 17 + }, + "wind": "10", + "humidity": 54 + }, { + "date": "Fri 9 Jun", + "description": "Partly cloudy", + "icon": 1003, + "temperature": { + "min": "15", + "max": "25" + }, + "wind": "12", + "humidity": 59 + }, { + "date": "Sat 10 Jun", + "description": "Light rain shower", + "icon": 1240, + "temperature": { + "min": "13", + "max": "22" + }, + "wind": "11", + "humidity": 68 + }, { + "date": "Sun 11 Jun", + "description": "Sunny", + "icon": 1000, + "temperature": { + "min": "15", + "max": "28" + }, + "wind": "14", + "humidity": 63 + }, { + "date": "Mon 12 Jun", + "description": "Sunny", + "icon": 1000, + "temperature": { + "min": "17", + "max": "27" + }, + "wind": "15", + "humidity": 64 + }] } module.exports = { diff --git a/test/mocha.opts b/test/mocha.opts index 52f1302..086a66a 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -3,6 +3,4 @@ --require ignore-styles --require test/helpers/helpers.js --require test/helpers/setup.js - --R spec -test/*.spec.js \ No newline at end of file +-R spec \ No newline at end of file diff --git a/test/utils.spec.js b/test/utils.spec.js index 5960ab7..9ecf676 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -4,7 +4,7 @@ describe('Utils module', () => { describe('getIcon', () => { it('return the weather-con class equivalent to OW class', () => { - var icon = utils.getIcon("04n"); + var icon = utils.getIcon("1006"); expect(icon).to.equal("wi-cloudy"); }); it('return "na" if no mapped class name found', () => { @@ -18,14 +18,14 @@ describe('Utils module', () => { var units = utils.getUnits("metric"); expect(units).to.deep.equal({ temp: "C", - speed: "Meter/Sec" + speed: "kph" }); }); it('return imperial units', () => { var units = utils.getUnits("imperial"); expect(units).to.deep.equal({ temp: "F", - speed: "Miles/Hour" + speed: "mph" }); }); it('return empty values if value provided doesnt exist', () => { @@ -38,14 +38,13 @@ describe('Utils module', () => { }); describe('formatDate', () => { - it('return date value formatted to "ddd D MMM" from unix string', () => { - var date = utils.formatDate("1492772400"); - expect(date).to.equal("Fri 21 Apr"); + it('return date value formatted to "ddd D MMM" from string', () => { + var date = utils.formatDate("2017-06-08"); + expect(date).to.equal("Thu 8 Jun"); }); it('handles invalid input values', () => { expect(utils.formatDate(null)).to.equal(""); expect(utils.formatDate("")).to.equal(""); - expect(utils.formatDate("invalid unix string")).to.equal(""); }); });