Difference between revisions of "IoTGateway/WiseSnail"

From ESS-WIKI
Jump to: navigation, search
(Callbacks)
 
(116 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
=Introduction=
 
=Introduction=
WiseSnail is the short name of Wise Sensor Network Abstract Interactive Layer. It is a layer to define the topology and behavior of sensor network. A complete device represented in WiseSnail includes one virtual gateway, one sensor connectivity interface and several sensor hubs. WiseSnail provides a form-like array which we call it infospec array to define tha parameters of sensor hub. And a form-like data array updates your real time data. So, you can easy to represent your device by creating several arrays.
+
:WiseSnail is the short name of Wise Sensor Network Abstract Interactive Layer. It is a layer to define the topology and behavior of sensor network. A complete device represented in WiseSnail includes one virtual gateway, one sensor connectivity interface and several sensor devices. WiseSnail provides a form-like array which we call it infospec array to define tha parameters of sensor device. And a form-like data array updates your real time data. So, you can easy to represent your device by creating several arrays.
=OS=
+
 
:*Ubuntu 14.04
+
= Design intention =
 +
 
 +
[[File:WiseSnail designintention.png|frameless|right|500px|WiseSnail designintention.png]]
 +
 
 +
:We refer the data handle flow on Wise-PaaS to design a data layout like right picture. There are two arrays, interface and sensor device, to implement the behavior of gateway. Each variable array includes several tags. A tag is a variable to indicate the parameter on interface or sensor device. So, we have two register functions and assign into two arrays to generate tags.<br/>
 +
 
 +
= Hardware requirements =
 +
:'''CPU architecture'''
 +
::*x86
 +
::*arm
 +
:'''Minimum ram size'''
 +
::*256kb and above.
 +
 
 +
= OS =
 +
 
 +
:
 +
*Ubuntu ( 14.04,&nbsp;16.04 )
 +
:*Yocto ( 1.5.3 Dora )
 
:*OpenWRT
 
:*OpenWRT
 +
:*Windows ( x86 )
 +
 +
= External library dependency requirements =
  
=Requirements=
 
 
#[https://www.openssl.org/ OpenSSL]
 
#[https://www.openssl.org/ OpenSSL]
 
#[http://www.eclipse.org/paho/ Paho]
 
#[http://www.eclipse.org/paho/ Paho]
 
#[https://mosquitto.org/ Mosquitto]
 
#[https://mosquitto.org/ Mosquitto]
 +
 +
=Source Code=
 +
:'''GitHub'''<br>
 +
::[https://github.com/ADVANTECH-Corp/WiseSnail.git https://github.com/ADVANTECH-Corp/WiseSnail.git]
 +
:'''Source tree'''<br>
 +
::{| class="wikitable" style="width: 50%"
 +
|-
 +
| inc || header files
 +
|-
 +
| library || includes [[IoTGateway/AdvJSON|AdvJSON]], AdvLog, WiseCore
 +
|-
 +
| sample || a simple sample to test library.
 +
|-
 +
| source|| source files
 +
|}
  
 
=Configure=
 
=Configure=
'''Optional'''
+
:'''Optional'''
{| class="wikitable" style="width: 50%"
+
::{| class="wikitable" style="width: 50%"
 
| --disable-paho|| Disable Paho support.
 
| --disable-paho|| Disable Paho support.
 
|-
 
|-
 
| --disable-mosquitto|| Disable Mosquitto support.
 
| --disable-mosquitto|| Disable Mosquitto support.
 
|}
 
|}
 +
 +
:'''Compile'''<br>
 +
::You can perform the following steps to build this library.
 +
::{| class="wikitable" style="width: 100%"
 +
|
 +
./configure <br>
 +
'''Or'''<br>
 +
./configure --host=<your cross compiler> --prefix=<install path><br>
 
<br>
 
<br>
'''Compile'''<br>
+
make<br>
You can perform the following steps to build this library.
+
make install
./configure
+
|}
'''Or'''
 
./configure --host=<your cross compiler> --prefix=<install path>
 
 
make
 
make install
 
  
'''Compile script'''<br>
+
:'''Compile script'''<br>
./snailconf.sh
+
::This script combines compile steps and version control handling.
 +
::{| class="wikitable" style="width: 100%"
 +
|
 +
./snailconf.sh<br>
 +
'''Or'''<br>
 +
./snailconf.sh --host=<your cross compiler> --prefix=<install path>
 +
|}
  
=Structures=
+
:'''Build sample'''
==Infospec==
+
::Enter the folder of sample,and make it directly. You can change the MQTT library by editing makefile.
 +
 
 +
=Capability=
 +
:{||
 +
<source lang="C">
 +
#define MAX_DEVICES 16    //The Maximum number of sensor device
 +
#define MAX_ITEMS 16      //The Maximum number of sensor value
 +
#define MAX_CMDS 16        //The Maximum number of command that can be processed in one second.
 +
</source>
 +
|}
 +
 
 +
= Structures =
 +
== Data Type ==
  
 
{|
 
{|
 
|-
 
|-
| '''Description'''
+
| '''Description'''<div style="margin-left:0.847cm;  margin-right:0cm">
<div style="margin-left:0.847cm;margin-right:0cm;">
+
We provide several types to describe the type of data.
The infospec structure defines your parameters in sensor hub. Those parameter structures will represented in Wise-Paas like a tag. this structure includes two callback functions. You can use the callbacks to define your own get and set function. The parameter button on Wise-Paas will different by whether the set function is defined or not. If the set function is defined, the value is writeable by users on Wise-Paas.
+
</div>
 +
|-
 +
|
 +
 
 +
<syntaxhighlight lang="C">
 +
    WISE_VALUE  //for numeric value
 +
    WISE_FLOAT  //for floating point
 +
    WISE_STRING //for string
 +
    WISE_BOOL  //for boolean
 +
    WISE_CUSTOMIZE          //for a customize value, use the following type definition
 +
        WISE_BASE64        // a base64 format data.
 +
</syntaxhighlight>
 +
|}
 +
 
 +
== Infospec ==
 +
 
 +
{|
 +
|-
 +
| '''Description'''<div style="margin-left:0.847cm; margin-right:0cm">
 +
The infospec structure defines your parameters in sensor device. Those parameter structures will represented in Wise-Paas like a tag. It includes two callback function pointers. You can use the callback pointers to define your own get and set function. The button on Wise-Paas for GPIO will be differed from whether the set function is assigned or not. If the set function is assigned, the value is writable by users on Wise-Paas.
 
</div>
 
</div>
 
|-
 
|-
 
|  
 
|  
 +
 +
<syntaxhighlight lang="C">
 
     struct WiseSnail_InfoSpec{
 
     struct WiseSnail_InfoSpec{
 
       WiseSnail_DataType type;
 
       WiseSnail_DataType type;
Line 48: Line 124:
 
         float value;
 
         float value;
 
         char *string;
 
         char *string;
 +
        WiseSnail_RAW *raw;
 
       };
 
       };
 
       float min;
 
       float min;
Line 54: Line 131:
 
       WiseSnail_SetValue setValue;
 
       WiseSnail_SetValue setValue;
 
       WiseSnail_GetValue getValue;
 
       WiseSnail_GetValue getValue;
 +
      WiseSnail_FormatType format;
 
     };
 
     };
 +
</syntaxhighlight>
 
|-
 
|-
 
| '''Example'''
 
| '''Example'''
 
|-
 
|-
|
+
|  
 +
 
 +
<syntaxhighlight lang="C">
 
     {
 
     {
 
       WISE_VALUE,                  //WiseSnail_DataType  
 
       WISE_VALUE,                  //WiseSnail_DataType  
Line 70: Line 151:
 
       NULL                        //get function
 
       NULL                        //get function
 
     }
 
     }
 +
</syntaxhighlight>
 
|}
 
|}
  
