[关闭]
@marsleung 2020-03-25T10:48:25.000000Z 字数 13386 阅读 7841

Neptune工业设备物联云平台教程(一) ② 使用Triton for WinCE连接您的设备

triton desktop neptune wince


1. 概述

本文将介绍,如何通过 Triton WinCE 把您的设备连接到 Neptune工业设备物联云平台,体验快速连接并传输数据的乐趣。

1.1 适用场景

Triton WinCE 适用于您的控制程序或者您的逻辑程序运行于WinCE(x86)之上(最普遍的情况为您的控制器运行操作系统,并且您对操作系统有操作的权限),通过您的程序和Triton交互,实现设备连接和数据传输的功能。

适配开发语言:

  • EVC (WinCE6)
  • OtoStudio V2.3
  • CoDeSys V2.3

交互方式为:

如果您使用的运行平台为Windows或者Linux,请参考以下文档:

使用Triton for Windows连接您的设备
使用Triton for Linux连接您的设备

1.2 连接流程

Untitled Diagram (1).png-10.5kB

1.3 注意事项

  1. 请确保您的程序运行在WinCE 6之上
  2. 下载Triton WinCE,并确保您的控制器能够运行Triton WinCE(x86);
  3. 请确保你的网络连接能正确连接到英特网;
  4. 请确保您的程序能够调用动态库(.dll);

2. 使用Triton连接Neptune

2.1 注册Neptune账号

STEP#01
访问 https://www.neptune-iiot.net, 点击右上角注册;
2017-09-13_14-03-18.png-55.2kB

STEP#02
填写注册信息,注册分为三个步骤:
a) 填写账户信息(使用邮件或者手机号码注册);
2017-09-13_14-18-24.png-52.9kB

b) 验证账户信息(使用邮件或者手机号码接收验收激活邮件或者验证码);
2017-09-13_14-21-41.png-50.7kB
2017-09-13_14-22-47.png-82.2kB
2017-09-13_14-23-24.png-207.4kB
以邮箱注册为例子,将收到上述邮件。点击激活邮箱,跳转到团队创建界面。

c) 创建或者加入一个团队[说明1], 完成注册;

说明1:团队
团队的含义是一个域,用来为用户划定一个空间。用户创建团队时,会自动成为该团队的管理员,别的用户可以申请加入您的团队,您也可以在团队中邀请用户加入。
说明2:申请加入
当申请加入一个团队时,需要对方团队的管理员通过您的请求。请在申请加入后,耐心等待通过。

STEP#03 注册完成
注册完成后,页面跳转到登录界面。您可以使用您的账号密码进行登录。
2017-09-13_15-01-46.png-108.5kB

本文档关注使用Triton将设备连接至Neptune,因此平台功能在本文档中不作过多介绍,平台功能的介绍将在其它文档中介绍。

2.2 在Neptune中创建设备

在Neptune账号注册完成后,我们需要在Neptune中“创建一个设备”,这个“设备”将获得一个全平台唯一的序列号,并且和实体设备一一对应起来。

STEP#01
点击左侧菜单栏分组设备列表,选中菜单设备,右侧出现设备列表,此时设备列表显示为空。
2017-09-13_15-17-57.png-62.6kB

点击列表上方创建按钮,出现以下对话框:
2017-09-13_15-28-04.png-52.9kB

STEP#02
为您的设备输入一个名称和描述,其它的栏位将会在平台使用教程中说明。

STEP#03
点击确认后,Neptune为该设备生成设备序列号以及团队令牌。上述信息是设备通过Triton能正确连接到Neptune的重要信息,后续仍可以在平台中查询得到。
2017-09-13_15-32-33.png-57.9kB

STEP#04
再次返回到设备列表,就可以看到您的设备已经添加到Neptune中了。
2017-09-13_15-44-04.png-53.2kB

2.3 下载Triton

Triton WinCE
x86 https://www.neptune-iiot.net/triton-release/triton-wince-386.zip

Triton目前支持以下版本:
Windows(x86/x64)WinCE(x86)Linux(x86/x64/ARMv5以上/AArch64),请按实际情况选择适配版本。

2.4 运行Triton

STEP#01
triton-wince-386.zip解压到WinCE文件目录\Hard Disk之下。
2017-09-14_17-27-41.png-107.6kB

