Digi Device API读取Datastream / DIO / AD

时间:2015-06-18 07:50:01

标签: xml cloud xbee

我有XBee Gateway ZB,Wifi和 我正在尝试使用Digi Device API。我已经尝试了Heroku App xbeegateway.herokuapp.com,它的效果非常好。

所以我想在线访问Datastream。使用Google电子表格或类似的东西。所以从digi阅读文档。我可以通过http://devicecloud.digi.com/ws/DataStream/00000000-00000000-00######-########/xbee.serialIn/

访问网关

但那不是问题。我以为我可以看到我通过Arduino发送到网关的serialIn。 (我发送一个包含我房间温度的字符串。)但是看看xml我真的不能理解它。

<result>
<resultSize>1</resultSize>
<requestedSize>1000</requestedSize>
<pageCursor>94a9cb44-1-cb91b9c6</pageCursor>
<DataStream>
<cstId>9921</cstId>
<streamId>
00000000-00000000-00######-########/xbee.serialIn/[00:##:##:00:##:##:##:##]!
</streamId>
<dataType>STRING</dataType>
<forwardTo/>
<currentValue>
<id>230fee58-158b-11e5-a4a7-fa163eefb35b</id>
<timestamp>1434612303755</timestamp>
<timestampISO>2015-06-18T07:25:03.755Z</timestampISO>
<serverTimestamp>1434612304781</serverTimestamp>
<serverTimestampISO>2015-06-18T07:25:04.781Z</serverTimestampISO>
<data>TWVzc3VuZzogMjIgQ2Vsc2l1cw0K</data>
<description/>
<quality>0</quality>
</currentValue>
<description/>
<units/>
<dataTtl>2678400</dataTtl>
<rollupTtl>2678400</rollupTtl>
</DataStream>
</result>

我看到了时间戳,但我无法理解这应该是什么意思<data>TWVzc3VuZzogMjIgQ2Vsc2l1cw0K</data>。这是字符代码还是我误解了什么?

如果我在串口终端小部件的Heroku应用程序中查看JavaScript,我会得到此代码。看起来好像是在使用var decoded = utils.base64_decode(newData);

/*
 * This Source Code Form is subject to the terms of the Mozilla Public License,
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 * obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (c) 2014 Digi International Inc., All Rights Reserved.
 */

'use strict';

