How to use JSON Receiver data point
-
Hello,
I am guessing this will be answered by @phildunlap - as he has responded to most of the JSON receiver questions. I would like to display weather data on my dashboard and am using the Open Weather API to access that data. The URL query returns a JSON string as seen below:
I have little experience with JSON, but I would like to pull the values of temp_max and temp_min and display them as new data points. Ideally this would be done every hour.
Is the HTTP JSON receiver capable of doing this? If so, how do I go about setting these data points up?
Cheers, Henry
-
I have also tried to access weather data via another technique. This is an example from JSfiddle which effectively shows what I would like: http://jsfiddle.net/derkoe/yc4yG/
Converting the page to HTML and adding in my API key I have the following code:
<!DOCTYPE html> <html lang="en"> <head> <style type="text/css"> // CSS Content </style> </head> <body> <div ng-app="myapp" ng-controller="WeatherCtrl"> <h2>Weather in Salzburg, Austria</h2> <weather-icon cloudiness="{{ weather.clouds }}"></weather-icon> <h3>Current: {{ weather.temp.current | temp:2 }}</h3> min: {{ weather.temp.min | temp }}, max: {{ weather.temp.max | temp }} </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script> <script language="JavaScript" type="text/javascript"> 'use strict'; var myapp = angular.module('myapp', []); myapp.factory('weatherService', function($http) { return { getWeather: function() { var weather = { temp: {}, clouds: null }; $http.jsonp('http://api.openweathermap.org/data/2.5/weather?q=Salzburg,at&units=metric&callback=JSON_CALLBACK&APPID=3d7ccb31d427bde3f4ef6537c6f5a586').success(function(data) { if (data) { if (data.main) { weather.temp.current = data.main.temp; weather.temp.min = data.main.temp_min; weather.temp.max = data.main.temp_max; } weather.clouds = data.clouds ? data.clouds.all : undefined; } }); return weather; } }; }); myapp.filter('temp', function($filter) { return function(input, precision) { if (!precision) { precision = 1; } var numberFilter = $filter('number'); return numberFilter(input, precision) + '\u00B0C'; }; }); myapp.controller('WeatherCtrl', function ($scope, weatherService) { $scope.weather = weatherService.getWeather(); }); myapp.directive('weatherIcon', function() { return { restrict: 'E', replace: true, scope: { cloudiness: '@' }, controller: function($scope) { $scope.imgurl = function() { var baseUrl = 'https://ssl.gstatic.com/onebox/weather/128/'; if ($scope.cloudiness < 20) { return baseUrl + 'sunny.png'; } else if ($scope.cloudiness < 90) { return baseUrl + 'partly_cloudy.png'; } else { return baseUrl + 'cloudy.png'; } }; }, template: '<div style="float:left"><img ng-src="{{ imgurl() }}"></div>' }; }); </script> </body>
When I open this HTML file in my browser it works fine, outputting
But if I paste this HTML code into the play area - it will display nothing. I'm happy with either solution - preferably one that works!
Thank you,
Henry -
Hi Henry,
The JSON Receiver is not what you're looking for. You need to retrieve this content to get values from it, so the HTTP Retriever is the better bet. It looks like there's only one instance of temp_min and temp_max, so your points' regex should be as simple as
.*temp_min":(\d+).*
and.*temp_max":(\d+).*
Perhaps Jared or Will will have the answer to your angular question.
-
That worked perfectly, thanks Phil.
-
If you don't need to log the data and you just want to display the weather on your dashboard then you can definitely just add a widget.
The fiddle you linked needed some changes for the latest version of AngularJS (1.6.4) but I got it working as an example of how to add custom directives to the user module.
To add the a user AngularJS module go to Administration... UI Settings then at the bottom click the icon next to
User module URL
. Click the plus icon (Create new file
) then copy paste this code (taken from the JSFiddle).The code had to be modified for SCE, strict dependency injection and some changes to the way JSONP requests work.
define(['angular', 'require'], function(angular, require) { 'use strict'; var userModule = angular.module('userModule', ['maUiApp']); userModule.config(['$sceDelegateProvider', function($sceDelegateProvider) { var whiteList = $sceDelegateProvider.resourceUrlWhitelist(); whiteList.push('http://api.openweathermap.org/**'); $sceDelegateProvider.resourceUrlWhitelist(whiteList); }]); userModule.factory('weatherService', ['$http', '$sce', function($http, $sce) { return { getWeather: function() { var weather = { temp: {}, clouds: null }; $http.jsonp('http://api.openweathermap.org/data/2.5/weather?q=Salzburg,at&units=metric&APPID=f9dbd911bc01df1d9ce563b2ba4d3209', {jsonpCallbackParam: 'callback'}).then(function(data) { if (data && data.data) { data = data.data; if (data.main) { weather.temp.current = data.main.temp; weather.temp.min = data.main.temp_min; weather.temp.max = data.main.temp_max; } weather.clouds = data.clouds ? data.clouds.all : undefined; } }); return weather; } }; }]); userModule.filter('temp', ['$filter', function($filter) { return function(input, precision) { if (!precision) { precision = 1; } var numberFilter = $filter('number'); return numberFilter(input, precision) + '\u00B0C'; }; }]); userModule.controller('WeatherCtrl', ['$scope', 'weatherService', function ($scope, weatherService) { $scope.weather = weatherService.getWeather(); }]); userModule.directive('weatherIcon', function() { return { restrict: 'E', replace: true, scope: { cloudiness: '@' }, controller: ['$scope', function($scope) { $scope.imgurl = function() { var baseUrl = 'https://ssl.gstatic.com/onebox/weather/128/'; if ($scope.cloudiness < 20) { return baseUrl + 'sunny.png'; } else if ($scope.cloudiness < 90) { return baseUrl + 'partly_cloudy.png'; } else { return baseUrl + 'cloudy.png'; } }; }], template: '<div style="float:left"><img ng-src="{{ imgurl() }}"></div>' }; }); return userModule; }); // define
The markup will look like this (you dont need the ng-app).
<div ng-controller="WeatherCtrl"> <h2>Weather in Salzburg, Austria</h2> <weather-icon cloudiness="{{ weather.clouds }}"></weather-icon> <h3>Current: {{ weather.temp.current | temp:2 }}</h3> min: {{ weather.temp.min | temp }}, max: {{ weather.temp.max | temp }} </div>
-
Thanks for sending that through Jared,
I've clicked the plus icon and this is the following pop-up I receive:
So I have named it 'weather' and it saved the file in the public file store, like this:
Where is it that I paste the code?Thanks,
Henry -
You just have to give the file a
.js
extension. SouserModule.js
or something like that. Then an editor will open. -
Sorry Jared - I'm still unsure about using the custom directives.
So I have saved the first block of code as userModule.js within the file stores:
I then copy and pasted the markup in the play area, saved and refreshed - but nothing is appearing. Have I done this incorrectly? -
That looks right, you probably just havent linked to the file from the
UI settings
page. It should look like thisBe sure to hit save at the top of the page.