Nella parte 1 di questo blog, abbiamo descritto come le telecamere termiche e altre nuove tecnologie diventeranno una seconda natura nel mondo post-COVID. Per questa parte mostreremo una configurazione di esempio.
Abbiamo usato un server di gestione video (VMS) con una piattaforma software che si integra con telecamere di centinaia di fornitori diversi, comprese le telecamere che supportano l'analisi in-camera e/o le immagini termiche. Gli utenti possono configurare gli eventi all'interno della piattaforma VMS o nel motore di regole di una telecamera intelligente. Questi eventi possono essere trigger di distanza dagli oggetti (cioè il rilevamento di oggetti con una distanza inferiore a 1,5 metri tra loro), trigger di conteggio degli oggetti (cioè il rilevamento di un certo numero di visitatori all'interno di un luogo) o trigger di temperatura (cioè il rilevamento di oggetti con temperatura superiore a 38 gradi centigradi).
Ognuno di questi eventi può attivare una chiamata HTTP all'API Userful, permettendo al server Userful di cambiare automaticamente il contenuto su un video wall, un singolo display o un gruppo di display. Quanto è semplice da implementare? Ci vogliono solo tre passi:
Il risultato finale (usando Python) contiene 26 righe di codice nell'applicazione principale:
se __name__ == '__main__':
# Collega il socket alla porta
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.1.100', 8081)
print ('Starting up on %s port %s' % server_address)
sock.bind(indirizzo_server)
# Ascolta le connessioni in arrivo
sock.listen(1)
mentre True:
# Aspetta una connessione proveniente da un sensore esterno
print ('waiting for a connection')
connessione, indirizzo_cliente = sock.accept()
provare:
print ('connessione da', indirizzo_cliente)
# Ricevere i dati in piccoli pezzi e leggerli
mentre True:
dati = connection.recv(512)
se dati:
# estrarre i dati provenienti dalla chiamata HTTP Camera.
camera = extract(data)
# effettua il login al server Userful per recuperare il cookie di autenticazione
session_header = login()
# determina cosa sta suonando attualmente sui display
current_source = is_playing(session_header, 'Shop-Floor')
# passa il contenuto dei display ad una sorgente prefconfigurata (in
# questo esempio un messaggio di avvertimento HTML
switch_source(session_header,'shop-Floor','HTML Warning')
# aspetta per 5 secondi
time.sleep(5)
# torna al contenuto che stava originariamente riproducendo
switch_source(session_header,'Shop-Floor', current_source)
#delete_source(session_header,'PIP_Dynamic')
time.sleep(5)
break
else:
print (sys.stderr, 'no more data from', client_address)
break
infine:
# Pulire la connessione
connection.close()
Perciò, esaminiamo questo progetto passo per passo.
Passo 1: configurare gli eventi sulla camera o VMS
In questo esempio usiamo il motore di analisi integrato della nostra piattaforma VMS di terze parti che riceve e registra i feed delle telecamere da più telecamere. Gli amministratori possono configurare diversi eventi all'interno del motore di regole della telecamera... Questo può essere un trigger di movimento o un trigger di analisi con cui il software VMS analizza i feed video in entrata e rileva gli eventi per ogni telecamera, per esempio:
Ogni evento ha una chiamata all'azione; per esempio una RICHIESTA HTTP al nostro ascoltatore web a 192.168.1.100:8081 con contenuti del messaggio come il nome della telecamera e la qualificazione dell'evento. Un esempio di regola dell'evento è mostrato nell'immagine qui sotto.
Passo 2: l'ascoltatore HTTP
Un server web HTTP è un semplice processo che viene eseguito sulla vostra macchina e fa esattamente due cose:
In this example; our listener is listening to port 8081 on it's external Ethernet interface on IP address 192.168.1.100. If incoming connections are detected, the data received in the HTTP message is collected and processed under a <call to action> routine. This is the routine of instructing the Userful server what to do. Enter your text here ...
# Bind il socket alla porta
importare socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
indirizzo_server = ('192.168.1.100', 8081)
print ('Starting up on %s port %s' % server_address)
sock.bind(indirizzo_server)
# Ascolta le connessioni in arrivo
sock.listen(1)
mentre True:
# Aspetta una connessione proveniente da un sensore esterno
print ('waiting for a connection')
connessione, indirizzo_cliente = sock.accept()
provare:
print ('connessione da', indirizzo_cliente)
# Ricevere i dati in piccoli pezzi e leggerli
mentre True:
dati = connection.recv(512)
se dati:
else:
print (sys.stderr, 'no more data from', client_address)
break
infine:
# Pulire la connessione
connection.close()
Prima di cambiare la nostra sorgente sugli schermi, controlliamo quale sorgente è attualmente in riproduzione in una zona (cioè un gruppo di schermi). In questo modo possiamo tornare al contenuto originale una volta che un evento è passato. Il codice qui sotto rileverà il nome della sorgente attualmente in riproduzione (cioè il nome del lettore di segnaletica, o altro). Quando chiamiamo questa funzione, passiamo il nostro cookie di autenticazione e il nome della zona.
def is_playing (session_header, zona):
get_url = api_url_base + '/api/zone/byname/' + zona
response = requests.get(url=get_url, headers=session_header)
se response.status_code == 200
dati = response.content
dict = json.loads(data)
sourceID = dict['playingSourceId']
sourceName = get_source_info(session_header,sourceID)
print(sourceName, 'sta giocando')
else:
print (response.status_code)
ritorna sourceName
def get_source_info (session_header, sourceID):
get_url = api_url_base + '/api/sources/' + sourceID
response = requests.get(url=get_url, headers=session_header)
se response.status_code == 200
dati = response.content
dict = json.loads(data)
altrimenti:
stampa (response.status_code)
return dict['sourceName']
Ora che abbiamo determinato il nome della sorgente attualmente in riproduzione, possiamo cambiare la sorgente per quella zona:
def switch_source(session_header, zone_name, source_name):
post_url = api_url_base + '/api/zone/byname/' + zone_name + '/switch?destinationSourceName=' + source_name
response = requests.put(url=post_url, headers=session_header)
valore = Falso
if response.status_code == 200
dati = response.content
value = json.loads(data)["isPlaying"]
print('Fonte commutata')
else:
stampa (response.status_code)
restituire il valore
And that is it…. The <CALL TO ACTION> in our HTTP Listener becomes: (1) retrieve the AUTH cookie for the Userful Server, (2) Detect current source playing in a particular zone, (3) Switch the content on the displays to a 'HTML Warning' message stored on the local server (4) Pause for some time, (5) Switch back to the original source.
# accede al server Userful per recuperare il cookie di autenticazione
session_header = login()
# determina ciò che è attualmente in riproduzione sui display
source = is_playing(session_header, 'Zone-3')
# cambia il contenuto dei display in una sorgente prefconfigurata (in questo esempio un messaggio di avvertimento HTML
switch_source(session_header,'Zone-3','HTML Warning')
# aspetta per 5 secondi
time.sleep(5)
# passa di nuovo al contenuto che stava originariamente riproducendo
switch_source(session_header,'Zone-3', source)
#delete_source(session_header,'PIP_Dynamic')
time.sleep(5)
break
Possiamo espandere questo script guardando effettivamente i dati che sono stati ricevuti nella chiamata HTTP proveniente dalla telecamera o dalla piattaforma VMS. Questi dati possono contenere informazioni sulla telecamera e/o sulla fonte di attivazione e queste informazioni possono essere utilizzate per visualizzare diversi tipi di contenuti. Pensate ai feed delle telecamere in diretta o, se la telecamera sta contando le persone, alla visualizzazione di quanti clienti sono nel negozio e di quanti altri clienti possono entrare nel negozio.
Con la semplicità di REST-API, i clienti e gli integratori di sistema possono implementare soluzioni semplici per alcune caratteristiche tecnicamente sbalorditive. Non c'è bisogno di soluzioni puntuali da diversi fornitori. Solo un po' di immaginazione combinata con limitate capacità di codifica può portare lontano. Spero che abbiamo innescato il vostro interesse e non vediamo l'ora di impegnarci in ulteriori scambi di idee ed esempi.