@marsleung
2019-12-20T06:46:29.000000Z
字数 15404
阅读 7897
triton
desktop
neptune
windows
本文将介绍,如何通过 Triton Windows 把您的设备连接到 Neptune工业设备物联云平台,体验快速连接并传输数据的乐趣。
Triton Windows 适用于您的控制程序或者您的逻辑程序运行于Windows(x86/x64)之上,通过您的程序和Triton交互,实现设备连接和数据传输的功能。
交互方式有以下三种,可根据您的实际情况选择使用:
- 您的程序实现TCP Client与Triton进行通讯;
- 您的程序实现Modbus协议(从站),Triton作为Modbus主站向您的程序读取数据;
- 您的程序集成Triton外部库(C/C++),您的程序直接与Triton进行通讯;
如果您使用的运行平台为Linux或者WinCE,请参考以下文档:
STEP#01
访问 https://www.neptune-iiot.net, 点击右上角注册
;
STEP#02
填写注册信息,注册分为三个步骤:
a) 填写账户信息(使用邮件或者手机号码注册);
b) 验证账户信息(使用邮件或者手机号码接收验收激活邮件或者验证码);
以邮箱注册为例子,将收到上述邮件。点击激活邮箱
,跳转到团队创建界面。
c) 创建或者加入一个团队[说明1], 完成注册;
新建一个团队,输入一个您的团队名称,点击创建
;
加入一个团队,通过关键字搜索一个团队的名称,点击申请加入
[说明2]。
说明1:团队
团队的含义是一个域,用来为用户划定一个空间。用户创建团队时,会自动成为该团队的管理员,别的用户可以申请加入您的团队,您也可以在团队中邀请用户加入。
说明2:申请加入
当申请加入一个团队时,需要对方团队的管理员通过您的请求。请在申请加入后,耐心等待通过。
STEP#03 注册完成
注册完成后,页面跳转到登录界面。您可以使用您的账号密码进行登录。
本文档关注使用Triton将设备连接至Neptune,因此平台功能在本文档中不作过多介绍,平台功能的介绍将在其它文档中介绍。
在Neptune账号注册完成后,我们需要在Neptune中“创建一个设备”,这个“设备”将获得一个全平台唯一的序列号,并且和实体设备一一对应起来。
STEP#01
点击左侧菜单栏分组设备列表
,选中菜单设备
,右侧出现设备列表,此时设备列表显示为空。
点击列表上方创建
按钮,出现以下对话框:
STEP#02
为您的设备输入一个名称和描述,其它的栏位将会在平台使用教程中说明,例如:
STEP#03
点击确认后,Neptune为该设备生成设备序列号
以及团队令牌
。上述信息是设备通过Triton能正确连接到Neptune的重要信息,后续仍可以在平台中查询得到。
STEP#04
再次返回到设备列表
,就可以看到您的设备已经添加到Neptune中了。
Triton Windows
x86
https://www.neptune-iiot.net/triton-release/triton-windows-386.exe
x64
https://www.neptune-iiot.net/triton-release/triton-windows-amd64.exe
Triton目前支持以下版本:
Windows(x86/x64)、WinCE(x86)、Linux(x86/x64/ARMv5以上/AArch64),请按实际情况选择适配版本。其它版本请从以下地址下载:
Triton WinCE
x86
https://www.neptune-iiot.net/triton-release/triton-wince-386.zip
Triton Linux
x86
https://www.neptune-iiot.net/triton-release/triton-linux-386
x64
https://www.neptune-iiot.net/triton-release/triton-linux-amd64
AArch64
https://www.neptune-iiot.net/triton-release/triton-linux-arm64
ARMv5
https://www.neptune-iiot.net/triton-release/triton-linux-armv5
ARMv6
https://www.neptune-iiot.net/triton-release/triton-linux-armv6
ARMv7
https://www.neptune-iiot.net/triton-release/triton-linux-armv7
STEP#01
在运行Triton前,需要生成Triton的配置文件。请在Windows命令提示符
(可通过 Win键+R 弹出运行
并输入cmd调用)中,定位到下载的Triton的所在目录。
STEP#02
输入以下命令:
triton-windows-amd64.exe -g triton.toml
命令执行后,在triton所在目录下,生成配置文件 triton.toml
STEP#03
使用文本编辑器打开triton.toml
,推荐使用Notepad++
, EditPlus
等文本编辑工具进行操作,使用Windows自带的记事本
打开,可能会丢失格式,但不影响使用。以下截图使用Visual Studio Code
打开:
STEP#04
修改配置文件中的第四行、第二十二行内容:
第四行
需要填写设备的序列号
,序列号可以在设备列表
中查找得到:
Serial = "6ed92f55a083f1038b005eb28ef0c760"
第二十二
行需要填写团队令牌
,团队令牌可以在团队设置
中查找得到:
Token = "05712fb7cf95547d3e0f2ad076c3db75"
如果您需要使用证书加密连接,请将UseSSL
改为true
,连接端口改为8883
,并修改相关配置项:
[MessageQueue]
#服务器地址保持不变
Address = "www.neptune-iiot.net"
Token = "05712fb7cf95547d3e0f2ad076c3db75"
#修改端口为8883
Port = "8883"
#启用加密
UseSSL = true
#加密连接属于公测阶段,InsecureSSL需要设置为`true`才能正常连接
InsecureSSL = true
#CA证书路径
CAPath = "/path/to/ca.crt"
#客户证书路径
CertPath = "/path/to/client.crt"
#客户私钥路径
KeyPath = "/path/to/client.key"
#客户私钥密码
KeyPassphrase = "hunter2"
修改配置文件中最后的LogLevel
配置,让程序在日志中显示更多的内容:
LogLevel = 5
修改完成后,保存triton.toml
, 双击运行triton-windows-amd64.exe
(Windows可能会提示拦截该程序,点击仍要运行
即可),输出如下内容:
打开Neptune,设备列表,查看列表中的设备是否已经显示在线,在线表示Triton与Neptune已经成功通讯。如果依然显示为离线,请检查:
- Triton所在的计算机网络是否正常;
- triton.toml中需要修改的两项内容是否正确填写;
Triton目前提供了三种数据交互的方式,分别为:
请根据您的实际情况,选择适配的方法。
所有需要传输的数据都需要先在Neptune中先定义,Neptune中称为数据定义
,每一个设备需要维护一份数据定义
。如果数据不事先定义好,在数据传输时,平台会把无定义的数据丢弃。
STEP#01
从设备列表中找到您需要添加数据定义的设置,点击设备名称进入设备表单;
STEP#02
采用key/value
模式(即编号/值)规划好您需要传输的数据,您需要为每个需要传输的变量定义一个在本设备中唯一的编号,建议编写具有阅读性、便于理解的编号;比如我们要传输以下内容,编号规划如下:
- 温度:temp,数字
- 湿度:humidity, 数字
- 照度:illuminance, 数字
- 是否工作:is_running, 布尔
- 工作状态:status, 文本
STEP#03
将上述内容输入到数据定义
表格中;
a) 点击添加
,在对话框中逐项输入第2点中的范例数据[说明1]:
说明1
1. 数据ID由数字和字母组成,不能包含特殊字符: + - * / > < = % . \ & $ # @, 但可以包含 _ (下划线)。
2.数据ID
、名称
以及数据类型
为必填项,其中数据类型可选值为:数字
(不区分整形和浮点型)、字符
、布尔类型
;
b) 如果您的数据存在枚举型
(即用数值代表一个选项,例如:1->男,2->女),可以使用数据转义
,数据转义
会将得到的数据值,直接翻译为转义值
c) 全部添加完成后,效果如下:
STEP#04
每个设备都需要有这样一份数据定义
,首个设备需要按照上述步骤手动创建,创建后可以将其保存为模板
或者导出Excel
方便下次直接引用或者使用Excel文件导入,以减少重复的操作次数;
说明
与3.4 使用Modbus协议读取您的数据
二选其一即可。
按照2.4 运行Triton中的描述正确运行Triton程序。
Triton正常运行后,它会建立一个Socket Server,Server信息如下:
Address = 127.0.0.1 (或本机局域网IP)
Port = 8864
请您在您的工程中,通过代码使用Socket通讯连接到上述地址;
当您有数据发送需求时,您需要将需要传输的数据按照特定的格式构造字符串,并将字符串发送到Triton建立的Socket Server中。字符串的格式为:
s|key1,value1|key2,value2|……|keyN,valueN
其中s|
为固定的字符前缀,所有数据以编号和值作为一组,编号与值的分隔符为,(英文)
,每组编号值之间分隔符为|
。
以3.2 数据定义中的数据为例,构造的字符串为:
s|temp,25.8|illuminance,600|humidity,70|is_running,1|status,2
将上述字符串以Socket的方式发送到127.0.0.1:8864
即可。
特别说明
1. 数据发送的时机及频率由用户的程序决定;
2. 每次发送时,仅需要发生当前需要发送的key/value即可,不必将所有的key/value都构造在发送字符串中。
除了3.3.2.1 发送数据到Neptune
中介绍的将数据从您的设备发送到Neptune以外,还支持接收来自Neptune的数据;从Neptune下发到设备的数据分为两类:
- 系统用数据
- 用户自定义数据
只有用户自定义数据
用户才能接收得到,系统用数据
会由Triton接收后进行特定处理,不会转交给用户。用户可以通过自行编写下发的数据,并在用户程序接收后做特定的处理。
当用户设备有数据接收需求时,可以向Triton建立的Socket Server中发送以下消息:
r
Socket Server将Neptune的数据返回给到TCP Client,Neptune的数据以队列的方式存在,每次向Socket Server发送r
时,取出一条数据,直到所有数据取完后,Socket Server返回NODATA
,表示队列中已无数据。
说明
与3.3 使用TCP与Triton进行Socket通讯
二选其一即可。
在开始使用Modbus协议作为数据交互方式时,需确认以下内容:
- 您的设备程序需要实现Modbus协议,并作为从站(Slave)将数据写入Modbus指定的存储区中;
- 您的设备程序如果与设备是分离的,那么设备与运行程序的计算机之间需要用网线或者串口线相连,网络连接实现Modbus-TCP,串口线连接实现Modbus-RTU;建议使用网线连接并实现Modbus-TCP协议;
- 您的程序已正确运行,并正确调用Triton动态库;
- 建议在开始本章节的测试前,您已经使用Modbus工具成功地从设备中读取到数据,以减少影响后续操作的因素;
Modbus Connector
应用套件该工具目前处于内测阶段,平台注册用户默认已开始此功能,因此不需要额外的安装工作,请直接查看3.5.2 结果测试-Modbus
。
Triton动态库包含一个库文件和一个头文件,请根据您使用的开发语言及平台下载对应的动态库:
Triton for Windows Library
x86
https://www.neptune-iiot.net/triton-release/libs/triton-windows-386.zip
libtriton.h
内容如下:
#pragma once
#ifdef libtriton_EXPORTS
#define LIBTRITON_API __declspec(dllexport)
#else
#define LIBTRITON_API __declspec(dllimport)
#endif
#ifndef NELEMS
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
#endif
#define RECV_BUFSIZE 16384
typedef struct KeyValue {
char* Key;
char* Value;
}KeyValue;
typedef struct Payload {
int size;
KeyValue *keyValue;
}Payload;
#ifdef __cplusplus
extern "C" {
#endif
// Send data
// Parameters:
// kvs - array of key value pairs (KeyValue structs) to be sent
// size - length of array (kvs)
// Return values:
// 0 - success
// -1 - error connecting to server
// -2 - error writing to server
// -3 - error reading response from server
// -4 - data error
LIBTRITON_API int Send(KeyValue kvs[], int size);
LIBTRITON_API int Send_T(KeyValue kvs[], int size);
LIBTRITON_API int Send_Compat(KeyValue kvs[], int size);
LIBTRITON_API int Send_Compat_T(KeyValue kvs[], int size);
// Receive data
// Parameters:
// buffer - pointer to buffer for writing received message
// Returns received data length by default, otherwise:
// -1 - error connecting to server
// -2 - error writing to server
// -3 - error reading response from server
// -4 - data error
LIBTRITON_API Payload* Receive();
LIBTRITON_API Payload* Receive_T();
LIBTRITON_API Payload* Receive_Compat();
LIBTRITON_API Payload* Receive_Compat_T();
// MQTT status
// Returns MQTT connection status, true if connected, false otherwise
LIBTRITON_API bool Status();
LIBTRITON_API bool Status_T();
LIBTRITON_API bool Status_Compat();
LIBTRITON_API bool Status_Compat_T();
LIBTRITON_API void freePayload(Payload *payload);
#ifdef __cplusplus
}
#endif
- 需要发送的数据按结构体
KeyValue
构造,将KeyValue
数组传入发送函数Send()
中;- 带有
_T
后缀的函数为包含执行时间输出的函数,以便于测试- 带有
_Compat
后缀的函数为兼容模式函数,一般情况下不需使用Receive
函数必须由调用者定期调用以获取消息
编写程序,在适当的时机以适当的频率调用发送和接收方法即可。可参考教程中的示例程序。
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
// Import the header
#include "libtriton.h"
enum
{
eLedBlink = 1,
eLedOn,
eLedOff
};
const unsigned int iMaxSize = 256;
static bool isExit = false;
static int iLedStatus = eLedBlink;
DWORD WINAPI MyReceiveThread(LPVOID lpParam);
int SendDataToServer(string led1_state,string led2_state);
void LedOn();
void LedOff();
void LedBlink();
int main()
{
DWORD dwThreadId;
HANDLE ThreadHandle;
ThreadHandle = CreateThread(NULL,0,MyReceiveThread,NULL,0,&dwThreadId);
if (ThreadHandle == NULL)
{
printf("Create thread error\n");
return -1;
}
//Get UUID
char uuid[32] = { 0 };
GetUUID(uuid);
printf("uuid %s\n", uuid);
// Get MQTT connection status
bool online = Status();
if (online)
{
printf("Network is connected\n");
}
else
{
printf("Network is disconnect\n");
}
while (!isExit)
{
if (iLedStatus == eLedOn)
{
LedOn();
}
else if (iLedStatus == eLedOff)
{
LedOff();
}
else if (iLedStatus == eLedBlink)
{
LedBlink();
}
Sleep(500);
// Send the LED status to server
}
system("pause");
WaitForMultipleObjects(1, &ThreadHandle, TRUE, INFINITE);
return 0;
}
DWORD WINAPI MyReceiveThread(LPVOID lpParam)
{
while (!isExit)
{
// Receive data from Neptune
Payload *payload = Receive();
// Check if data size is not zero
if (payload->size > 0)
{
for (int i = 0; i < payload->size; ++i)
{
string strKey = payload->keyValue[i].key;
string strValue = payload->keyValue[i].value;
if (strcmp(strKey.c_str(),"switch") == 0)
{
if (strcmp(strValue.c_str(),"ALL_ON") == 0)
{
iLedStatus = eLedOn;
}
else if (strcmp(strValue.c_str(), "ALL_OFF") == 0)
{
iLedStatus = eLedOff;
}
else if (strcmp(strValue.c_str(), "NORMAL") == 0)
{
iLedStatus = eLedBlink;
}
}
//printf("%d. key: %s, value: %s", i, payload->keyValue[i].key, payload->keyValue[i].value);
}
}
// Use `freePayload` helper function to free the payload
freePayload(payload);
Sleep(1000);
}
return 0;
}
void LedOn()
{
printf("Led1 ●,Led2 ●\n");
SendDataToServer("On", "On");
}
void LedOff()
{
printf("Led1 ○,Led2 ○\n");
SendDataToServer("Off", "Off");
}
void LedBlink()
{
printf("Led1 ○,Led2 ●\n");
SendDataToServer("Off", "On");
Sleep(500);
printf("Led1 ●,Led2 ○\n");
SendDataToServer("On", "Off");
}
int SendDataToServer(string led1_state, string led2_state)
{
// Let's say we have 5 pairs of key-values that we need to send
KeyValue kv[2];
//new space what you need
for (int i = 0; i < 2; i++)
{
kv[i].key = new char[iMaxSize];
kv[i].value = new char[iMaxSize];
}
// Write keys/values to the structs
sprintf_s(kv[0].key, iMaxSize, "led1");
sprintf_s(kv[0].value, iMaxSize, "%s",led1_state.c_str());
sprintf_s(kv[1].key, iMaxSize, "led2");
sprintf_s(kv[1].value, iMaxSize, "%s", led2_state.c_str());
// Send the key values to server and get its return value
int ret = Send(kv, 2);
for (int k = 0; k < 2; k++)
{
delete kv[k].key;
delete kv[k].value;
}
return ret;
}
结果测试将使用Neptune上的开发者面板
进行,开发者面板
的作用是查看平台数据的交互结果是否正确,以便提高调试效率,并非最终的数据应用方式。
STEP#01
在Neptune中打开需要调试的对象设备,同时请注意设备的状态需要是“在线”,如果设备不在线,请检查:
- Triton是否正确运行;
- 网络连接是否正确;
STEP#02
打开开发者面板
;
STEP#03
选择密令项[说明1] start_data
,并点击按钮推送密令到设备
,点击后Triton会接收到该密令,并将数据打印在开发者面板之上。
说明1
密令项指Neptune和Triton之间的内部沟通指令,用户也可以向设备推送自定义的沟通指令,以实现用户自定义的功能;
STEP#04
观察开发面板的数据输出窗口是否已经打印出您上传的数据,数据格式为json,您上发的数据位于data标签中,其它的键值为Neptune内部使用,用户不必关注。
STEP#05
数据上传测试完成。
STEP#01
打开开发者面板
;
STEP#02
编写向下推送的密令,向下发送的密令只需要符合json格式(即key/value格式)即可,内容没有特定的要求,只需要您的程序能够使用即可。比如,用户期望推送"300秒后关机"到设备上,让其执行关机,那么我们可以编写以下内容:
{
"action":"shutdown",
"delay":"300"
}
STEP#03
将上述密令粘贴到密令输入框入,然后点击推送。消息正确推送时,界面不会有任何的错误提示,如果有出现错误提示,按提示的内容检查即可。
STEP#04
数据推送下去后,需要使用r
命令进行数据读取,如果不读取数据,将一直留存在列队中。每次通过r
命令读取后,服务器中的消息就会减少一条,直到全部取完。以下我们使用SocketTool作为测试的工具:
这里看到,推送的数据都收到了,但数据里多了一项uuid,这一项是系统默认会带上的,用于标记数据是发给哪一个设备。
{
"action":"shutdown",
"delay":"300",
"uuid":"6ed92f55a083f1038b005eb28ef0c760"
}
此时我们再向Triton发送r
命令,可以看到,所有数据取完后,Triton回复NODATA
:
STEP#05
数据下发测试完成。
- 由于Modbus协议本身的设计规范,无法实现下发数据的功能,即不能够实现从Neptune向您的设备推送数据;
- 考虑到实际安全性的问题,Modbus协议暂不考虑实现修改存储区数值的功能,仅保留数据读取的功能。
工作流程:推送配置 -> 读取数据
STEP#01
在Neptune中打开需要调试的对象设备,同时请注意设备的状态需要是“在线”,如果设备不在线,请检查:
- Triton是否正确运行;
- 网络连接是否正确;
STEP#02
打开开发者面板
;
STEP#03
选择密令项[说明1]modbus_setting_tcp
说明1
密令项指Neptune和Triton之间的内部沟通指令,用户也可以向设备推送自定义的沟通指令,以实现用户自定义的功能;
右侧出现密令的详细内容,我们需要修改密令的内容,建议将密令内容复制到文本处理工具中编辑后再粘贴到此窗口:
{
"action": "modbus",
"type": "settings",
"uuid": "IdeaBoxPro-Left",
"details": {
"protocol": "tcp",
"address": "192.168.1.1",
"slave_id": 1,
"dataset": [
{
"key": "switches 1",
"region": "coilro",
"address": 0,
"length": 8
},
{
"key": "switches 2",
"region": "coilrw",
"address": 0,
"length": 16
}
]
}
}
您需要修改的部分为 address
, slave_id
以及dataset
a. address
:即Modbus设备的IP地址;
"address": "192.168.1.1"
b. slave_id
:即Modbus设备的从站ID;
"slave_id": 1
c. dataset
:即通过Modbus协议读取的数据组,dataset为列表,dataset中的每一个元素为需要读取的数据,每个数据由数据编号
、读取区域
、起始地址
和读取长度
构成,其中数据编号
与3.2.1 添加数据定义
中所述的数据定义
一一对应;
"dataset": [
{
"key": "temp",
"region": "coilro",
"address": 0,
"length": 8
},
{
"key": "humidity",
"region": "coilrw",
"address": 0,
"length": 16
}
]
以上配置表示通过Modbus协议读取两组数据:
- 第一组:从
coilro
(Coil)中起始地址为0的位置读取长度为8的数据,数据对应数据定义中的temp
;- 第二组:从
coilrw
(Discret Input)中起始地址为0的位置读取长度为16的数据,数据对应数据定义中的humidity
;
STEP#04
当配置内容确定后,将全部的密令内容粘贴到密令窗口中,点击推送密令到设备
STEP#05
选择密令modbus_read
,将按第4点中的配置内容向设备请求数据,并将结果返回到输出面板中。
STEP#01
在Neptune中打开需要调试的对象设备,同时请注意设备的状态需要是“在线”,如果设备不在线,请检查:
- Triton是否正确运行;
- 网络连接是否正确;
STEP#02
打开开发者面板
;
STEP#03
选择密令项[说明1]modbus_ports
,该密令能够将计算机上的串口列表返回供用户选择,如果您已经清楚您设备的连接串口,可以跳过此步骤。
该计算机共有三个串口,本示例中的设备连接在串口/dev/ttyS0
上。
说明1
密令项指Neptune和Triton之间的内部沟通指令,用户也可以向设备推送自定义的沟通指令,以实现用户自定义的功能;
STEP#04
选择密令项modbus_setting_rtu
;
右侧出现密令的详细内容,我们需要修改密令的内容,建议将密令内容复制到文本处理工具中编辑后再粘贴到此窗口:
{
"action": "modbus",
"type": "settings",
"details": {
"protocol": "rtu",
"serial_port": "/dev/ttyS0",
"baudrate": 9600,
"databits": 8,
"parity": "none",
"stopbits": 1,
"slave_id": 1,
"uuid": "IdeaBoxPro-Right",
"dataset": [
{
"key": "temp",
"region": "coilro",
"address": 0,
"length": 8
},
{
"key": "humidity",
"region": "coilrw",
"address": 0,
"length": 16
}
]
}
}
您需要修改的部分为 serial_port
、baudrate
、databits
、parity
、stopbits
、slave_id
、dataset
a. serial_port
:计算机与设备相连的串口;
"serial_port": "/dev/ttyS0";
b. baudrate
:波特率;
"baudrate": 9600
c. databits
:数据位;
"databits": 8
d. parity
:奇偶校验;
"parity": "none"
d. stopbits
:停止位;
"stopbits": 1
e. slave_id
:从站ID;
"slave_id": 1
f. dataset
:即通过Modbus协议读取的数据组,dataset为列表,dataset中的每一个元素为需要读取的数据,每个数据由数据编号
、读取区域
、起始地址
和读取长度
构成,其中数据编号
与3.2.1 添加数据定义
中所述的数据定义
一一对应。
"dataset": [
{
"key": "temp",
"region": "coilro",
"address": 0,
"length": 8
},
{
"key": "humidity",
"region": "coilrw",
"address": 0,
"length": 16
}
]
以上配置表示通过Modbus协议读取两组数据:
- 第一组:从
coilro
(Coil)中起始地址为0的位置读取长度为8的数据,数据对应数据定义中的temp
;- 第二组:从
coilrw
(Discret Input)中起始地址为0的位置读取长度为16的数据,数据对应数据定义中的humidity
;
STEP#05
当配置内容确定后,将全部的密令内容粘贴到密令窗口中,点击推送密令到设备
STEP#06
选择密令modbus_read
,将按第4点中的配置内容向设备请求数据,并将结果返回到输出面板中。
结果测试将使用Neptune上的开发者面板进行,开发者面板的作用是查看平台数据的交互结果是否正确,以便提高调试效率,并非最终的数据应用方式。
STEP#01
在Neptune中打开需要调试的对象设备,同时请注意设备的状态需要是“在线”,如果设备不在线,请检查:
- Triton是否正确运行;
- 网络连接是否正确;
STEP#02
打开开发者面板
;
STEP#03
选择密令项[说明1] start_data
,并点击按钮推送密令到设备
,点击后Triton会接收到该密令,并将数据打印在开发者面板之上。
说明1
密令项指Neptune和Triton之间的内部沟通指令,用户也可以向设备推送自定义的沟通指令,以实现用户自定义的功能;
STEP#04
观察开发面板的数据输出窗口是否已经打印出您上传的数据,数据格式为json,您上发的数据位于data标签中,其它的键值为Neptune内部使用,用户不必关注。
STEP#05
数据上传测试完成。
STEP#01
打开开发者面板
;
STEP#02
编写向下推送的密令,向下发送的密令只需要符合json格式(即key/value格式)即可,内容没有特定的要求,只需要您的程序能够使用即可。比如,用户期望推送"300秒后关机"到设备上,让其执行关机,那么我们可以编写以下内容:
{
"action":"shutdown",
"delay":"300"
}
STEP#03
将上述密令粘贴到密令输入框入,然后点击推送。消息正确推送时,界面不会有任何的错误提示,如果有出现错误提示,按提示的内容检查即可。
STEP#04
数据推送下去后,按上述说明使用triton_recv()
进行读取,以下为程序输出结果:
这里看到,推送的数据都收到了,但数据里多了一项uuid,这一项是系统默认会带上的,用于标记数据是发给哪一个设备。
{
"action":"shutdown",
"delay":"300",
"uuid":"6ed92f55a083f1038b005eb28ef0c760"
}
此时我们再调用triton_recv()
方法,可以看到,所有数据取完后,Triton回复NODATA
:
STEP#05
数据下发测试完成。