UNIVERSITÀ DEGLI STUDI DI MODENA E REGGIO EMILIA
Progetto e Sviluppo di un Sistema per la
Geolocalizzazione Indoor basata su tecnologia Bluetooth Low Energy
Dipartimento di Scienze Fisiche, Informatiche e Matematiche
CORSO DI LAUREA IN INFORMATICA
Relatore:
Ing. Riccardo Martoglia
Candidato:
Luca Betti
Tirocinio presso Lapsy Srl
Lapsy è una start-up Modenese incentrata sullo sviluppo di sistemi Bluetooth per diversi segmenti di mercato.
In particolare si occupa dello sviluppo di applicazioni che sfruttando la geolocalizzazione delle persone,
consentendo attività di mobile advertising, mobile
payment ed applicazioni healthcare & fitness adoperate su smartphone e smartwatch.
Attività di tirocinio
Sviluppo di un sistema di geolocalizzazione indoor all’interno di un Hotel situato a Roma per il controllo movimenti del personale.
Sala da pranzo
Salotto Hall
notifica uscita
Introduzione agli strumenti principali
Antenna Braccialetti
(Beacon)
• UUID
• Cod_Zona
• Tenant_ID
• UUID
• Major
• Minor
Problematiche affrontate
Configurazione
Gestione segnali
Autonomia
Testing
Configurazione
Read
TkInter ConfigParser python-wifi 0.6.1
Problematiche affrontate
Configurazione
Gestione segnali
Autonomia
Testing
Scenario - Gestione Segnali
Invia segnali
Gestione segnali
Controllo
corrispondenza UUID
Estrazione valori
Memorizzazion e segnale
Controllo evento
Segnalazione al server
Aggiornamento lista beacon presenti
<<uses>
>
<<uses>
>
Scenario - Estrazione valori
Invia segnali
Gestione segnali
Controllo
corrispondenza UUID
Estrazione valori
Memorizzazion e segnale
Controllo evento
Segnalazione al server
Aggiornamento lista beacon presenti
<<uses>
>
<<uses>
>
def scan():
" Ricerca i segnali di advertising "
command1 = "timeout -s SIGINT 1s hcitool -i hci0 lescan"
command2 = "timeout -s SIGINT 1s hcidump --raw"
args1 = shlex.split(command1) p1 = subprocess.Popen(args1,
stdout=subprocess.PIPE,stderr=subproces s.PIPE)
args2 = shlex.split(command2) p2 = subprocess.Popen(args2,
stdout=subprocess.PIPE,stderr=subproc ess.PIPE)
testo,errore=p2.communicate() return testo,errore
RSSI -80
RSSI
-60 RSSI
-45
Beacon RSSI -80: 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 af
Beacon RSSI -60: 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 01 c1
Beacon RSSI -45: 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 02 d2
UUID Major Minor
Complemento a 2 della potenza
percepita
Scenario – Memorizzazione segnale
Invia segnali
Gestione segnali
Controllo
corrispondenza UUID
Estrazione valori
Memorizzazion e segnale
Controllo evento
Segnalazione al server
Aggiornamento lista beacon presenti
<<uses>
>
<<uses>
>
Beacon
TIME AVERAGE_POWER
UUID
MAJOR
MINOR
LOG_SIGNAL
?
?
?
?
?
?
Potenza 1 Potenza 2 Potenza 3 Potenza 4 Potenza 5 Media Pot
-55 -52 -57 -58 -52 ~ -54
def setAveragePower(self,power):
" Aggiunge una potenza rilevata "
self.averagePower.append(abs(power)) def delAveragePower(self):
" Elimina la potenza rilevata meno recente "
del self.averagePower[0]
def get_media(self):
" Calcola e restituisce la media delle potenze "
somma = 0
for val in self.averagePower:
somma = somma + val
return somma/len(self.averagePower)
Scenario – Controllo evento
Invia segnali
Gestione segnali
Controllo
corrispondenza UUID
Estrazione valori
Memorizzazion e segnale
Controllo evento
Segnalazione al server
Aggiornamento lista beacon presenti
<<uses>
>
<<uses>
>
Controlli applicati
Presenza Beacon (spostamento)
Entrata nuovo Beacon
Throttling
Potenza 1 Potenza 2 Potenza 3 Potenza 4 Potenza 5 Media Pot
-55 -52 -57 -58 -52 ~ -54
Potenza 1 Potenza 2 Potenza 3 Potenza 4 Potenza 5 Media Pot
-52 -57 -58 -52 -57 ~ -55
Shift a sinistra Nuova potenza:
-57 RSSI
Scenario – Aggiornamento Lista
Invia segnali
Gestione segnali
Controllo
corrispondenza UUID
Estrazione valori
Memorizzazion e segnale
Controllo evento
Segnalazione al server
Aggiornamento lista beacon presenti
<<uses>
>
<<uses>
>
payload = json.dumps(
{
"beac_uuid": str(beacon.UUID),
"beac_major": beacon.major,
"beac_minor": beacon.minor,
"ten_id": beacon.cod_tenid,
"zona_code": str(beacon.cod_zona),
"viol_mon_type": cViolation,
"log_signal": float(beacon.log_signal),
"battery": float(beacon.battery) }
)
headers = {'mime-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)
Segnalazione al server
Problematiche affrontate
Configurazione
Gestione segnali
Autonomia
Testing
Autonomia
Aggiornamenti
Riavvio automatico
30 min
for fileM in righe:
scarica_url = urls + fileM
r = requests.get(scarica_url, stream = True) with open(fileM, 'wb') as f:
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
for tripla in os.walk(os.getcwd()):
lista_file = tripla [2]
for elem in lista_file:
if elem == fileM:
tmppercorso = tripla [0] + '/' + elem nuovopercorso = tmppercorso[1:]
os.remove(nuovopercorso)
os.rename(fileM,nuovopercorso)
Aggiornamenti
Riavvio automatico
systemd
Autonomia
Problematiche affrontate
Configurazione
Gestione segnali
Autonomia
Testing
Testing
Potenza Alta (-5 dBm)
Frequenza 0.4s 1s 2.5s 5s
Distanz a
14m - - - -
12m - - - -
10m 85/95 80/90 87/96 -
8m 75/85 78/90 80/92 76/85
6m 80/90 77/90 75/86 76/85
4m 71/81 75/88 78/87 73/83
3m 69/79 70/80 70/80 68/78
2m 62/72 60/73 60/75 58/70
1m 56/70 (max 80) 66/79 55/70 60/70
50cm 56/58 53/56 52/53 48/50
30cm 35/38 37/39 35/37 34/37
Potenza Media (-10 dBm)
Frequenza 0.4s 1s 2.5s 5s
Distanz a
14m - - - -
12m - - - -
10m - - - -
8m 82/92 - - -
6m 74/85 85/99 80/90 76/90
4m 77/87 75/95 77/80 74/85
3m 72/83 80/94 75/84 73/83
2m 67/79 75/85 60/62 68/78
1m 55/75 52/54 62/75 55/70
50cm 56/60 57/61 56/60 50/53
30cm 40/43 39/42 37/39 37/38
Potenza Massima (0 dBm)
Frequenza 0.4s 1s 2.5s 5s
Distanz a
14m - - 85/95 -
12m 85/91 (max
99) 87/95 85/95 -
10m 74/88 77/88-90 80/90 73/77
8m 75/80 75/90 70/80-83 75/85
6m 70/80 68/78 70/80 68/80
4m 62/75 58/77 60/74 70/82
3m 60/80 57/75 60/75 55/70
2m 61/74 55/75 59/70 55/65
1m 55/72 (max
77) 60/75 54/70 50/65
50cm 56 53/56 50 48/50
30cm 37/39 37/38 34/37 34/37
Potenze (dBm) : 0, -5, -10, -20, -30;
Frequenza segnale (s) : 0.4, 1, 2.5, 5.
Nov 17 08:39:21 raspberrypi: Already up-to-date.
Nov 17 09:09:21 raspberrypi: Checking for new version...
Nov 17 09:09:21 raspberrypi: Sent ping
Nov 17 09:09:25 raspberrypi: No updates found.
[...]
Nov 17 09:09:53 raspberrypi: Sent 56697267-1122-3344-0000-001000000011+256+8, E, -86 Nov 17 09:09:57 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -77
Nov 17 09:10:01 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -83 [...]
Nov 17 09:10:53 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -78 Nov 17 09:10:58 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -51 Nov 17 09:10:58 raspberrypi: Sent 56697267-1122-3344-0000-001000000011+256+8, P, 82 Nov 17 09:11:02 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -65 [...]
Nov 17 09:11:18 raspberrypi: beacon 56697267-1122-3344-0000-001000000011+256+8 => -95 Nov 17 09:11:28 raspberrypi: Sent 56697267- 1122-3344-0000-001000000011+256+8, U, 0