triton-wince-386.zip解压后包含以下文件:
2017-09-14_17-32-16.png-8kB

  • Triton.exe: 主程序
  • options.ini: 配置文件
  • Resources:相关的资源目录

当Triton正常运行后,该目录还会自动产生一个Log文件夹,用于存放日志文件。

STEP#02
在运行Triton前,需修改Triton的配置文件。请使用文本编辑器打开配置文件options.ini

  1. #triton client config file
  2. #服务器连接信息
  3. [server]
  4. #设备在Neptune中的<序列号>
  5. uuid=
  6. #Neptune用户的<团队令牌>
  7. token=
  8. #服务器地址
  9. address=www.neptune-iiot.net
  10. #服务器端口
  11. port=9883
  12. #本地网络配置
  13. [network]
  14. #managed=0: 由用户自行配置网络,不使用以下网卡配置;
  15. #managed=1: 用以下网卡配置来配置本地网络;默认使用此项;
  16. managed=1
  17. #设备有两个网口时,建议一个网口用于连接Neptune,另一个网口用于本地开发调试使用;以下网卡1用于上网,网卡2用于本地调试。
  18. #网卡1
  19. #nic0_network_type可选项:dhcp (自动分配) / static(静态设置)
  20. nic0_network_type=dhcp
  21. nic0_ip_address=192.168.1.2
  22. nic0_netmask=255.255.255.0
  23. nic0_gateway=192.168.1.1
  24. nic0_dns=192.168.1.1
  25. #网卡2
  26. #nic1_network_type可选项:dhcp (自动分配) / static(静态设置)
  27. nic1_network_type=static
  28. nic1_ip_address=192.168.0.2
  29. nic1_netmask=255.255.255.0
  30. nic1_gateway=
  31. nic1_dns=
  32. #自启动程序
  33. [start_up]
  34. #请填写程序的绝对路径,如:program0=\Hard Disk\CPAC\GRT.exe
  35. program0=
  36. program1=
  37. program2=

您需要修改[server]中的uuid(设备序列号)以及token(团队令牌),将您创建的设备的序列号及您团队的令牌填写在这里:

  1. #服务器连接信息
  2. [server]
  3. #设备在Neptune中的<序列号>
  4. uuid=6ed92f55a083f1038b005eb28ef0c760
  5. #Neptune用户的<团队令牌>
  6. token=05712fb7cf95547d3e0f2ad076c3db75
  7. #服务器地址
  8. address=www.neptune-iiot.net
  9. #服务器端口
  10. port=9883

修改完成后,保存options.ini

STEP#03
双击运行triton.exe, 右下角任务栏出现triton的程序图标,并且在网络不可用或者配置文件内容填写错误时,显示无法连接图标。客户端离线.png-2.2kB

如果网络可用且配置文件内容正确,triton将显示已链接图标。2017-09-14_18-01-57.png-2.1kB

STEP#04
建议创建Triton的自启动快捷方式,以便控制器重新启动时,Triton能够自动运行起来。

a) 定位到triton程序目录,右击triton.exe, 点击Copy(复制)
2017-09-15_11-45-34.png-23.6kB

b) 移动到\Hard Disk\StartUp目录,点击Paste Shortcut(粘贴为快捷方式)
2017-09-15_11-46-11.png-47kB

c) 完成上述操作后,在控制器重启时,Triton也能够自动启动。

2.5 测试连接是否成功

打开Neptune,设备列表,查看列表中的设备是否已经显示在线,在线表示Triton与Neptune已经成功通讯。如果依然显示为离线,请检查:

2017-09-13_17-13-09.png-34.5kB

3. 使用Triton与Neptune进行数据交互

3.1 概述

Triton目前提供了以下数据交互的方式:

3.2 定义您需要传输的数据

所有需要传输的数据都需要先在Neptune中先定义,Neptune中称为数据定义,每一个设备需要维护一份数据定义。如果数据不事先定义好,在数据传输时,平台会把无定义的数据丢弃。

3.2.1 添加数据定义

STEP#01
从设备列表中找到您需要添加数据定义的设置,点击设备名称进入设备表单;
2017-09-13_18-52-06.png-93.9kB

