Digi 设备 API 读取数据流/DIO/AD

Digi Device API reading Datastream / DIO / AD

我有 XBee Gateway ZB、Wifi 和 我正在试验 Digi 设备 API。我已经尝试过 Heroku App xbeegateway.herokuapp.com 并且效果非常好。

所以我想在线访问数据流。使用 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);
    });

好吧,我的错。没听说过 base64。可能是因为我是在线数据流的新手。

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

我可以解码 TWVzc3VuZzogMjIgQ2Vsc2l1cw0K

不需要更改启用编码 64 或不启用编码 64 到 digi 网关的选项,

问候 维克多