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
86 (((
87 (((
88 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.
89 )))
90 )))
91
92 4. Upload Floor plan.
93
94 [[image:https://wiki.dragino.com/images/thumb/d/d1/Beacon12.png/800px-Beacon12.png||alt="File:Beacon12.png" height="196" width="598"]]
95
96 add images
97
98 5. Create Layer
99
100 [[image:https://wiki.dragino.com/images/thumb/0/0e/Beacon13.png/600px-Beacon13.png||height="208" width="600"]]
101
102 create layer
103
104 (((
105 6. Add iBeacon position info. Drag the iBeacon to match position and input the UUID, MAJOR and MINOR of this iBeacon.
106 )))
107
108 [[image:https://wiki.dragino.com/images/thumb/1/1d/Beacon14.png/600px-Beacon14.png||height="261" width="600"]]
109
110 create iBeacon
111
112 = 3. Configure TTN =
113
114 == 3.1 Configure LBT1 to Upload data to TTN ==
115
116 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.
117
118 == 3.2 Decoder in TTN ==
119
120 (% class="box" %)
121 (((
122 function Decoder(bytes, port) {
123 \\~/~/ Decode an uplink message from a buffer
124 \\~/~/ (array) of bytes to an object of fields.
125 \\value = bytes[0] << 8 | bytes[1];
126 \\var batV = value/1000;~/~/Battery,units:V
127 \\var mode = bytes[5];
128 \\~/~/var value=(bytes[3]-0x30)*1000 +(bytes[5]-0x30)*100 + (bytes[5]-0x30)*10 +(bytes[6]-0x30);
129 \\~/~/var value = bytes.slice(3);
130 \\var i;
131 \\var con;
132 \\var str = "";
133 \\var major = 1;
134 \\var minor = 1;
135 \\var rssi = 0;
136 \\var addr = "";
137 \\if(mode ==2 ) {
138 \\ for(i = 38 ; i<50 ; i++) {
139 \\ con = bytes[i].toString();
140 \\ str += String.fromCharCode(con);
141 \\ }
142 \\ addr = str;
143 \\ str = "";
144 \\ for(i = 6 ; i<38 ; i++) {
145 \\ con = bytes[i].toString();
146 \\ str += String.fromCharCode(con);
147 \\ }
148 \\ value = str;
149 \\}
150 \\if(mode == 3 ) {
151 \\ str = "";
152 \\ for(i = 18 ; i < 22 ; i++) {
153 \\ con = bytes[i].toString();
154 \\ str += String.fromCharCode(con);
155 \\ }
156 \\ major = parseInt(str, 16);
157 \\ str = "";
158 \\ for(i = 22 ; i < 26 ; i++) {
159 \\ con = bytes[i].toString();
160 \\ str += String.fromCharCode(con);
161 \\ }
162 \\ minor = parseInt(str, 16);
163 \\ str = "";
164 \\ for(i = 28 ; i < 32 ; i++) {
165 \\ con = bytes[i].toString();
166 \\ str += String.fromCharCode(con);
167 \\ }
168 \\ rssi = parseInt(str);
169 \\ str = "";
170 \\ for(i = 6 ; i < 18 ; i++) {
171 \\ con = bytes[i].toString();
172 \\ str += String.fromCharCode(con);
173 }
174 \\ value = str;
175 }
176 \\if(mode == 1) {
177 \\ for(i = 6 ; i<11 ; i++) {
178 \\ con = bytes[i].toString();
179 \\ str += String.fromCharCode(con);
180 \\ }
181 \\ value = str;
182 }
183 \\var uuid = value;
184 \\var alarm = bytes[2] >> 4 & 0x0F;
185 \\var step_count = (bytes[2] & 0x0F) << 16 | bytes[3] << 8 | bytes[4];
186 \\return {
187 UUID: uuid,
188 ADDR: addr,
189 MAJOR: major,
190 MINOR: minor,
191 RSSI:rssi,
192 STEP: step_count,
193 ALARM: alarm,
194 BatV:batV,
195 };
196 }
197
198 )))
199
200 = 4. Set Up Converter Server =
201
202 * (((
203 How to install and run this service on Linux?
204 )))
205
206 (((
207 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).
208 )))
209
210 (((
211 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.
212 )))
213
214 (((
215 System: Debian / Ubuntu
216 )))
217
218 (% class="box" %)
219 (((
220 step:
221 \\1. sudo apt install libcurl4-dev 
222 \\2. sudo apt install  gcc automake autoconf libtool make cmake
223 \\3. git clone -b master https:~/~/github.com/mikayong/location.git
224 \\4. cd location/libmqtt
225 \\5. mkdir build
226 \\6. cd build && cmake ../
227 \\7. make && sudo make install 
228 \\8. cd ../
229 \\9. make 
230 \\10. sudo cp location_conf.json  /etc/
231 \\11. Edit the configuration file, and run the location service in the background: ./location &
232 )))
233
234 (((
235 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
236 )))
237
238 = 5. Configuration file: location_conf.json =
239
240 * (((
241 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.
242 )))
243
244 (((
245 { "location_conf": {
246 )))
247
248 (% class="box" %)
249 (((
250 (((
251 "loctype": "indoor",       ~/~/ indoor/outdoor
252 "locmap": "mapwize"    ~/~/   Map interface: mapwize, traccar
253 )))
254 )))
255
256 (((
257 }, "mqtt_conf": {
258 )))
259
260 (% class="box" %)
261 (((
262 (((
263 "servaddr": "[str]",    ~/~/     Lorawan server address: Refer to TTN app handler:eu.thethings.network
264 "servport": [int],       ~/~/   Lorawan server port: 1883
265 "clientid": "[str]",       ~/~/   MQTT client identity: Custom
266 "qos":[int],                 ~/~/  (Optional) MQTT service quality: 0
267 "username":"[str]",     ~/~/   Agent name of mqtt: application ID of TTN
268 "password":"[str]",      ~/~/  The proxy password of mqtt: application access key of TTN
269 "topic":"[str]",              ~/~/ The topic of mqtt subscription: TTN is + / devices / + / up
270 "connection":"[str]" },   ~/~/(Optional) mqtt is a string used for direct connection, composed of serveraddr and port
271 "mapwize_conf":{          ~/~/Map settings
272 "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
273 "venueid":"[str]",        ~/~/ (Optional)Indoor map area identification
274 "orgid":"[str]",           ~/~/  The identity of the user organizer
275 "universesid":"[str]",   ~/~/The range indicator of the indoor map, find it on the universes page
276 "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
277 },
278 "loracloud":{
279 "token":  "[str]"          ~/~/The password string of loracloud location service, the outdoor map must fill in the account token of loracloud
280 )))
281 )))
282
283 (((
284 }
285 )))
286
287 (% class="box" %)
288 (((
289 (((
290 "rssi_conf": {
291 "rssirate": [int],          ~/~/ (Optional) A basis for rssi calculation distance, the rssi value (absolute value) when the beacon is 1 meter apart 
292 "rssidiv": [float] }        ~/~/ (Optional) rssi measures an attenuation value of distance. As the distance to the beacon is farther, the value changes speed
293 )))
294 )))
295
296 (((
297 }
298 )))
299
300 * Parameter acquisition method of configuration file:
301
302 (% class="box" %)
303 (((
304 "username":"[str]"
305 )))
306
307 [[image:https://wiki.dragino.com/images/thumb/d/da/Beacon50.png/600px-Beacon50.png||height="185" width="600"]]
308
309 username
310
311 (% class="box" %)
312 (((
313 "password":"[str]"     
314 )))
315
316 [[image:https://wiki.dragino.com/images/thumb/b/bd/Beacon51.png/800px-Beacon51.png||alt="File:Beacon51.png" height="259" width="598"]]
317
318 password
319
320 (% class="box" %)
321 (((
322 "apikey": "[str]"
323 )))
324
325 [[image:https://wiki.dragino.com/images/thumb/5/53/Qwe3.png/800px-Qwe3.png||alt="File:Qwe3.png" height="325" width="606"]]
326
327 apikey
328
329 (% class="box" %)
330 (((
331 "orgid":"[str]"
332 )))
333
334 [[image:https://wiki.dragino.com/images/thumb/f/f4/Qwe4.png/800px-Qwe4.png||alt="File:Qwe4.png" height="304" width="622"]]
335
336 orgid
337
338 (% class="box" %)
339 (((
340 "universesid":"[str]"
341 )))
342
343 [[image:https://wiki.dragino.com/images/thumb/9/9a/Qwe5.jpg/600px-Qwe5.jpg||height="424" width="600"]]
344
345 universesid
346
347 (% class="box" %)
348 (((
349 "placetype": "[str]"
350 )))
351
352 [[image:https://wiki.dragino.com/images/thumb/9/93/Qwe6.png/600px-Qwe6.png||height="318" width="600"]]
353
354 placetype
355
356
357 **Here are two ways to enter the server:**
358
359 **~1. WinSCP**
360
361 [[image:https://wiki.dragino.com/images/thumb/6/6b/Ibeacon4.jpg/600px-Ibeacon4.jpg||height="385" width="600"]]
362
363 [[image:https://wiki.dragino.com/images/thumb/7/78/Ibeacon5.jpg/600px-Ibeacon5.jpg||height="385" width="600"]]
364
365 [[image:https://wiki.dragino.com/images/thumb/c/cd/Ibeacon6.jpg/800px-Ibeacon6.jpg||alt="File:Ibeacon6.jpg" height="362" width="599"]]
366
367 way1
368
369 **2. secureCRT**
370
371 [[image:https://wiki.dragino.com/images/thumb/7/7b/Ibeacon7.jpg/600px-Ibeacon7.jpg||height="326" width="600"]]
372
373 [[image:https://wiki.dragino.com/images/thumb/6/64/Ibeacon8.jpg/600px-Ibeacon8.jpg||height="326" width="600"]]
374
375 [[image:https://wiki.dragino.com/images/thumb/d/de/Ibeacon9.jpg/800px-Ibeacon9.jpg||alt="File:Ibeacon9.jpg" height="327" width="602"]]
376
377 way2
378
379 = 6. Test Result =
380
381 The real-time position on the map is obtained according to the moving change of LBT1.
382
383 [[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