STEP#02
采用key/value模式(即编号/值)规划好您需要传输的数据,您需要为每个需要传输的变量定义一个在本设备中唯一的编号,建议编写具有阅读性、便于理解的编号;比如我们要传输以下内容,编号规划如下:

  • 温度:temp,数字
  • 湿度:humidity, 数字
  • 照度:illuminance, 数字
  • 是否工作:is_running, 布尔
  • 工作状态:status, 文本

STEP#03
将上述内容输入到数据定义表格中;
a) 点击添加,在对话框中逐项输入第2点中的范例数据[说明1]
2017-09-14_10-01-26.png-161kB

说明1
1. 数据ID由数字和字母组成,不能包含特殊字符: + - * / > < = % . \ & $ # @, 但可以包含 _ (下划线)。
2. 数据ID名称以及数据类型为必填项,其中数据类型可选值为:数字(不区分整形和浮点型)、字符布尔类型

b) 如果您的数据存在枚举型(即用数值代表一个选项,例如:1->男,2->女),可以使用数据转义数据转义会将得到的数据值,直接翻译为转义值
2017-09-14_10-20-07.png-124.2kB

c) 全部添加完成后,效果如下:
2017-09-14_10-20-56.png-27.6kB

STEP#04
每个设备都需要有这样一份数据定义,首个设备需要按照上述步骤手动创建,创建后可以将其保存为模板或者导出Excel方便下次直接引用或者使用Excel文件导入,以减少重复的操作次数;

3.3 集成Triton动态库到您的程序

根据您使用不同的开发语言及平台,集成方式有所不同,请根据您的实际情况选择集成方法。

3.3.1 OtoStudio2.3/CoDeSys2.3 集成 Triton

3.3.1.1 下载Triton动态库

Triton WinCE Library - CPAC
cpac https://www.neptune-iiot.net/triton-release/libs/triton-wince-386-cpac.zip

3.3.1.2 动态库说明

下载解压后,包含以下文件:
image_1bt93g8ih1mutsubvtm2jt1kmo9.png-10kB

  • triton_cpac.lib: OtoStudio的外部库,需要将其添加到您的工程中;
  • triton_cpac.dll: triton_lib_cpac.lib调用,充当函数入口 ,相当于是头文件的作用;
  • triton_lib.dll: 接口函数库,实现数据的收发的具体逻辑;

triton_cpac.lib包含结构体定义

该结构体表示数据从控制器发送至Neptune时,需要以此数据类型进行构造并发送;

  1. TYPE TritonDataSend : (*发送结构体*)
  2. STRUCT
  3. iSize: UDINT; (*发送的变量组数*)
  4. Payload: ARRAY[0..499] OF Payload;
  5. END_STRUCT
  6. END_TYPE
  7. TYPE TritonDataRecv : (*接收结构体*)
  8. STRUCT
  9. iSize: UDINT; (*接收的变量组数*)
  10. Payload: ARRAY[0..31] OF Payload;
  11. END_STRUCT
  12. END_TYPE
  13. TYPE Payload : (*变量结构体*)
  14. STRUCT
  15. szKey: ARRAY[0..63] OF BYTE; (*数据ID,对应Neptune的数据ID*)
  16. szValue: ARRAY[0..63] OF BYTE; (*数据值,对应的数据值*)
  17. END_STRUCT
  18. END_TYPE
  19. TYPE TritonDataSendSampling : (*采样发送结构体*)
  20. STRUCT
  21. iSize: UDINT; (*变量组数*)
  22. szTimeStart: ARRAY[0..63] OF BYTE; (*采样开始时间*)
  23. szInterval: ARRAY[0..63] OF BYTE; (*采样间隔*)
  24. Payload: ARRAY[0..199] OF PayloadSampling;
  25. END_STRUCT
  26. END_TYPE
  27. TYPE PayloadSampling : (*采样变量结构体*)
  28. STRUCT
  29. szKey: ARRAY[0..63] OF BYTE; (*数据ID,对应Neptune的数据ID*)
  30. szValue: ARRAY[0..254] OF BYTE; (*数据值,对应的数据值*)
  31. END_STRUCT
  32. END_TYPE

