Show last authors
1 **~ Contents:**
2
3 {{toc/}}
4
5
6 = 1. Introduction =
7
8 This article shows how to use [[LBT1>>url:http://www.dragino.com/products/lora-lorawan-end-node/item/165-lbt1.html]] to build an Indoor Positioning Solution.
9
10 [[image:image-20220526150521-2.png]]
11
12 LBT1 Indoor Positioning Network Structure
13
14
15 = 2. Prepare Map =
16
17 == 2.1 Prepare iBeacons ==
18
19 (((
20 (((
21 Any BLE iBeacons should work in this solution, each iBeacon stands for a fix position in the map. Here is an iBeacon for example.
22 )))
23 )))
24
25 (((
26 (((
27 First of all, user needs to accurately place the beacon at each location, which is the reference for positioning.
28 )))
29 )))
30
31 (((
32 (((
33 BCN01 iBeacon from Dragino: [[http:~~/~~/www.dragino.com/products/accessories/item/166-bcn01.html>>url:http://www.dragino.com/products/accessories/item/166-bcn01.html]]
34 )))
35 )))
36
37 [[image:image-20220526150651-4.png]]
38
39 BCN01 iBeacon
40
41
42 (((
43 (((
44 We need to get the UUID, MAJOR, MINOR, TXPOWER where each iBeacon is placed. We can get it with the iBeacon software, such as "EW-beacon".
45 )))
46 )))
47
48 [[image:image-20220526150743-5.png]]
49
50 beacon software
51
52
53 [[image:image-20220526150824-6.png]]
54
55 beacon software
56
57
58 == 2.2 Create Map ==
59
60 (((
61 (((
62 Here we use the indoor map at [[https:~~/~~/studio.mapwize.io/>>url:https://studio.mapwize.io/]]. Below shows the steps for create a map and put the iBeacon on a fix position.
63 )))
64 )))
65
66 (((
67 (((
68 ~1. Register an account at [[https:~~/~~/studio.mapwize.io/>>url:https://studio.mapwize.io/]] to create an indoor map.
69 )))
70 )))
71
72 (((
73 (((
74 2. Create Place Types.
75 )))
76 )))
77
78 [[image:image-20220526150915-7.png]]
79
80 Create place types
81
82
83 3. Search Venues. (Indoor map area identification)
84
85 [[image:image-20220526151046-8.png]]
86
87 (((
88 (((
89 The map accurately places the beacon of ibeacon, which is the reference for positioning. At this time, UUID, MAJOR and MINOR must be filled in correctly.
90
91
92 )))
93 )))
94
95 4. Upload Floor plan.
96
97 [[image:image-20220526151223-9.png]]
98
99 add images
100
101
102 5. Create Layer
103
104 [[image:image-20220526151305-10.png]]
105
106 create layer
107
108
109 (((
110 6. Add iBeacon position info. Drag the iBeacon to match position and input the UUID, MAJOR and MINOR of this iBeacon.
111 )))
112
113 [[image:image-20220526151519-11.png]]
114
115 create iBeacon
116
117 = 3. Configure TTN =
118
119 == 3.1 Configure LBT1 to Upload data to TTN ==
120
121 Please refer the instruction in the [[User Manual>>url:http://www.dragino.com/downloads/index.php?dir=accessories/Bluetooth/BCN01]]. Note the (% style="color:#4f81bd" %)**LBT1 need to set to MOD=3**(%%) here.
122
123 == 3.2 Decoder in TTN ==
124
125 (% class="box" %)
126 (((
127 function Decoder(bytes, port) {
128 \\~/~/ Decode an uplink message from a buffer
129 \\~/~/ (array) of bytes to an object of fields.
130 \\value = bytes[0] << 8 | bytes[1];
131 \\var batV = value/1000;~/~/Battery,units:V
132 \\var mode = bytes[5];
133 \\~/~/var value=(bytes[3]-0x30)*1000 +(bytes[5]-0x30)*100 + (bytes[5]-0x30)*10 +(bytes[6]-0x30);
134 \\~/~/var value = bytes.slice(3);
135 \\var i;
136 \\var con;
137 \\var str = "";
138 \\var major = 1;
139 \\var minor = 1;
140 \\var rssi = 0;
141 \\var addr = "";
142 \\if(mode ==2 ) {
143 \\ for(i = 38 ; i<50 ; i++) {
144 \\ con = bytes[i].toString();
145 \\ str += String.fromCharCode(con);
146 \\ }
147 \\ addr = str;
148 \\ str = "";
149 \\ for(i = 6 ; i<38 ; i++) {
150 \\ con = bytes[i].toString();
151 \\ str += String.fromCharCode(con);
152 \\ }
153 \\ value = str;
154 \\}
155 \\if(mode == 3 ) {
156 \\ str = "";
157 \\ for(i = 18 ; i < 22 ; i++) {
158 \\ con = bytes[i].toString();
159 \\ str += String.fromCharCode(con);
160 \\ }
161 \\ major = parseInt(str, 16);
162 \\ str = "";
163 \\ for(i = 22 ; i < 26 ; i++) {
164 \\ con = bytes[i].toString();
165 \\ str += String.fromCharCode(con);
166 \\ }
167 \\ minor = parseInt(str, 16);
168 \\ str = "";
169 \\ for(i = 28 ; i < 32 ; i++) {
170 \\ con = bytes[i].toString();
171 \\ str += String.fromCharCode(con);
172 \\ }
173 \\ rssi = parseInt(str);
174 \\ str = "";
175 \\ for(i = 6 ; i < 18 ; i++) {
176 \\ con = bytes[i].toString();
177 \\ str += String.fromCharCode(con);
178 }
179 \\ value = str;
180 }
181 \\if(mode == 1) {
182 \\ for(i = 6 ; i<11 ; i++) {
183 \\ con = bytes[i].toString();
184 \\ str += String.fromCharCode(con);
185 \\ }
186 \\ value = str;
187 }
188 \\var uuid = value;
189 \\var alarm = bytes[2] >> 4 & 0x0F;
190 \\var step_count = (bytes[2] & 0x0F) << 16 | bytes[3] << 8 | bytes[4];
191 \\return {
192 UUID: uuid,
193 ADDR: addr,
194 MAJOR: major,
195 MINOR: minor,
196 RSSI:rssi,
197 STEP: step_count,
198 ALARM: alarm,
199 BatV:batV,
200 };
201 }
202
203 )))
204
205 = 4. Set Up Converter Server =
206
207 * (((
208 How to install and run this service on Linux?
209 )))
210
211 (((
212 Step1.Rent a Linux on Amazon cloud or alicloud to the host, and pre install the Linux system (Debian, Ubuntu, CentOS are available for distribution).
213 )))
214
215 (((
216 Step2.Run the code on the server after compiling. Compilation requires the support of libcurl. First, compile libmqtt in the code, and then compile location.
217 )))
218
219 (((
220 System: Debian / Ubuntu
221 )))
222
223 (% class="box" %)
224 (((
225 step:
226 \\1. sudo apt install libcurl4-dev 
227 \\2. sudo apt install  gcc automake autoconf libtool make cmake
228 \\3. git clone -b master https:~/~/github.com/mikayong/location.git
229 \\4. cd location/libmqtt
230 \\5. mkdir build
231 \\6. cd build && cmake ../
232 \\7. make && sudo make install 
233 \\8. cd ../
234 \\9. make 
235 \\10. sudo cp location_conf.json  /etc/
236 \\11. Edit the configuration file, and run the location service in the background: ./location &
237 )))
238
239 (((
240 Step3.The location service subscribes to the lora information stream on TTN through the mqtt protocol, parses the information to generate a geographic location, and finally creates a geographic location on the mapwize map. The following is the configuration of the location service, the configuration file is in json format, the file is /etc/location_conf.json
241 )))
242
243 = 5. Configuration file: location_conf.json =
244
245 * (((
246 We use the 120.78.138.177 server as an example. The location service is currently installed on the 120.78.138.177 server, the code is in /root/location, and the configuration file for running location pre-read directly is /etc/location_conf.json.
247 )))
248
249 (((
250 { "location_conf": {
251 )))
252
253 (% class="box" %)
254 (((
255 (((
256 "loctype": "indoor",       ~/~/ indoor/outdoor
257 "locmap": "mapwize"    ~/~/   Map interface: mapwize, traccar
258 )))
259 )))
260
261 (((
262 }, "mqtt_conf": {
263 )))
264
265 (% class="box" %)
266 (((
267 (((
268 "servaddr": "[str]",    ~/~/     Lorawan server address: Refer to TTN app handler:eu.thethings.network
269 "servport": [int],       ~/~/   Lorawan server port: 1883
270 "clientid": "[str]",       ~/~/   MQTT client identity: Custom
271 "qos":[int],                 ~/~/  (Optional) MQTT service quality: 0
272 "username":"[str]",     ~/~/   Agent name of mqtt: application ID of TTN
273 "password":"[str]",      ~/~/  The proxy password of mqtt: application access key of TTN
274 "topic":"[str]",              ~/~/ The topic of mqtt subscription: TTN is + / devices / + / up
275 "connection":"[str]" },   ~/~/(Optional) mqtt is a string used for direct connection, composed of serveraddr and port
276 "mapwize_conf":{          ~/~/Map settings
277 "apikey": "[str]",        ~/~/ The apikey of the map user can be found on the Api keys page of wapwize, and read and write permissions need to be set
278 "venueid":"[str]",        ~/~/ (Optional)Indoor map area identification
279 "orgid":"[str]",           ~/~/  The identity of the user organizer
280 "universesid":"[str]",   ~/~/The range indicator of the indoor map, find it on the universes page
281 "placetype": "[str]"     ~/~/The type of place used to identify the creation must be created on the placetypes page in the map, where the placetype name is filled in
282 },
283 "loracloud":{
284 "token":  "[str]"          ~/~/The password string of loracloud location service, the outdoor map must fill in the account token of loracloud
285 )))
286 )))
287
288 (((
289 }
290 )))
291
292 (% class="box" %)
293 (((
294 (((
295 "rssi_conf": {
296 "rssirate": [int],          ~/~/ (Optional) A basis for rssi calculation distance, the rssi value (absolute value) when the beacon is 1 meter apart 
297 "rssidiv": [float] }        ~/~/ (Optional) rssi measures an attenuation value of distance. As the distance to the beacon is farther, the value changes speed
298 )))
299 )))
300
301 (((
302 }
303 )))
304
305 * Parameter acquisition method of configuration file:
306
307 (% class="box" %)
308 (((
309 "username":"[str]"
310 )))
311
312 [[image:https://wiki.dragino.com/images/thumb/d/da/Beacon50.png/600px-Beacon50.png||height="185" width="600"]]
313
314 username
315
316 (% class="box" %)
317 (((
318 "password":"[str]"     
319 )))
320
321 [[image:https://wiki.dragino.com/images/thumb/b/bd/Beacon51.png/800px-Beacon51.png||alt="File:Beacon51.png" height="259" width="598"]]
322
323 password
324
325 (% class="box" %)
326 (((
327 "apikey": "[str]"
328 )))
329
330 [[image:https://wiki.dragino.com/images/thumb/5/53/Qwe3.png/800px-Qwe3.png||alt="File:Qwe3.png" height="325" width="606"]]
331
332 apikey
333
334 (% class="box" %)
335 (((
336 "orgid":"[str]"
337 )))
338
339 [[image:https://wiki.dragino.com/images/thumb/f/f4/Qwe4.png/800px-Qwe4.png||alt="File:Qwe4.png" height="304" width="622"]]
340
341 orgid
342
343 (% class="box" %)
344 (((
345 "universesid":"[str]"
346 )))
347
348 [[image:https://wiki.dragino.com/images/thumb/9/9a/Qwe5.jpg/600px-Qwe5.jpg||height="424" width="600"]]
349
350 universesid
351
352 (% class="box" %)
353 (((
354 "placetype": "[str]"
355 )))
356
357 [[image:https://wiki.dragino.com/images/thumb/9/93/Qwe6.png/600px-Qwe6.png||height="318" width="600"]]
358
359 placetype
360
361
362 **Here are two ways to enter the server:**
363
364 **~1. WinSCP**
365
366 [[image:https://wiki.dragino.com/images/thumb/6/6b/Ibeacon4.jpg/600px-Ibeacon4.jpg||height="385" width="600"]]
367
368 [[image:https://wiki.dragino.com/images/thumb/7/78/Ibeacon5.jpg/600px-Ibeacon5.jpg||height="385" width="600"]]
369
370 [[image:https://wiki.dragino.com/images/thumb/c/cd/Ibeacon6.jpg/800px-Ibeacon6.jpg||alt="File:Ibeacon6.jpg" height="362" width="599"]]
371
372 way1
373
374 **2. secureCRT**
375
376 [[image:https://wiki.dragino.com/images/thumb/7/7b/Ibeacon7.jpg/600px-Ibeacon7.jpg||height="326" width="600"]]
377
378 [[image:https://wiki.dragino.com/images/thumb/6/64/Ibeacon8.jpg/600px-Ibeacon8.jpg||height="326" width="600"]]
379
380 [[image:https://wiki.dragino.com/images/thumb/d/de/Ibeacon9.jpg/800px-Ibeacon9.jpg||alt="File:Ibeacon9.jpg" height="327" width="602"]]
381
382 way2
383
384 = 6. Test Result =
385
386 The real-time position on the map is obtained according to the moving change of LBT1.
387
388 [[image:https://wiki.dragino.com/images/thumb/7/70/Beacon15.png/600px-Beacon15.png||alt="Beacon15.png" height="294" width="600"]]
Copyright ©2010-2022 Dragino Technology Co., LTD. All rights reserved
Dragino Wiki v2.0