Wiki source code of Connect Devices to ThingsEye
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | **Table of Contents:** | ||
| 4 | |||
| 5 | {{toc/}} | ||
| 6 | |||
| 7 | |||
| 8 | = 1. Overview = | ||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | = 2. UDP Procotol ~-~- Directly Connection = | ||
| 13 | |||
| 14 | == 2.1 UDP Interface == | ||
| 15 | |||
| 16 | * Server Address: server1.thingseye.io | ||
| 17 | * Port: 11562 | ||
| 18 | |||
| 19 | The data sent to above UDP interface will not go directly to client's database. | ||
| 20 | |||
| 21 | Please contact ThingsEye team for detail how to forward data to client. | ||
| 22 | |||
| 23 | |||
| 24 | == 2.2 Test UDP Interface via Socket Tool == | ||
| 25 | |||
| 26 | Download the UDP Test Tool from: [[https:~~/~~/sourceforge.net/projects/sockettest/ >>https://sourceforge.net/projects/sockettest/]]. Run this tool, and input the server address and UDP port as below and click send. | ||
| 27 | |||
| 28 | [[image:1728566363151-470.png]] | ||
| 29 | |||
| 30 | In server side, Tenant Administrator can check this in Tenant UDP Server location. | ||
| 31 | |||
| 32 | [[image:1728362834430-749.png||height="510" width="1667"]] | ||
| 33 | |||
| 34 | Click and see the debug info as below: | ||
| 35 | |||
| 36 | [[image:1728363020699-203.png]] | ||
| 37 | |||
| 38 | We can see the message arrives, but it shows ERROR because the message doesn't follow with the UDP Server format. | ||
| 39 | |||
| 40 | |||
| 41 | == 2.3 Test with Dragino NB device == | ||
| 42 | |||
| 43 | === 2.3.1 Configure NB-IoT End Node === | ||
| 44 | |||
| 45 | Device here is **[[S31-NB>>https://www.dragino.com/products/temperature-humidity-sensor/item/288-s31-nb-s31b-nb.html]]** : and have been configure below | ||
| 46 | |||
| 47 | * Set to use ThingsEye UDP server: **AT+SERVADDR=server1.thingseye.io,11560** | ||
| 48 | * Use UDP Uplink & Json protocol:** AT+PRO=2,5** | ||
| 49 | * Equip with a NB-IoT SIM Card to access to NB-IoT Network. | ||
| 50 | |||
| 51 | The S31-NB's cellular module has the IMEI: **863663062789483** | ||
| 52 | |||
| 53 | |||
| 54 | === 2.3.2 Check Uplink Data === | ||
| 55 | |||
| 56 | Re-activate the S31-NB, and we can see it in the debug window: | ||
| 57 | |||
| 58 | [[image:1728378218744-800.png||height="431" width="1003"]] | ||
| 59 | |||
| 60 | |||
| 61 | === 2.3.3 Auto-Create Device === | ||
| 62 | |||
| 63 | The default **Tenant UDP Server** has already been configured to decode the Dragino -NB / -CB NB-IoT node. So once each end node sends a data to server. Tenant will auto create the device in the server. | ||
| 64 | |||
| 65 | [[image:1728378968101-683.png||height="273" width="1307"]] | ||
| 66 | |||
| 67 | [[image:1728379050044-764.png||height="424" width="1312"]] | ||
| 68 | |||
| 69 | |||
| 70 | **So we have this device in the Tenant Device List. The next step will be how to use these value to make a nice dashboard for user's application.** | ||
| 71 | |||
| 72 | |||
| 73 | |||
| 74 | = 2. Connect to The Things Stack = | ||
| 75 | |||
| 76 | == 2.1 Network Structure == | ||
| 77 | |||
| 78 | |||
| 79 | == 2.2 Creat Integration for The Things Stack. == | ||
| 80 | |||
| 81 | (% class="lead" %) | ||
| 82 | Add Integration | ||
| 83 | |||
| 84 | [[image:1728535775119-971.png||height="456" width="1087"]] | ||
| 85 | |||
| 86 | |||
| 87 | (% class="lead" %) | ||
| 88 | Choose Connection Type | ||
| 89 | |||
| 90 | [[image:1728535857345-950.png]] | ||
| 91 | |||
| 92 | |||
| 93 | (% class="lead" %) | ||
| 94 | Input Uplink Data Converter Code | ||
| 95 | |||
| 96 | [[image:1728535941851-388.png||height="466" width="398"]] | ||
| 97 | |||
| 98 | Demo Code as below: | ||
| 99 | |||
| 100 | >var data = decodeToJson(payload); | ||
| 101 | >var deviceName = data.end_device_ids.device_id; | ||
| 102 | >var deviceType = data.end_device_ids.application_ids.application_id; | ||
| 103 | >var model = {}; | ||
| 104 | >var data2 = data.uplink_message.decoded_payload; | ||
| 105 | >var flg = data.uplink_message.f_port | ||
| 106 | >for (var key in data2) { | ||
| 107 | > model[key] = data2[key]; | ||
| 108 | >} | ||
| 109 | >var obj = {"devid":deviceName} | ||
| 110 | >var result = { | ||
| 111 | > deviceName: deviceName, | ||
| 112 | > deviceType: deviceType, | ||
| 113 | > telemetry: model, | ||
| 114 | > groupName: "Case Study", | ||
| 115 | > attributes:{"devid":deviceName, | ||
| 116 | > "timevalue":"test", | ||
| 117 | > "inactivityTimeout":1260000 | ||
| 118 | > } | ||
| 119 | >}; | ||
| 120 | >function decodeToString(payload) { | ||
| 121 | > return String.fromCharCode.apply(String, payload); | ||
| 122 | >}function decodeToJson(payload) { | ||
| 123 | > var str = decodeToString(payload); | ||
| 124 | > var data = JSON.parse(str); | ||
| 125 | > return data; | ||
| 126 | >} | ||
| 127 | >if (flg===2){ | ||
| 128 | >return result; | ||
| 129 | >} | ||
| 130 | |||
| 131 | |||
| 132 | (% class="lead" %) | ||
| 133 | Input Downlink Converter | ||
| 134 | |||
| 135 | [[image:1728536142721-488.png||height="470" width="407"]] | ||
| 136 | |||
| 137 | Example Code as below: | ||
| 138 | |||
| 139 | >function hexToBase64(hexString) { | ||
| 140 | > var bytes = hexString.match(/.{2}/g); | ||
| 141 | > var binaryString = bytes.map(function(byte) { | ||
| 142 | > return String.fromCharCode(parseInt(byte, 16)); | ||
| 143 | > }).join(''); | ||
| 144 | > | ||
| 145 | > return btoa(binaryString); | ||
| 146 | >} | ||
| 147 | >var flg = "shared_value" in metadata | ||
| 148 | >var value2 = parseInt(metadata.ss_timevalue).toString(16)if (value2.length==1){ | ||
| 149 | > value2 = "00000"+parseInt(metadata.ss_timevalue).toString(16) | ||
| 150 | >} | ||
| 151 | >else if (value2.length==2){ | ||
| 152 | > value2 = "0000"+parseInt(metadata.ss_timevalue).toString(16) | ||
| 153 | >} | ||
| 154 | >else if (value2.length==3){ | ||
| 155 | > value2 = "000"+parseInt(metadata.ss_timevalue).toString(16) | ||
| 156 | >} | ||
| 157 | >else if (value2.length==4){ | ||
| 158 | > value2 = "00"+parseInt(metadata.ss_timevalue).toString(16) | ||
| 159 | >} | ||
| 160 | >else if (value2.length==5){ | ||
| 161 | > value2 = "0"+parseInt(metadata.ss_timevalue).toString(16) | ||
| 162 | >} | ||
| 163 | >else { | ||
| 164 | > value2 = value2 | ||
| 165 | >} | ||
| 166 | >var data = "01"+value2 | ||
| 167 | >if (flg === true){ | ||
| 168 | >data = { | ||
| 169 | > downlinks: [{ | ||
| 170 | > f_port: 1, | ||
| 171 | > confirmed: false, | ||
| 172 | > frm_payload: hexToBase64(metadata.shared_value), | ||
| 173 | > priority: "NORMAL" | ||
| 174 | > }] | ||
| 175 | > }; | ||
| 176 | >} | ||
| 177 | >else{ | ||
| 178 | > data = { | ||
| 179 | > downlinks: [{ | ||
| 180 | > f_port: 1, | ||
| 181 | > confirmed: false, | ||
| 182 | > frm_payload: hexToBase64(data), | ||
| 183 | > priority: "NORMAL" | ||
| 184 | > }] | ||
| 185 | > }; | ||
| 186 | >} | ||
| 187 | >var result = { | ||
| 188 | > contentType: "JSON", | ||
| 189 | > data: JSON.stringify(data), | ||
| 190 | > metadata: { | ||
| 191 | > devId: metadata.ss_devid | ||
| 192 | > } | ||
| 193 | >}; | ||
| 194 | >if (metadata.shared_timevalue!=="test" || metadata.ss_timevalue!=="test"){ | ||
| 195 | >return result; | ||
| 196 | >} | ||
| 197 | |||
| 198 | |||
| 199 | (% class="lead" %) | ||
| 200 | Set up Connection to The Things Network application | ||
| 201 | |||
| 202 | [[image:1728536305503-380.png||height="510" width="1206"]] | ||
| 203 | |||
| 204 | |||
| 205 | |||
| 206 | (% class="lead" %) | ||
| 207 | Test Connection & Add iIntegration | ||
| 208 | |||
| 209 | [[image:1728536374214-962.png]] | ||
| 210 | |||
| 211 | After add , we can see the integration here: | ||
| 212 | |||
| 213 | [[image:1728536420275-153.png||height="208" width="1404"]] | ||
| 214 | |||
| 215 | |||
| 216 | == 2.3 Test Uplink == | ||
| 217 | |||
| 218 | We can use Simulate Uplink to simulate an uplink in the things stack. Then we should be able to see the message in ThingsEye | ||
| 219 | |||
| 220 | [[image:1728536524638-768.png||height="493" width="1071"]] | ||
| 221 | |||
| 222 | |||
| 223 | [[image:1728536541040-814.png]] |