triton_cpac.dll包含五个接口函数

  1. (*发送数据:普通*)
  2. FUNCTION triton_send : INT
  3. VAR_INPUT
  4. Param: POINTER TO TritonDataSend;
  5. END_VAR
  6. VAR
  7. END_VAR
  8. (*接收数据:普通*)
  9. FUNCTION triton_recv : INT
  10. VAR_INPUT
  11. Param: POINTER TO TritonDataRecv;
  12. END_VAR
  13. VAR
  14. END_VAR
  15. (*发送数据:采样*)
  16. FUNCTION triton_send_sampling : INT
  17. VAR_INPUT
  18. Param: POINTER TO TritonDataSendSampling;
  19. END_VAR
  20. VAR
  21. END_VAR
  22. (*读取Triton运行状态*)
  23. FUNCTION triton_status : INT
  24. VAR_INPUT
  25. END_VAR
  26. VAR
  27. END_VAR
  28. (*读取设备UUID*)
  29. FUNCTION triton_uuid : INT
  30. VAR_INPUT
  31. Param: POINTER TO STRING;
  32. END_VAR
  33. VAR
  34. END_VAR

3.3.1.3 将动态库引入您的工程

STEP#01
将动态链接库(.dll)放置到控制器CPAC目录下。
image_1bt93pn9emlnhif1q76k4p1duhm.png-119.5kB

STEP#02
配置RTS3S.CFG文件
image_1bt93tc171fnm1c6t1pvc19jtffi13.png-136.8kB

配置文件内容如下:

  1. [IODRIVERLIST]
  2. ;MODULE0=3SSJA1000P
  3. MODULE0=GT8003S
  4. INITFCT0=IODrvInit
  5. ;INITFCT1=IODrvInit
  6. [PLC]
  7. DisableSerialProgramming=Yes
  8. SETTINGS_FROM_CFG=Yes
  9. ;USE SYSINTR_TIMING AS TICK=No
  10. CESchedulerSleepTillTick=Yes
  11. Files=\hard disk\CPAC
  12. BootMode=Run
  13. MapPhysical0=Shm
  14. MapPhysical1=Shm1
  15. NoSetMemoryDivision=1
  16. ;UseIRQ10ForExternalEventTask=Yes
  17. ;CEGetTimeSyncWithTick=Yes
  18. ;DataSize=0x3000000
  19. UseIRQ11ForExternalEventTask=Yes
  20. [Googol]
  21. UsePortAddress=0
  22. UseIsaCard=0
  23. IsaBaseAddress=0x300
  24. IsaIrqNumber=9
  25. RetainOffset=0x800
  26. IOOffset=0x0
  27. IOOputOffset=0x100
  28. IODiagnosis=0x1f0
  29. pIOOffset=0x0
  30. pIOOputOffset=0x0
  31. pIODiagnosis=0x0
  32. ideaType=0
  33. IOExtendType=0
  34. [RETAIN]
  35. ;TYPE=Task
  36. SIZE=0x300
  37. [External Dlls]
  38. CheckExtRef=Yes
  39. Path0=triton_cpac
  40. [VISUALIZATION]
  41. TargetVisuLoadOnlyCurrentUsedBitmaps=Yes
  42. FONT0=SUNFON.ttf
  43. FONT1=MSYH.ttf
  44. [SJA1000P]
  45. SJAPCIScan=1
  46. SJAInterruptTaskPriority=0
  47. SJAOutputControlMode=0x1a
  48. ;SJASendTestMsgAfterInit=1
  49. SJAPCIVendorId=0x11d4
  50. SJAPCISubVendorId=0x0
  51. SJAPCIDeviceId=0x1535
  52. SJAPCISubsystemId=0x0
  53. SJAXTALFrequency=24000000
  54. ;TargetVisuWindowBottom=300
  55. ;TargetVisuWindowLeft=0
  56. ;TargetVisuWindowRight=400
  57. ;TargetVisuWindowTop=0

[External DLLs]中增加cpac_gagent.lib作为调用项:

  1. [External Dlls]
  2. CheckExtRef=Yes
  3. Path0=triton_cpac

STEP#03
添加triton_cpac.lib到您的工程中:
添加库1.png-268.2kB

STEP#04
编写您的OtoStudio程序,在适当的时机以适当的频率调用发送和接收方法即可。可参考教程中的示例程序。

