Wiki source code of Mapwize

Version 28.8 by Xiaoling on 2022/07/25 13:42

Show last authors
1 **~ Table of Contents:**
2
3 {{toc/}}
4
5
6
7
8 = 1.  Introduction =
9
10
11 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.
12
13
14 [[image:image-20220526150521-2.png]]
15
16 LBT1 Indoor Positioning Network Structure
17
18
19
20 = 2.  Prepare Map =
21
22
23 == 2.1  Prepare iBeacons ==
24
25
26 (((
27 (((
28 Any BLE iBeacons should work in this solution, each iBeacon stands for a fix position in the map. Here is an iBeacon for example.
29 )))
30 )))
31
32 (((
33 (((
34 First of all, user needs to accurately place the beacon at each location, which is the reference for positioning.
35 )))
36 )))
37
38 (((
39 (((
40 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]]
41
42
43 )))
44 )))
45
46 [[image:image-20220526150651-4.png]]
47
48 BCN01 iBeacon
49
50
51
52 (((
53 (((
54 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".
55 )))
56 )))
57
58 [[image:image-20220526150743-5.png]]
59
60 beacon software
61
62
63
64 [[image:image-20220526150824-6.png]]
65
66 beacon software
67
68
69
70 == 2.2  Create Map ==
71
72
73 (((
74 (((
75 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.
76
77
78 )))
79 )))
80
81 (((
82 (((
83 **~1. Register an account at [[https:~~/~~/studio.mapwize.io/>>url:https://studio.mapwize.io/]] to create an indoor map.**
84 )))
85 )))
86
87 (((
88 (((
89 **2. Create Place Types.**
90
91
92 )))
93 )))
94
95 [[image:image-20220526150915-7.png]]
96
97 Create place types
98
99
100
101 **3. Search Venues. (Indoor map area identification)**
102
103
104 [[image:image-20220526151046-8.png]]
105
106
107 (((
108 (((
109 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.
110
111
112
113 )))
114 )))
115
116 **4. Upload Floor plan.**
117
118
119 [[image:image-20220526151223-9.png]]
120
121 add images
122
123
124
125 **5. Create Layer**
126
127
128 [[image:image-20220526151305-10.png]]
129
130 create layer
131
132
133 (((
134 **6. Add iBeacon position info. Drag the iBeacon to match position and input the UUID, MAJOR and MINOR of this iBeacon.**
135
136
137 )))
138
139 [[image:image-20220526151519-11.png]]
140
141 create iBeacon
142
143
144
145 = 3.  Configure TTN =
146
147
148 == 3.1  Configure LBT1 to Upload data to TTN ==
149
150
151 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.
152
153
154
155 == 3.2  Decoder in TTN ==
156
157
158 (% class="box" %)
159 (((
160 function Decoder(bytes, port) {
161 \\~/~/ Decode an uplink message from a buffer
162 \\~/~/ (array) of bytes to an object of fields.
163 \\value = bytes[0] << 8 | bytes[1];
164 \\var batV = value/1000;~/~/Battery,units:V
165 \\var mode = bytes[5];
166 \\~/~/var value=(bytes[3]-0x30)*1000 +(bytes[5]-0x30)*100 + (bytes[5]-0x30)*10 +(bytes[6]-0x30);
167 \\~/~/var value = bytes.slice(3);
168 \\var i;
169 \\var con;
170 \\var str = "";
171 \\var major = 1;
172 \\var minor = 1;
173 \\var rssi = 0;
174 \\var addr = "";
175 \\if(mode ==2 ) {
176 \\ for(i = 38 ; i<50 ; i++) {
177 \\ con = bytes[i].toString();
178 \\ str += String.fromCharCode(con);
179 \\ }
180 \\ addr = str;
181 \\ str = "";
182 \\ for(i = 6 ; i<38 ; i++) {
183 \\ con = bytes[i].toString();
184 \\ str += String.fromCharCode(con);
185 \\ }
186 \\ value = str;
187 \\}
188 \\if(mode == 3 ) {
189 \\ str = "";
190 \\ for(i = 18 ; i < 22 ; i++) {
191 \\ con = bytes[i].toString();
192 \\ str += String.fromCharCode(con);
193 \\ }
194 \\ major = parseInt(str, 16);
195 \\ str = "";
196 \\ for(i = 22 ; i < 26 ; i++) {
197 \\ con = bytes[i].toString();
198 \\ str += String.fromCharCode(con);
199 \\ }
200 \\ minor = parseInt(str, 16);
201 \\ str = "";
202 \\ for(i = 28 ; i < 32 ; i++) {
203 \\ con = bytes[i].toString();
204 \\ str += String.fromCharCode(con);
205 \\ }
206 \\ rssi = parseInt(str);
207 \\ str = "";
208 \\ for(i = 6 ; i < 18 ; i++) {
209 \\ con = bytes[i].toString();
210 \\ str += String.fromCharCode(con);
211 }
212 \\ value = str;
213 }
214 \\if(mode == 1) {
215 \\ for(i = 6 ; i<11 ; i++) {
216 \\ con = bytes[i].toString();
217 \\ str += String.fromCharCode(con);
218 \\ }
219 \\ value = str;
220 }
221 \\var uuid = value;
222 \\var alarm = bytes[2] >> 4 & 0x0F;
223 \\var step_count = (bytes[2] & 0x0F) << 16 | bytes[3] << 8 | bytes[4];
224 \\return {
225 UUID: uuid,
226 ADDR: addr,
227 MAJOR: major,
228 MINOR: minor,
229 RSSI:rssi,
230 STEP: step_count,
231 ALARM: alarm,
232 BatV:batV,
233 };
234 }
235
236 )))
237
238
239
240 = 4.  Set Up Converter Server =
241
242
243 * (((
244 (% style="color:blue" %)**How to install and run this service on Linux?**
245 )))
246
247 (((
248 (% style="color:red" %)**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).
249 )))
250
251 (((
252 (% style="color:red" %)**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.
253
254
255 )))
256
257 (((
258 **System:  Debian / Ubuntu**
259 )))
260
261 (% class="box" %)
262 (((
263 (% style="color:blue" %)**step:**(%%)
264 \\1. **sudo** apt install libcurl4-dev 
265 \\2. **sudo** apt **install  gcc automake autoconf** libtool **make** cmake
266 \\3. git clone -b master https:~/~/github.com/mikayong/location.git
267 \\4. cd location/libmqtt
268 \\5. mkdir build
269 \\6. cd build && cmake ../
270 \\7. make && sudo make install 
271 \\8. cd ../
272 \\9. make 
273 \\10. sudo cp location_conf.json  /etc/
274 \\11. Edit the configuration file, and run the location service in the background: ./location &
275 )))
276
277 (((
278 (% style="color:red" %)**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
279
280
281
282 )))
283
284 = 5.  Configuration file: location_conf.json =
285
286
287 * (((
288 (% style="color:blue" %)**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.**
289
290
291 )))
292
293 (((
294 { "location_conf": {
295 )))
296
297 (% class="box" %)
298 (((
299 (((
300 "loctype": "indoor",       ~/~/ indoor/outdoor
301 "locmap": "mapwize"    ~/~/   Map interface: mapwize, traccar
302 )))
303 )))
304
305 (((
306 }, "mqtt_conf": {
307 )))
308
309 (% class="box" %)
310 (((
311 (((
312 "servaddr": "[str]",    ~/~/     Lorawan server address: Refer to TTN app handler:eu.thethings.network
313 "servport": [int],       ~/~/   Lorawan server port: 1883
314 "clientid": "[str]",       ~/~/   MQTT client identity: Custom
315 "qos":[int],                 ~/~/  (Optional) MQTT service quality: 0
316 "username":"[str]",     ~/~/   Agent name of mqtt: application ID of TTN
317 "password":"[str]",      ~/~/  The proxy password of mqtt: application access key of TTN
318 "topic":"[str]",              ~/~/ The topic of mqtt subscription: TTN is + / devices / + / up
319 "connection":"[str]" },   ~/~/(Optional) mqtt is a string used for direct connection, composed of serveraddr and port
320 "mapwize_conf":{          ~/~/Map settings
321 "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
322 "venueid":"[str]",        ~/~/ (Optional)Indoor map area identification
323 "orgid":"[str]",           ~/~/  The identity of the user organizer
324 "universesid":"[str]",   ~/~/The range indicator of the indoor map, find it on the universes page
325 "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
326 },
327 "loracloud":{
328 "token":  "[str]"          ~/~/The password string of loracloud location service, the outdoor map must fill in the account token of loracloud
329 )))
330 )))
331
332 (((
333 }
334 )))
335
336 (% class="box" %)
337 (((
338 (((
339 "rssi_conf": {
340 "rssirate": [int],          ~/~/ (Optional) A basis for rssi calculation distance, the rssi value (absolute value) when the beacon is 1 meter apart 
341 "rssidiv": [float] }        ~/~/ (Optional) rssi measures an attenuation value of distance. As the distance to the beacon is farther, the value changes speed
342 )))
343 )))
344
345 (((
346 }
347
348
349
350 )))
351
352 * (% style="color:blue" %)**Parameter acquisition method of configuration file:**
353
354
355
356 (% class="box" %)
357 (((
358 "username":"[str]"
359 )))
360
361
362 [[image:image-20220526151707-12.png]]
363
364 username
365
366
367
368 (% class="box" %)
369 (((
370 "password":"[str]"     
371 )))
372
373 [[image:image-20220526151736-13.png]]
374
375 password
376
377
378
379 (% class="box" %)
380 (((
381 "apikey": "[str]"
382 )))
383
384 [[image:image-20220526151819-14.png||height="588" width="1203"]]
385
386 apikey
387
388
389
390 (% class="box" %)
391 (((
392 "orgid":"[str]"
393 )))
394
395 [[image:image-20220526152014-15.png]]
396
397 orgid
398
399
400
401 (% class="box" %)
402 (((
403 "universesid":"[str]"
404 )))
405
406 [[image:image-20220526152115-16.png]]
407
408 universesid
409
410
411
412 (% class="box" %)
413 (((
414 "placetype": "[str]"
415 )))
416
417 [[image:image-20220526152150-17.png]]
418
419 placetype
420
421
422
423 (% style="color:blue" %)**Here are two ways to enter the server:**
424
425 (% style="color:red" %)**1. WinSCP**
426
427 [[image:image-20220526152303-18.png]]
428
429
430 [[image:image-20220526152355-19.png]]
431
432
433 [[image:image-20220526152912-20.png]]
434
435 way1
436
437
438
439 (% style="color:red" %)**2. secureCRT**
440
441 [[image:image-20220526153145-22.png]]
442
443 [[image:image-20220526153236-23.png]]
444
445 [[image:image-20220526153304-24.png]]
446
447 way2
448
449
450
451 = 6.  Test Result =
452
453
454 The real-time position on the map is obtained according to the moving change of LBT1.
455
456
457 [[image:image-20220526153424-25.png||height="693" width="1414"]]