==Data==
+
== Data ==
  
 
{|
 
{|
 
|-
 
|-
| '''Description'''
+
| '''Description'''<div style="margin-left:0.847cm; margin-right:0cm">
<div style="margin-left:0.847cm;margin-right:0cm;">
+
The data structure defines your value you want to update in sensor device. The cliendId and infomation is for internal used and will be assigned while your callback function(like set) is called.
The data structure defines your value you want to update in sensor hub. the cliendId and info is for internal used and will be assigned while your callback function(like set) is called.
 
 
</div>
 
</div>
 
|-
 
|-
 
|  
 
|  
 +
 +
<syntaxhighlight lang="C">
 
     struct WiseSnail_Data{
 
     struct WiseSnail_Data{
 
       WiseSnail_DataType type;
 
       WiseSnail_DataType type;
Line 88: Line 171:
 
         float value;
 
         float value;
 
         char *string;
 
         char *string;
 +
        WiseSnail_RAW *raw;
 
       };
 
       };
 +
      WiseSnail_FormatType format;
 
       char *clientId;              //internal
 
       char *clientId;              //internal
 
       WiseSnail_InfoSpec *info;    //internal
 
       WiseSnail_InfoSpec *info;    //internal
 
     }
 
     }
 +
</syntaxhighlight>
 
|-
 
|-
 
| '''Example'''
 
| '''Example'''
 
|-
 
|-
|
+
|  
 +
 
 +
<syntaxhighlight lang="C">
 
     {
 
     {
 
       WISE_VALUE,                  //WiseSnail_DataType  
 
       WISE_VALUE,                  //WiseSnail_DataType  
Line 101: Line 189:
 
       100                          //value or string
 
       100                          //value or string
 
     }
 
     }
 +