3.3.1.4 示例程序

  1. PROGRAM PLC_PRG
  2. VAR
  3. iSize: INT;(*发送数据的组数*)
  4. sTritonDataSend: TritonDataSend; (*发送的数据的结构体,结构体中发送数据的结构体中的szKeyszValue长度均为64个字节(由于内存长度限制)*)
  5. sTritonDataRecv: TritonDataRecv;(*从Neptune获取的数据*)
  6. aTempKey: ARRAY [0..99] OF string;
  7. aTempNote: ARRAY [0..99] OF string;
  8. strJsonData: ARRAY [0..9] OF JsonDataString;
  9. (*
  10. 需要在<数据类型>中定义以下结构体:
  11. TYPE JsonDataString :
  12. STRUCT
  13. szKey:STRING;
  14. szValue:STRING;
  15. END_STRUCT
  16. END_TYPE
  17. *)
  18. loop: WORD := 1000; (* 1000ms给一次实时数据 *)
  19. rt: INT;(*调用接口函数返回值*)
  20. i: INT := 1;
  21. Delay: TON;
  22. irandom: INT;
  23. baction_done: BOOL;
  24. END_VAR
  25. (*从Neptune获取数据*)
  26. rtn:=triton_recv(ADR(sTritonDataRecv));
  27. IF sTritonDataRecv.iSize<>0 THEN
  28. FOR i:=0 TO 9 DO
  29. SysMemCpy(ADR(strJsonData[i].szKey),ADR(sTritonDataRecv.payload[i].szKey),SIZEOF(sTritonDataRecv.payload[i].szKey));
  30. SysMemCpy(ADR(strJsonData[i].szValue),ADR(sTritonDataRecv.payload[i].szValue),SIZEOF(sTritonDataRecv.payload[i].szValue));
  31. END_FOR
  32. END_IF
  33. IF strJsonData[1].szKey='0100' THEN
  34. bstrart_lift:=STRING_TO_BOOL(strJsonData[1].szValue);
  35. baction_done:=TRUE;
  36. END_IF
  37. IF baction_done THEN
  38. SysMemSet(ADR(strJsonData),0,SIZEOF(strJsonData));(*清空数据缓存区*)
  39. baction_done:=FALSE;
  40. END_IF
  41. iSize:=0;
  42. aTempKey[0]:='0100H';
  43. aTempNote[0]:=INT_TO_STRING(irandom);
  44. iSize:=iSize+1;
  45. aTempKey[1]:='0101H';
  46. aTempNote[1]:=REAL_TO_STRING(50);
  47. iSize:=iSize+1;
  48. aTempKey[2]:='0102H';
  49. aTempNote[2]:=REAL_TO_STRING(25);
  50. iSize:=iSize+1;
  51. aTempKey[3]:='0103H';
  52. aTempNote[3]:=REAL_TO_STRING(8);
  53. iSize:=iSize+1;
  54. aTempKey[4]:='0104H';
  55. aTempNote[4]:=REAL_TO_STRING(40);
  56. iSize:=iSize+1;
  57. (*循环发送数据,采用的是计时器,每1S发送一次*)
  58. Delay(in:=TRUE, PT:=WORD_TO_TIME(loop), Q=>, ET=>);
  59. IF Delay.Q THEN
  60. Delay(in:=FALSE);
  61. (*给sTritonDataRecv赋值*)
  62. sTritonDataSend.iSize:=iSize;(*发送数据的组数*)
  63. FOR i:=0 TO iSize DO
  64. SysMemCpy(ADR(sTritonDataSend.payload[i].szKey), ADR(aTempKey[i]), LEN(aTempKey[i]));(*发送的keystring转化成数组的byte(库要求的是byte的数组)*)
  65. SysMemCpy(ADR(sTritonDataSend.payload[i].szValue), ADR(aTempNote[i]), LEN(aTempNote[i]));(*发送的valuestring转化成数组的byte(库要求的是byte的数组)*)
  66. END_FOR
  67. rt := triton_send(ADR(sTritonDataSend));
  68. SysMemSet(ADR(sTritonDataSend),0,SIZEOF(sTritonDataSend));(*清空数据缓存区*)
  69. END_IF

