Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website

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:

    0_1499392680084_98cf7878-581e-4b03-b36b-d19d125d9d36-image.png

    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
    0_1499394749806_233d28d9-bfed-4420-a206-72d8bc1dd15d-image.png

    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:
    0_1499731481345_cb22014c-3144-435e-b665-247d955c0803-image.png
    So I have named it 'weather' and it saved the file in the public file store, like this:
    0_1499731575078_28572826-a63c-49f5-ab9b-79b4f7779d5e-image.png
    Where is it that I paste the code?

    Thanks,
    Henry


  • You just have to give the file a .js extension. So userModule.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:
    0_1499815158121_5eb10078-2fcd-4acc-b89a-32bc28e00e11-image.png
    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 this

    0_1499874100270_31f5a1d0-e9cc-412c-bbd8-41a7422d8c20-image.png

    Be sure to hit save at the top of the page.