angular.module('XBeeGatewayApp')
    //jshint -W098
    .controller('serialWidgetCtrl', function ($scope, utils, $log, dashboardApi, notificationService) {
        $scope.data_sending = false;
        $scope.last_received_timestamp = undefined;

        $scope.getStreamUpdateHandler = function (newData) {
            // For the serial widget, data *should* come in as an object of the form
            //   {"content": "...", "format": "base64"}
            var _newData = newData.value;
            if (_.isEmpty(_newData)) {
                $log.warn("Serial widget got malformed data", newData);
                return;
            }
            var _timestamp = newData.timestamp;
            newData = _newData;

            // XBee Gateway
            if (angular.isString(newData)) {
                var decoded = utils.base64_decode(newData);

                if (_.isEmpty(decoded)) {
                    // Might not be decoded.
                    newText = newData;
                } else {
                    // Successfully decoded the data.
                    newText = decoded;
                }
                $log.info("Adding text:", newText);
                $scope.displaySerialText(newText, true);
                $scope.last_received_timestamp = _timestamp;
                return;
            }
            // Or, XBee Wi-Fi
            else if (newData.content !== undefined){
                // Check format to see if we should b64 decode
                var newText;
                if(newData.format === "base64"){
                    newText = utils.base64_decode(newData.content);
                } else {
                    newText = newData.content;
                }
                $scope.displaySerialText(newText, true);
                $scope.last_received_timestamp = _timestamp;
            } else {
                // TODO display some error?
                $log.warn('Serial widget got malformed data', newData);
            }
        }

        $scope.setStreamUpdateHandler = function (newData) {
            // Updates to the set stream could be handled here too, as we use the same for get/set
            return;
        }

        $scope.serialEnterKeypress = function($event){
            if($scope.serialOutText){
               $scope.sendText($scope.serialOutText);
            }
            $event.preventDefault();
        }

        $scope.sendText = function(text) {
            $scope.data_sending = true;

            if ($scope.widget.add_carriage_returns) {
                // Insert a CR before/after string to make it show on new line
                // on both ends
                var cr = String.fromCharCode(13);
                text = cr + text + cr;
            }

            dashboardApi.send_serial($scope.widget.device, $scope.widget.radio, text).then(
                function(result){
                    // On success, show the sent text
                    $scope.displaySerialText(text, false);
                    // Clear the input box for next entry
                    $scope.serialOutText = null;
                    // Reenable input
                    $scope.data_sending = false;
                },
                function(reason){
                    notificationService.error("Error sending text. Please try again.");
                    // Reenable input
                    $scope.data_sending = false;
                });
        }

        $scope.$watch('data_sending', function (sending) {
            if (sending) {
                $scope.widgetState = 1;
            } else {
                $scope.widgetState = 0;
            }
        });
    })
    .directive('serialWidget', function (widgetRegistry, utils, dataStreams, $log) {
        // called after DOM element is compiled
        var linker = function postLink(scope, element) {
            scope.$element = element;
            var type = 'serial';
            var spec = widgetRegistry.get(type);

            // See http://lodash.com/docs#bind
            // (dataUpdate simply calls scope.updateHandler)
            var getCallback = _.bind(scope.getStreamUpdateHandler, scope);
            var setCallback = _.bind(scope.setStreamUpdateHandler, scope);
            utils.postlinkWidget(type, scope, element, spec, getCallback, setCallback);
            // Any more fancy footwork can be done here.

            // Manually listen for serialIn
            var device = scope.widget.device;
            var inputStream = "xbee.serialIn/[" + scope.widget.radio + "]!";
            $log.debug("Listening for serial stream: ", device, inputStream);
            var removeListener = dataStreams.listen(device, inputStream, scope.getStreamUpdateHandler);
            scope.$on('$destroy', function () {
                removeListener();
            });

            // Widget display area
            // Use jquery to find, Angular's jqlite doesn't support selector
            var output_pane = $(element).find(".serial-display");

            scope.displaySerialText = function(text, isInbound){
                var $newText = null;
                if(isInbound){
                    $newText = $('<span/>').addClass("serial-in");
                    // Show incomming text inline
                    // Split string to handle any Carriage Returns
                    if(text === "\r"){
                        $newText.append($('<br>'));
                    } else {
                        var snippets = text.split("\r");
                        _.each(snippets, function (snippet) {
                            // CR at start & end will make cause empty strings
                            if(snippet === ""){
                                $newText.append($('<br>'));
                            } else {
                                $newText.append($('<span/>').text(snippet));
                            }
                        });
                    }
                } else {
                    // Outgoing should be in it's own line
                    $newText = $('<p/>').text(text).addClass("serial-out");
                }
                $(output_pane).append($newText);
                $(output_pane).scrollTop($(output_pane)[0].scrollHeight);
            }
        };

        // AngularJS directive setup
        return {
            templateUrl: "widgets/serialWidget/serialWidget.tpl.html",
            restrict: 'AE',
            link: linker,
            controller: 'serialWidgetCtrl',
            scope: { widget: "=serialWidget", widgetState: "=state" }
        };
    })
    // This function, referred to in AngularJS as a "run block", is called by
    // AngularJS after the injector is created and is used to bootstrap the
    // application. The XBee ZigBee Cloud Kit makes use of the run block
    // to add widget definitions to the widget registry at start-up.
    .run(function(widgetRegistry) {
        // Adding the widget to the widget registry
        var widget_type_key = 'serial';
        var widget_description = 'Serial Data Widget';
        var widget_spec = {
            // Whether or not the widget is built-in or user-created
            // (i.e., whether the code is in /src/app or /src/common)
            builtin: true,
            // widget size: X,Y (columns, rows)
            size: [3, 2],
            // description appearing in 'Widget Type' list when adding new
            // widgets
            description: widget_description,
            directive: "serial-widget",
            // camel-case version of directive
            directive_c: "serialWidget",

            // properties pertaining to widget settings
            /*
            has_input: does the widget's data get updated from Device Cloud?
            sends_output: does the widget send data to the device?
            input_xform: can the user specify a custom transformation to apply
                            to incoming data? (optional)
            options: list of objects defining the settings associated with this
                        widget type
                - options generally follow the Revalidator API
                    (http://github.com/flatiron/revalidator)
            */
            has_input: false,
            sends_output: false,
            options: [
                {key: "add_carriage_returns", label: "Add Carriage Returns",
                 type: "boolean", required: false, 'default': true}
            ]
        };

        // DO NOT CHANGE ANY CODE BELOW HERE.
        widgetRegistry.put(widget_type_key, widget_spec);
    });

2 个答案:

答案 0 :(得分:0)

好吧,我的坏。从未听说过base64。也许是因为我不熟悉在线数据流。

搜索后,我发现了一个使用base64解码的网站:https://www.base64decode.org

我可以解码TWVzc3VuZzogMjIgQ2Vsc2l1cw0K

答案 1 :(得分:-1)

您无需更改选项enable encode 64或不将编码64启用到digi网关,

此致 维克多