3.3.2 EVC 集成 Triton

3.3.2.1 下载Triton动态库

Triton动态库包含一个库文件和一个头文件,请根据您使用的开发语言及平台下载对应的动态库:

Triton WinCE Library - EVC
evc https://www.neptune-iiot.net/triton-release/libs/triton-wince-386-evc.zip

3.3.2.2 动态库说明

triton_lib_evc.h内容如下:

  1. #pragma once
  2. #define MAX_LENGTH 64 // 数据key以及value字符串最大长度
  3. #define MAX_SEND_PAIR 500 // 发送至平台的数据组(key+value)组数上限
  4. #define MAX_RECEIVE_PAIR 10 // 从平台接收数据组(key+value)组数上限
  5. #pragma pack(1)
  6. typedef struct _TritonPayload
  7. {
  8. char szKey[MAX_LENGTH]; //数据ID:对应Neptune的数据定义
  9. char szValue[MAX_LENGTH]; //数据值
  10. }TritonPayload;
  11. //数据传输结构
  12. typedef struct _triton_send_data
  13. {
  14. unsigned int iSize; //数据组数
  15. TritonPayload payload[MAX_SEND_PAIR];
  16. _triton_send_data()
  17. {
  18. memset(this, 0, sizeof(*this));
  19. }
  20. } TritonDataSend;
  21. //数据接收结构
  22. typedef struct _triton_receive_data
  23. {
  24. unsigned int iSize; //数据组数
  25. TritonPayload payload[MAX_RECEIVE_PAIR];
  26. _triton_receive_data()
  27. {
  28. memset(this, 0, sizeof(*this));
  29. }
  30. } TritonDataRecv;
  31. #pragma pack()
  32. #ifdef TRITON_LIB_EXPORTS
  33. #define TRITON_API extern "C" short __declspec(dllexport)
  34. #else
  35. #define TRITON_API extern "C" short __declspec(dllimport)
  36. #endif
  37. //发送数据
  38. TRITON_API triton_send(TritonDataSend *pTritonDataSend);
  39. //获取推送命令
  40. TRITON_API triton_recv(TritonDataRecv *pTritonDataRecv);
  • 需要发送的数据按结构体TritonDataSend构造,传入发送函数triton_send()中;
  • 需要接收的数据按结构体TritonDataRecv构造,传入接收函数triton_recv()中;

3.3.2.3 将动态库引入您的工程

编写程序,在适当的时机以适当的频率调用发送和接收方法即可。可参考教程中的示例程序。