</syntaxhighlight>
 
|}
 
|}
  
==Callbacks==
+
== Callbacks ==
 +
 
 
{|
 
{|
 
|-
 
|-
Line 110: Line 200:
 
|  
 
|  
 
   typedef int (*WiseSnail_SetValue)(WiseSnail_Data *data);
 
   typedef int (*WiseSnail_SetValue)(WiseSnail_Data *data);
 +
 
|-
 
|-
 
| '''Get Callback'''
 
| '''Get Callback'''
Line 115: Line 206:
 
|  
 
|  
 
   typedef int (*WiseSnail_GetValue)(WiseSnail_Data *data);
 
   typedef int (*WiseSnail_GetValue)(WiseSnail_Data *data);
 +
 
|-
 
|-
 
| '''Sleep callback'''
 
| '''Sleep callback'''
 
|-
 
|-
|
+
|  
 
   typedef void (*WiseSnail_SleepOneSecond)(void);
 
   typedef void (*WiseSnail_SleepOneSecond)(void);
 +
 
|}
 
|}
  
Line 165: Line 258:
 
==Register==
 
==Register==
 
*'''WiseSnail_RegisterInterface'''
 
*'''WiseSnail_RegisterInterface'''
 +
::One instance only includes one interface.
 
<div style="margin-left:0.847cm;margin-right:0cm;">
 
<div style="margin-left:0.847cm;margin-right:0cm;">
 
{| class="wikitable"
 
{| class="wikitable"
Line 188: Line 282:
 
</div>
 
</div>
 
*'''WiseSnail_RegisterSensor'''
 
*'''WiseSnail_RegisterSensor'''
 +
::The maximum number of sensor devcie, please refer to MAX_DEVICES.
 
<div style="margin-left:0.847cm;margin-right:0cm;">
 
<div style="margin-left:0.847cm;margin-right:0cm;">
 
{| class="wikitable"
 
{| class="wikitable"
Line 198: Line 293:
 
! Parameter !! Description
 
! Parameter !! Description
 
|-
 
|-
| align="center" width="40%" | deviceMac|| The mac address of sensor hub.
+
| align="center" width="40%" | deviceMac|| The mac address of sensor device.
 
|-
 
|-
| align="center" | defaultName|| The default name of sensor hub.
+
| align="center" | defaultName|| The default name of sensor device.
 
|-
 
|-
| align="center" | infospec || Sensor hub parameter array.
+
| align="center" | infospec || Sensor device parameter array.
 
|-
 
|-
 
| align="center" | count|| The size of infospec.
 
| align="center" | count|| The size of infospec.
Line 236: Line 331:
 
</div>
 
</div>
  
==Update==
+
== Update ==
 +
 
 
*'''WiseSnail_Update'''
 
*'''WiseSnail_Update'''
<div style="margin-left:0.847cm;margin-right:0cm;">
+
 
 +
::You can update your data from this function by assigning a data array.
 +
<div style="margin-left:0.847cm; margin-right:0cm">
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 
| void '''WiseSnail_Update'''(char *'''deviceMac''', WiseSnail_Data* '''data''', int '''count''');
 
| void '''WiseSnail_Update'''(char *'''deviceMac''', WiseSnail_Data* '''data''', int '''count''');
 
|}
 
|}
<div style="margin-left:0.847cm;margin-right:0cm;">
+
<div style="margin-left:0.847cm; margin-right:0cm">
 
{| class="wikitable" width="50%"
 
{| class="wikitable" width="50%"
 
|-
 
|-
! Parameter !! Description
+
! Parameter
 +
! Description
 
|-
 
|-
| align="center" width="40%" | deviceMac|| The mac of device which you will update.
+
| align="center" width="40%" | deviceMac
 +
| The mac of device which you will update.
 
|-
 
|-
| align="center" | data|| Data array.
+
| align="center" | data
 +
| Data array.
 
|-
 
|-
| align="center" | count|| The size of data.
+
| align="center" | count
 +
| The size of data.
 
|}
 
|}
</div>
+
</div></div>
</div>
+
 
 +
== Main Handle Loop function ==
  
==Loop function==
 
 
*'''WiseSnail_MainLoop'''
 
*'''WiseSnail_MainLoop'''
<div style="margin-left:0.847cm;margin-right:0cm;">
+
 
 +
::This is a very important function. It includes main logic and error handling. The interval of sleepOneSec must be one second.<br/>
 +
::You also can run an external timer, but this function must be executed per one second.
 +
<div style="margin-left:0.847cm; margin-right:0cm">
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 
| void '''WiseSnail_MainLoop'''(WiseSnail_SleepOneSecond '''sleepOneSec''');
 
| void '''WiseSnail_MainLoop'''(WiseSnail_SleepOneSecond '''sleepOneSec''');
 
|}
 
|}
<div style="margin-left:0.847cm;margin-right:0cm;">
+
<div style="margin-left:0.847cm; margin-right:0cm">
 