3.3.2.4 示例程序

  1. // triton_lib_test.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "triton_lib_evc.h"
  5. #include <cstdlib>
  6. #include <iostream>
  7. #include <string>
  8. using namespace std;
  9. static char *TimeFormat() //Neptune时间格式
  10. {
  11. SYSTEMTIME st;
  12. GetLocalTime(&st);
  13. char szTime[64] = {0};
  14. sprintf(szTime, "%04d%02d%02d%02d%02d%02d%03d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  15. return szTime;
  16. }
  17. static DWORD WINAPI RecvDataFromNeptune(LPVOID pvParams)
  18. {
  19. while (1)
  20. {
  21. TritonDataRecv *sTritonDataRecv = new TritonDataRecv;
  22. memset(TritonDataRecv, 0, sizeof(sTritonDataRecv));
  23. int ret = triton_recv(sTritonDataRecv); //轮询Neptune是否有下发数据
  24. if (ret != 0)
  25. {
  26. cout << TimeFormat().c_str() << "call triton_recv failed, errorcode: " << ret << endl;
  27. }
  28. else
  29. {
  30. if (sTritonDataRecv->size == 0)
  31. {
  32. Sleep(100);
  33. continue;
  34. }
  35. cout << TimeFormat().c_str() << "receive data from Neptune: ";
  36. for (int i = 0; i < sTritonDataRecv->size; i++)
  37. {
  38. cout << sTritonDataRecv->payload[i].szKey << " " << sTritonDataRecv->payload[i].szValue << "\t";
  39. }
  40. cout << endl;
  41. }
  42. delete sTritonDataRecv;
  43. sTritonDataRecv = NULL;
  44. Sleep(100);
  45. }
  46. return 0;
  47. }
  48. int _tmain(int argc, _TCHAR *argv[])
  49. {
  50. HANDLE hRecvData = CreateThread(NULL, 0, RecvDataFromNeptune, NULL, 0, 0); //使用线程检测是否收到Neptune下发数据
  51. srand(GetTickCount());
  52. int i_temp = 10;
  53. while (i_temp-- > 0)
  54. {
  55. cout << endl;
  56. TritonDataSend *sTritonDataSend = new TritonDataSend;
  57. sTritonDataSend->size = 6;
  58. for (int i = 0; i < sTritonDataSend->size; ++i)
  59. {
  60. sprintf(sTritonDataSend->payload[i].szKey, "%d", i + 1);
  61. sprintf(sTritonDataSend->payload[i].szValue, "%.3f", (float)(rand() % 100) * 0.234); //生成一个随机value,用于测试
  62. }
  63. int rtn = triton_send(sTritonDataSend);
  64. if (rtn == 0)
  65. {
  66. cout << TimeFormat().c_str() << "call triton_send success." << endl;
  67. }
  68. else
  69. {
  70. cout << TimeFormat().c_str() << "call triton_send fail." << endl;
  71. return -1;
  72. }
  73. delete sTritonDataSend;
  74. sTritonDataSend = NULL;
  75. Sleep(1000);
  76. }
  77. cout << endl;
  78. cout << "Press 'Enter' key exit..." << endl;
  79. cin.get();
  80. return 0;
  81. }

3.4 测试数据交互结果

结果测试将使用Neptune上的开发者面板进行,开发者面板的作用是查看平台数据的交互结果是否正确,以便提高调试效率,并非最终的数据应用方式。

3.4.1 上传数据到Neptune

STEP#01
在Neptune中打开需要调试的对象设备,同时请注意设备的状态需要是“在线”,如果设备不在线,请检查:

  • Triton是否正确运行;
  • 网络连接是否正确;

2017-09-14_11-18-04.png-119.5kB

STEP#02
打开开发者面板;
2017-09-14_11-18-57.png-184.3kB

STEP#03
选择密令项[说明1] start_data,并点击按钮推送密令到设备,点击后Triton会接收到该密令,并将数据打印在开发者面板之上。
2017-09-14_11-35-45.png-117.6kB

说明1
密令项指Neptune和Triton之间的内部沟通指令,用户也可以向设备推送自定义的沟通指令,以实现用户自定义的功能;

STEP#04
观察开发面板的数据输出窗口是否已经打印出您上传的数据,数据格式为json,您上发的数据位于data标签中,其它的键值为Neptune内部使用,用户不必关注。
2017-09-14_11-54-17.png-150.2kB

STEP#05
数据上传测试完成。

3.4.2 下发数据到设备

STEP#01
打开开发者面板;
2017-09-14_11-18-57.png-184.3kB

STEP#02
编写向下推送的密令,向下发送的密令只需要符合json格式(即key/value格式)即可,内容没有特定的要求,只需要您的程序能够使用即可。比如,用户期望推送"300秒后关机"到设备上,让其执行关机,那么我们可以编写以下内容:

  1. {
  2. "action":"shutdown",
  3. "delay":"300"
  4. }

STEP#03
将上述密令粘贴到密令输入框入,然后点击推送。消息正确推送时,界面不会有任何的错误提示,如果有出现错误提示,按提示的内容检查即可。
2017-09-22_14-02-37.png-63.8kB

STEP#04
数据推送下去后,按上述说明使用triton_recv()进行读取,以下为程序输出结果:
2017-09-22_18-01-24.png-3.6kB

这里看到,推送的数据都收到了,但数据里多了一项uuid,这一项是系统默认会带上的,用于标记数据是发给哪一个设备。

  1. {
  2. "action":"shutdown",
  3. "delay":"300",
  4. "uuid":"6ed92f55a083f1038b005eb28ef0c760"
  5. }

此时我们再调用triton_recv()方法,可以看到,所有数据取完后,Triton回复NODATA:
2017-09-22_18-07-02.png-4.8kB

STEP#05
数据下发测试完成。

4. 在Neptune上对数据进行应用

请参考《Neptune工业设备物联云平台教程(二) 使用Neptune管理和监控您的设备》

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注