{| class="wikitable" width="50%"
 
{| class="wikitable" width="50%"
 
|-
 
|-
! Parameter !! Description
+
! Parameter
 +
! Description
 
|-
 
|-
| align="center" width="40%" | sleepOneSec|| a callback function for sleep one second.
+
| align="center" width="40%" | sleepOneSec
 +
| a callback function for sleep one second.
 
|}
 
|}
</div>
+
</div></div>
</div>
+
 
 +
= Sample Program =
 +
 
 +
== Prerequest ==
 +
 
 +
1. Visual Studio 2015 or above.
 +
 
 +
&nbsp; &nbsp; Download URL: [https://docs.microsoft.com/zh-tw/visualstudio/install/install-visual-studio?view=vs-2019 https://docs.microsoft.com/zh-tw/visualstudio/install/install-visual-studio?view=vs-2019]
 +
 
 +
2. WISE-Agent 1.1.x
 +
 
 +
&nbsp; &nbsp; Download from WISE-PaaS/EdgeSense Portal,&nbsp;Settings Page.
 +
 
 +
3. API-GW 2.0.x
 +
 
 +
&nbsp; &nbsp; Download URL:&nbsp;[https://www.dropbox.com/s/amsooqwswabfxbk/API-GW-2.0.7.exe?dl=0 https://www.dropbox.com/s/amsooqwswabfxbk/API-GW-2.0.7.exe?dl=0]
 +
 
 +
== Sample Code Overview ==
 +
 
 +
<span style="font-size:x-small">(pseudo code)</span>
 +
 
 +
 
 +
<syntaxhighlight lang="C">
 +
 
 +
WiseSnail_InfoSpec interface[] = {
 +
{
 +
WISE_BOOL,
 +
"/Info/reset",
 +
"",
 +
0,
 +
0,
 +
1,
 +
"",
 +
Reset
 +
}
 +
};
 +
 
 +
void SetGPIO_1(WiseSnail_Data*data) {
 +
    printf("(GPIO 1) = %d\r\n",data->value);
 +
}
 +
 
 +
void SetGPIO_2(WiseSnail_Data*data) {
 +
    printf("(GPIO 2) = %d\r\n",data->value);
 +
}
 +
 
 +
/***********************CUSTOMIZE VALUE FOR BASE64*******************************/
 +
char rawData[128] = "ABCDE";
 +
WiseSnail_RAW rawItem = {
 +
    .data = rawData,
 +
    .len = 5
 +
};
 +
 
 +
int SetRAW(WiseSnail_Data *data) {
 +
    if(data->type == WISE_CUSTOMIZE) {
 +
        memcpy(&rawItem, data->raw, sizeof(rawItem));
 +
    }
 +
}
 +
 
 +
int GetRAW(WiseSnail_Data *data) {
 +
    if(data->type == WISE_CUSTOMIZE) {
 +
        memcpy(data->raw, &rawItem, sizeof(rawItem));
 +
    }
 +
}
 +
/********************************************************************************/
 +
 
 +
WiseSnail_InfoSpec infospec[] = {
 +
{
 +
WISE_STRING,
 +
"/Info/Name",
 +
"",
 +
.string = "SenHub1",  // Device Name of SenHub (*)
 +
0,
 +
0,
 +
"",
 +
//SetSHName,
 +
.getValue = GetSHName
 +
},
 +
{
 +
WISE_VALUE, //type
 +
"Temperature",     //name
 +
"Cel", //unit
 +
0,     //value[union]
 +
-100, //min
 +
200, //max
 +
"ucum.Cel" //resourceType
 +
},
 +
{
 +
WISE_VALUE, //type
 +
"Humidity", //name
 +
"%", //unit
 +
0,     //value[union]
 +
0,     //min
 +
100, //max
 +
"ucum.%" //resourceType
 +
},
 +
                {
 +
        WISE_IO_BOOL,
 +
                        "GPIO1",
 +
                        "",
 +
                        0,
 +
                        0,
 +
                        1,
 +
                        "",
 +
                        SetGPIO_1
 +
                },
 +
                {
 +
                        WISE_IO_BOOL,
 +
                        "GPIO2",
 +
                        "",
 +
                        0,
 +
                        0,
 +
                        1,
 +
                        "",
 +
                        SetGPIO_2
 +
},
 +
                {
 +
                                WISE_CUSTOMIZE,
 +
                                "RAW",
 +
                                "",
 +
                                .raw = &rawItem,
 +
                                0,
 +
                                1,
 +
                                "",
 +
                                SetRAW,
 +
                                GetRAW,
 +
                                WISE_BASE64
 +
}
 +
};
 +
 
 +
WiseSnail_Data data[] = {
 +
{
 +
WISE_VALUE, //type
 +
"Temperature", //name
 +
100 //value
 +
},
 +
{
 +
WISE_VALUE, //type
 +
"Humidity", //name
 +
55 //value
 +
},
 +
                {
 +
                                WISE_CUSTOMIZE,
 +
                                "RAW",
 +
                                .raw = &rawItem,
 +
                                WISE_BASE64
 +
}
 +
};
 +
 
 +
void sleepOneSecond() {
 +
sleep(1);
 +
}
 +
 
 +
#define SERVER_ADDRESS "rmm.wise-paas.com"
 +
 
 +
int main() {
 +
//initial
 +
WiseSnail_Init("IotGW",NULL, NULL, NULL, 0);
 +
WiseSnail_RegisterInterface("000E4CAB1234", "Ethernet", -1, interface, 1);
 +
 +
if(WiseSnail_Connect(SERVER_ADDRESS, 1883, "", "", NULL, 0) == 0) {
 +
//
 +
// no succesful connection to broker
 +
//
 +
return -1;
 +
} else {
 +
WiseSnail_RegisterSensor("000E4C000000", "OnBoard", infospec, sizeof(infospec)/sizeof(WiseSnail_InfoSpec));
 +
}
 +
 +
int count = 0;
 +
int second = 0;
 +
for(;;) {
 +
if(second == 0) {
 +
/*HDC1050_GetSensorData(&Temperature, &Humidity);
 +
  data[0].value = Temperature;
 +
  data[1].value = Humidity;
 +
*/
 +
 +
if(data[0].value < 100) {
 +
data[0].value++;
 +
} else {
 +
data[0].value = 0;
 +
}
 +
 +
if(data[1].value < 100) {
 +
data[1].value++;
 +
} else {
 +
data[1].value = 0;
 +
}
 +
 
 +
printf("\r\n****** \033[33mSend update.\033[0m ******\r\n");
 +
WiseSnail_Update("000E4C000000", data, 2);
 +
count++;
 +
}
 +
 
 +
WiseSnail_MainLoop(sleepOneSecond);
 +
second = (second+1)%5;
 +
}
 +
return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
== Get WiseSnail Project ==
 +
 
 +
1. Open&nbsp;WiseSnail project URL:&nbsp;[https://github.com/ADVANTECH-Corp/WiseSnail.git https://github.com/ADVANTECH-Corp/WiseSnail.git]
 +
 
 +
2. Download ZIP of WiseSnail project and unzip it to your local storage, for example: "C:\Projects\WiseSnail"
 +
 
 +
[[File:Wisesnail-Github-01.png|800x480px|Wisesnail-Github-01.png]]
 +
 
 +
== Compile&nbsp;Sample Code ==
 +
 
 +
1. Install prerequest packages that listed in Prequested Packages session.
 +
 
 +
2. Open \WiseSnail\project\VS2015\WiseSnail\Test.sln from&nbsp;Visual Studio menu.
 +
 
 +
3. Change '''Solution Platform''' to "x86".
 +
 
 +
[[File:Wisesnail-Sample-01.png|800x480px|Wisesnail-Sample-01.png]]
 +
 
 +
 
 +
 
 +
4. Rebuild Solution.
 +
 
 +
[[File:Wisesnail-Sample-02.png|800x480px|Wisesnail-Sample-02.png]]
 +
 
 +
 
 +
 
 +
 
 +
 
 +
5. After sample program rebuilt, open Debug (or Release) folder to check if the output file Test.exe is created.
 +
 
 +
[[File:Wisesnail-Sample-03.png|border|800x480px|Wisesnail-Sample-03.png]]
 +
 
 +
== Run Sample Code ==
 +
 
 +
1. Create a new folder named WSNTest on Desktop (or any folder you like)
 +
 
 +
2. Copy all DLL files in the folder \WiseSnail\prebuilt_files\ and put sample program Test.exe together in the same&nbsp;folder.
 +
 
 +
[[File:Wisesnail-Sample-04.png|border|800x480px|Wisesnail-Sample-04.png]]
 +
 
 +
 
 +
 
 +
3. Double click "Test.exe" to run&nbsp;sample program, the simulated sensor data will start uploading.
 +
 
 +
[[File:Wisesnail-sample-05.png|800x480px|Wisesnail-sample-05.png]]
 +
 
 +
== Check Cloud Data ==
 +
 
 +
1. Open WISE-PaaS/EdgeSense Portal and login using your account.&nbsp;
 +
 
 +
2. Click "+Add" to add your device to&nbsp;WISE-PaaS/EdgeSense.
 +
 
 +
3. Click on your device name, for example "GW-ARK-1123H".
 +
 
 +
[[File:Wisesnail-edgesense-01.png|800x480px|Wisesnail-edgesense-01.png]]
 +
 
 +
 
 +
 
 +
4. Click on "Device Children" to open the page.
 +
 
 +
[[File:Wisesnail-edgesense-02.png|800x480px|Wisesnail-edgesense-02.png]]
 +
 
 +
 
 +
 
 +
5. Click on "Monitor" icon to check sensor hub list.
 +
 
 +
[[File:Wisesnail-edgesense-03.png|800x480px|Wisesnail-edgesense-03.png]]
 +
 
 +
 
 +
 
 +
6. Click on SenHub&nbsp;icon to check sensor data.
 +
 
 +
[[File:Wisesnail-edgesense-04.png|800x480px|Wisesnail-edgesense-04.png]]
 +
 
 +
 
 +
 
 +
7. In this page, you can find all sensors that you uploaded.
  
=Demo=
+
[[File:Wisesnail-edgesense-05.png|800x600px|Wisesnail-edgesense-05.png]]

Latest revision as of 09:55, 3 July 2019

Introduction

WiseSnail is the short name of Wise Sensor Network Abstract Interactive Layer. It is a layer to define the topology and behavior of sensor network. A complete device represented in WiseSnail includes one virtual gateway, one sensor connectivity interface and several sensor devices. WiseSnail provides a form-like array which we call it infospec array to define tha parameters of sensor device. And a form-like data array updates your real time data. So, you can easy to represent your device by creating several arrays.

Design intention

WiseSnail designintention.png
We refer the data handle flow on Wise-PaaS to design a data layout like right picture. There are two arrays, interface and sensor device, to implement the behavior of gateway. Each variable array includes several tags. A tag is a variable to indicate the parameter on interface or sensor device. So, we have two register functions and assign into two arrays to generate tags.

Hardware requirements

CPU architecture
  • x86
  • arm
Minimum ram size
  • 256kb and above.

OS

  • Ubuntu ( 14.04, 16.04 )
  • Yocto ( 1.5.3 Dora )
  • OpenWRT
  • Windows ( x86 )

External library dependency requirements

  1. OpenSSL
  2. Paho
  3. Mosquitto

Source Code

GitHub
https://github.com/ADVANTECH-Corp/WiseSnail.git
Source tree
inc header files
library includes AdvJSON, AdvLog, WiseCore
sample a simple sample to test library.
source source files

Configure

Optional
--disable-paho Disable Paho support.
--disable-mosquitto Disable Mosquitto support.
Compile
You can perform the following steps to build this library.

./configure
Or
./configure --host=<your cross compiler> --prefix=<install path>

make
make install

Compile script
This script combines compile steps and version control handling.

./snailconf.sh
Or
./snailconf.sh --host=<your cross compiler> --prefix=<install path>

Build sample
Enter the folder of sample,and make it directly. You can change the MQTT library by editing makefile.

Capability

#define MAX_DEVICES 16     //The Maximum number of sensor device
#define MAX_ITEMS 16       //The Maximum number of sensor value
#define MAX_CMDS 16        //The Maximum number of command that can be processed in one second.

Structures

Data Type

Description

We provide several types to describe the type of data.

    WISE_VALUE  //for numeric value
    WISE_FLOAT  //for floating point
    WISE_STRING //for string
    WISE_BOOL   //for boolean
    WISE_CUSTOMIZE          //for a customize value, use the following type definition
        WISE_BASE64         // a base64 format data.

Infospec

Description

The infospec structure defines your parameters in sensor device. Those parameter structures will represented in Wise-Paas like a tag. It includes two callback function pointers. You can use the callback pointers to define your own get and set function. The button on Wise-Paas for GPIO will be differed from whether the set function is assigned or not. If the set function is assigned, the value is writable by users on Wise-Paas.

    struct WiseSnail_InfoSpec{
      WiseSnail_DataType type;
      char *name;
      char *unit;
      union {
        float value;
        char *string;
        WiseSnail_RAW *raw;
      };
      float min;
      float max;
      char *resourcetype;
      WiseSnail_SetValue setValue;
      WiseSnail_GetValue getValue;
      WiseSnail_FormatType format;
    };
Example
    {
      WISE_VALUE,                  //WiseSnail_DataType 
      "Temperature",               //name
      "Cel",                       //unit
      0,                           //value or string
      -100,                        //min
      200,                         //max
      "ucum.Cel",                  //resourcetype, optional
      NULL,                        //set function
      NULL                         //get function
    }

Data

Description

The data structure defines your value you want to update in sensor device. The cliendId and infomation is for internal used and will be assigned while your callback function(like set) is called.

    struct WiseSnail_Data{
      WiseSnail_DataType type;
      char *name;
      union {
        float value;
        char *string;
        WiseSnail_RAW *raw;
      };
      WiseSnail_FormatType format;
      char *clientId;              //internal
      WiseSnail_InfoSpec *info;    //internal
    }
Example
    {
      WISE_VALUE,                  //WiseSnail_DataType 
      "Temperature",               //name
      100                          //value or string
    }

Callbacks

Set Callback
 typedef int (*WiseSnail_SetValue)(WiseSnail_Data *data);
Get Callback
 typedef int (*WiseSnail_GetValue)(WiseSnail_Data *data);
Sleep callback
 typedef void (*WiseSnail_SleepOneSecond)(void);

Functions

Initial & Uninitial

  • WiseSnail_Init
void WiseSnail_Init(char *productionName, char *wanIp, unsigned char *parentMac, WiseSnail_InfoSpec *infospec, int count);
Parameter Description
productionName Name for device.
wanIp Ip address.
parentMac The mac address of parent device.
infospec Optional parameter array.
count The size of infospec.
  • WiseSnail_Uninit
void WiseSnail_Uninit();
Parameter Description
None None

Register

  • WiseSnail_RegisterInterface
One instance only includes one interface.
void WiseSnail_RegisterInterface(char *ifMac, char *ifName, int ifNumber, WiseSnail_InfoSpec *infospec, int count);
Parameter Description
ifMac The mac address of interface.
ifName The name of interface.
ifNumber The index number of interface.
infospec Interface parameter array.
count The size of infospec.
  • WiseSnail_RegisterSensor
The maximum number of sensor devcie, please refer to MAX_DEVICES.
void WiseSnail_RegisterSensor(char *deviceMac, char *defaultName, WiseSnail_InfoSpec *infospec, int count);
Parameter Description
deviceMac The mac address of sensor device.
defaultName The default name of sensor device.
infospec Sensor device parameter array.
count The size of infospec.

Connect

  • WiseSnail_Connect
int WiseSnail_Connect(char *server_url, int port, char *username, char *password, WiseSnail_InfoSpec *infospec, int count);
Parameter Description
server_url The address of mqtt broker.
port The port of mqtt broker.
username The username of mqtt broker.("" for none)
password The password of mqtt broker.("" for none)
infospec Connect parameter array.
count The size of infospec.

Update

  • WiseSnail_Update
You can update your data from this function by assigning a data array.
void WiseSnail_Update(char *deviceMac, WiseSnail_Data* data, int count);
Parameter Description
deviceMac The mac of device which you will update.
data Data array.
count The size of data.

Main Handle Loop function

  • WiseSnail_MainLoop
This is a very important function. It includes main logic and error handling. The interval of sleepOneSec must be one second.
You also can run an external timer, but this function must be executed per one second.
void WiseSnail_MainLoop(WiseSnail_SleepOneSecond sleepOneSec);
Parameter Description
sleepOneSec a callback function for sleep one second.

Sample Program

Prerequest

1. Visual Studio 2015 or above.

    Download URL: https://docs.microsoft.com/zh-tw/visualstudio/install/install-visual-studio?view=vs-2019

2. WISE-Agent 1.1.x

    Download from WISE-PaaS/EdgeSense Portal, Settings Page.

3. API-GW 2.0.x

    Download URL: https://www.dropbox.com/s/amsooqwswabfxbk/API-GW-2.0.7.exe?dl=0

Sample Code Overview

(pseudo code)


WiseSnail_InfoSpec interface[] = {
		{
				WISE_BOOL,
				"/Info/reset",
				"",
				0,
				0,
				1,
				"",
				Reset
		}
};

void SetGPIO_1(WiseSnail_Data*data) {
    printf("(GPIO 1) = %d\r\n",data->value);
}

void SetGPIO_2(WiseSnail_Data*data) {
    printf("(GPIO 2) = %d\r\n",data->value);
}

/***********************CUSTOMIZE VALUE FOR BASE64*******************************/
char rawData[128] = "ABCDE";
WiseSnail_RAW rawItem = {
    .data = rawData,
    .len = 5
};

int SetRAW(WiseSnail_Data *data) {
    if(data->type == WISE_CUSTOMIZE) {
        memcpy(&rawItem, data->raw, sizeof(rawItem));
    }
}

int GetRAW(WiseSnail_Data *data) {
    if(data->type == WISE_CUSTOMIZE) {
        memcpy(data->raw, &rawItem, sizeof(rawItem));
    }
}
/********************************************************************************/

WiseSnail_InfoSpec infospec[] = {
		{
				WISE_STRING,
				"/Info/Name",
				"",
				.string = "SenHub1",  // Device Name of SenHub (*) 
				0,
				0,
				"",
				//SetSHName,
				.getValue = GetSHName
		},
		{
				WISE_VALUE,			//type
				"Temperature",	    //name
				"Cel",				//unit
				0,				    //value[union]
				-100,				//min
				200,				//max
				"ucum.Cel"			//resourceType
		},
		{
				WISE_VALUE,			//type
				"Humidity",			//name
				"%",				//unit
				0,				    //value[union]
				0,				    //min
				100,				//max
				"ucum.%"			//resourceType
		},
                {
		        	WISE_IO_BOOL,
                        	"GPIO1",
                        	"",
                        	0,
                        	0,
                        	1,
                        	"",
                        	SetGPIO_1
                },
                {
                        	WISE_IO_BOOL,
                        	"GPIO2",
                        	"",
                        	0,
                        	0,
                        	1,
                        	"",
                        	SetGPIO_2
		},
                {
                                WISE_CUSTOMIZE,
                                "RAW",
                                "",
                                .raw = &rawItem,
                                0,
                                1,
                                "",
                                SetRAW,
                                GetRAW,
                                WISE_BASE64
		}
};

WiseSnail_Data data[] = {
		{
				WISE_VALUE,			//type
				"Temperature",			//name
				100				//value
		},
		{
				WISE_VALUE,			//type
				"Humidity",			//name
				55				//value
		},
                {
                                WISE_CUSTOMIZE,
                                "RAW",
                                .raw = &rawItem,
                                WISE_BASE64
		}
};

void sleepOneSecond() {
	sleep(1);
}

#define SERVER_ADDRESS "rmm.wise-paas.com"

int main() {
	//initial
	WiseSnail_Init("IotGW",NULL, NULL, NULL, 0);
	WiseSnail_RegisterInterface("000E4CAB1234", "Ethernet", -1, interface, 1);
		
	if(WiseSnail_Connect(SERVER_ADDRESS, 1883, "", "", NULL, 0) == 0) {
		//
		// no succesful connection to broker
		//
		return -1;
	} else {
		WiseSnail_RegisterSensor("000E4C000000", "OnBoard", infospec, sizeof(infospec)/sizeof(WiseSnail_InfoSpec));
	}
		
	int count = 0;
	int second = 0;
	for(;;) {
		if(second == 0) {
			/*HDC1050_GetSensorData(&Temperature, &Humidity);
			  data[0].value = Temperature;
			  data[1].value = Humidity;
			*/
				
			if(data[0].value < 100) {
				data[0].value++;
			} else {
				data[0].value = 0;
			}
				
			if(data[1].value < 100) {
				data[1].value++;
			} else {
				data[1].value = 0;
			}

			printf("\r\n****** \033[33mSend update.\033[0m ******\r\n");
			WiseSnail_Update("000E4C000000", data, 2);
		count++;
		}

		WiseSnail_MainLoop(sleepOneSecond);	
		second = (second+1)%5;
	}
	return 0; 
}



Get WiseSnail Project

1. Open WiseSnail project URL: https://github.com/ADVANTECH-Corp/WiseSnail.git

2. Download ZIP of WiseSnail project and unzip it to your local storage, for example: "C:\Projects\WiseSnail"

Wisesnail-Github-01.png

Compile Sample Code

1. Install prerequest packages that listed in Prequested Packages session.

2. Open \WiseSnail\project\VS2015\WiseSnail\Test.sln from Visual Studio menu.

3. Change Solution Platform to "x86".

Wisesnail-Sample-01.png


4. Rebuild Solution.

Wisesnail-Sample-02.png



5. After sample program rebuilt, open Debug (or Release) folder to check if the output file Test.exe is created.

Wisesnail-Sample-03.png

Run Sample Code

1. Create a new folder named WSNTest on Desktop (or any folder you like)

2. Copy all DLL files in the folder \WiseSnail\prebuilt_files\ and put sample program Test.exe together in the same folder.

Wisesnail-Sample-04.png


3. Double click "Test.exe" to run sample program, the simulated sensor data will start uploading.

Wisesnail-sample-05.png

Check Cloud Data

1. Open WISE-PaaS/EdgeSense Portal and login using your account. 

2. Click "+Add" to add your device to WISE-PaaS/EdgeSense.

3. Click on your device name, for example "GW-ARK-1123H".

Wisesnail-edgesense-01.png


4. Click on "Device Children" to open the page.

Wisesnail-edgesense-02.png


5. Click on "Monitor" icon to check sensor hub list.

Wisesnail-edgesense-03.png


6. Click on SenHub icon to check sensor data.

Wisesnail-edgesense-04.png


7. In this page, you can find all sensors that you uploaded.

Wisesnail-edgesense-05.png