Upload
codemotion
View
67
Download
1
Embed Size (px)
Citation preview
The Retail RevolutionAntonio Nappi & Enzo Carrea
Chi Siamo
Enzo Carrea (CarenZ)
Antonio Nappi
Team Leader - Indra
Software Engineer - Indra
Indra & Tim Foundry
Questo Prototipo nasce da un accordo di collaborazione siglato tra Tim ed Indra per lo sviluppo congiunto di soluzioni innovative nell’ambito dell’Internet of things e delle smart solutions.
Il prototipo è stato sviluppato all’interno dell’officina dell’innovazione “TIM Foundry”, dove si identificano e sperimentano le soluzioni più innovative nel settore della digital life.
Indice
• Dall’idea al prototipo• Proximity Marketing• Beacon• Le nostre scelte• Il prototipo• L’app• Stack Software• Nativa, Ibrida o Html
5
• Cordova• I plugin Cordova• Angular JS• Code Snippet• Sofia• Dashboard & Sofia• Dashboard Code
Snippet• Demo
Di cosa Parleremo
Dall’idea al prototipo
Qual è la differenza tra uno Store Fisico ed uno Store Online?Come può aumentare la produttività ed incrementare i clienti?
Quali dati possiamo raccogliere in uno Store Fisico?
Una tecnica di marketing che opera su un’area geografica delimitata e precisa attraverso tecnologie di comunicazione di tipo visuale e mobile con lo scopo di promuovere la vendita di prodotti e servizi. (Wikipedia)
Proximity Marketing
Come possiamo offrire una soluzione di Smart Store
BEACON
APP Mobile
Dashboard
Smart Store
I Beacon, sono dei dispositivi che grazie alla tecnologia Bluetooth 4.0 Smart Low Energy, possono interagire con periferiche e dispositivi senza impieghi energetici eccessivi. La tecnologia si presenta come un sistema di proposta contestuale di contenuti basati su microgeolocalizzazione.
Un sensore iBeacon definisce un'area il cui raggio varia da 20cm fino ad un massimo di 70 metri (all’aria aperta). Ogni dispositivo, dotato di un'apposita app, può, determinare il grado di prossimità e “scatenare” un azione
Beacon
I Beacon definiscono una Regione e sono identificata dalla seguente tripletta:
• UUID: (Universally Unique Identifier) – stringa che identifica I beacon
• Major: identifica un beacon e può essere comune a più beacon in una regione
• Minor: identifica un beacon e può essere unico nella stessa regione
Beacon
Abbiamo usato i beacons Estimote perché offrivano delle api multipiattaforma ed maggiormente documentati e supporati dalla community
http://developer.estimote.com/ibeacon/
APIestimote
Le nostre scelte
cordova.apache.org angularjs.org
sofia2.com developer.estimote.com
Stack Software
Perché Cordova e non un’app nativa ?
Cordova
Plugin Cordova
• Bluetooth• Vibrazione • Device-Motion• Device-Orentation• Estimote-Plugin
I plugin Cordova
Angular come framework per il nostro prototipo
Librerie Javascript utilizzate• BlueImp per i carousel• OnSen per rendere compliant le due
soluzioni iOS ed Android• SwetAlert, Stroll
Angular JS
Presentation
Logic
Adapter
Mobile Platform
Architettura dell’App
<body ng-controller="AppController" ontouchstart="myEstimote.onTouchStart(event);" ontouchmove="myEstimote.onTouchMove(event);" ontouchcancel="myEstimote.onTouchCancel(event);"> <ons-navigator var="myNavigator"><ons-page ng-controller="MasterController" ng-device-backbutton="exitApp()"> <ons-toolbar fixed-style> <div class="center"></div> <div class="right"> <ons-button ng-click="showSettings()" class="settings-btn btnCustom"> <ons-icon icon="ion-android-settings" fixed-width="true"></ons-icon> </ons-button> <ons-button onClick="callRetailer()" class="shopping-cart-btn btnCustom"> <ons-icon icon="ion-android-person" fixed-width="true"></ons-icon> </ons-button> <ons-button ng-click="showShoppingCart()" class="shopping-cart-btn btnCustom"> <ons-icon icon="ion-android-cart" fixed-width="true"></ons-icon> <span class="shopping-cart-counter">{{getCartCounter()}}</span> </ons-button> </div> </ons-toolbar> <div> <div align="center"> <img src="img/tim_proximity_logo6.png" alt="TIM Logo" width="200" height="100" align="middle" style="margin: 20px auto;"> </div> <div align="center"> <ons-button class="circle-button grow" ng-click="startRanging()" style="margin-top: 70px !important;"> CERCA </ons-button>
Code SnippetPresentation
$("#loading_label").show(); $scope.items = {}; $scope.ons.navigator.pushPage('offers.html', { title: "Offerte", onTransitionEnd: function () { // startStroll(); } }); beaconInRange = false; if (IS_ANDROID || IS_IPHONE) { myEstimote.onStartRanging(); }
function onRange() var beaconVincitore = beaconInfo.beacons[0];$.each(beaconInfo.beacons, function(key, beacon)
{if(beacon.distance < beaconVincitore.distance){
beaconVincitore = beacon;}
});onBeaconRange(beaconVincitore);
EstimoteBeacons.startRangingBeaconsInRegion({}, // Empty region matches all beacons.onRange,onError);
function onStartRangin ()
function startRanging()
Logic
Code Snippet
…if(beacon.minor == beaconMin && beacon.major == beaconMaj) { beaconLastRangeTime = new Date().getTime(); br = beacon.distance; posElement = search('B04',mapBeaconPOI); idPoi = mapBeaconPOI[posElement].idPoi; idCategoria = mapBeaconPOI[posElement].cat; descrizione = mapBeaconPOI[posElement].descrizione; if (!beaconInRange && (beacon.proximity == 2 || beacon.proximity == 3) && myNavigator.getCurrentPage().page == "offers.html") { swal(frasiCategorie[idCategoria-1][0]); SetObjBeaconData(UUIDApp,"BO4",idPoi,descrizione,beacon.proximity); if (VIBRATION_SETTING_ENABLE) navigator.vibrate(1000); resetIsBaeconInRange(); beaconInRange = true; angular.element($("#offersControllerId")).scope().refreshList(idCategoria); } if (beaconInRange && beacon.proximity == 1 && (currTime - lastImmediateOfferPushTime) > 4000 && myNavigator.getCurrentPage().page == "offers.html") { lastImmediateOfferTime = new Date().getTime(); currentImmediateOfferId = 4; SetObjBeaconData(UUIDApp,"BO4",idPoi,descrizione,beacon.proximity); if (VIBRATION_SETTING_ENABLE) navigator.vibrate(1000); lastImmediateOfferPushTime = new Date().getTime(); angular.element($("#offersControllerId")).scope().showDetailFromBeacon(idCategoria, idPoi); } } …
function onBeaconRange(beacon)
Logic
Code Snippet
… var currTime = new Date().getTime(); if (beacon1InRange && (currTime - beacon1LastRangeTime) > 5000) { beacon1InRange = false; } if (beacon2InRange && (currTime - beacon2LastRangeTime) > 8000) { beacon2InRange = false; posElement = search('B02',mapBeaconPOI); idPoi = mapBeaconPOI[posElement].idPoi; idCategoria = mapBeaconPOI[posElement].cat; swal(frasiCategorie[idCategoria-1][1]); angular.element($("#offersControllerId")).scope().refreshList(); } }…
function checkBeaconOutOfRange()
…checkBeaconOutOfRange();sendBeaconDataTimer += deltaTime;if (sendBeaconDataTimer >= intervallo) { // in secondssendBeaconDataTimer = 0;sendBeaconData(); }…
function update()Logic
Code Snippet
var jsonData = { Feed:{ idApp:UUIDApp, intervallo:intervallo, dateTime: data, idBeacon: idBeacon, idPOI: idPoi, descrizione:descrizione, range: proximity, isEnabled: true } }; $.ajax({ url:'http://130.211.88.57/sib-api/api/v1/feedretailbeaconsdatait', type:'POST', dataType:'json', contentType:'application/json', headers:{ 'Accept':'application/json, text/javascript', 'X-SOFIA2-APIKey':'172f6f768a614da1b1c8abea9ee44fbd' }, data:JSON.stringify(jsonData), success: function(data){ console.log(data);},
function sendBeaconData()
Feed
Code Snippet
I dati raccolti dall’ Applicazione Mobile vengono inviati a Sofia anche per generare una pubblicità personalizzata per l’utente che si avvicina alla Cassafunction sendBeaconDataCart(){
Feed:{ idEvent:"Cassa", idApp:UUIDApp, dateTime: data, last_instance:2, infos:"string", } };$.ajax({ url:'http://130.211.88.57/sib-api/api/v1/feedretaileventit', type:'POST', dataType:'json', contentType:'application/json', headers:{ 'Accept':'application/json, text/javascript', 'X-SOFIA2-APIKey':'172f6f768a614da1b1c8abea9ee44fbd' }, data:JSON.stringify(jsonData)…..
Code Snippet
FEEP IoT Platform SOFIA2
Tutti i dati raccolti dall’app vengono caricati tramite Sofia in un database NoSql Mongo. La Dashboard sviluppata in Angular effettua delle query Mongo sul Database per ottenere i Dati da mostrare
Le query mongo vengono gestite tramite la libreria javascript di Sofia reperibile dal Sito sofia2.com
Dashboard & Sofia
Il prototipo di Dashbord permette la rappresentazione dei dati RealTime e di Storico più altri dettagli detto store
Dashboard Code Snippet
function loadNumberOfUserInStoreActual(ssapMessageJson){
if(ssapMessageJson===null || ssapMessageJson===undefined){console.log('impossibile recuperare i dati: null json message');} else { if(ssapMessageJson.body.data===null || ssapMessageJson.body.data === undefined) return; if(ssapMessageJson.body.data.length>0) { var _numeroUtenti = ssapMessageJson.body.data[0].numeroUtenti; _scope.numeroUtentiNelloStoreActual = _numeroUtenti; } } _scope.$digest();
… var queryMongo = "db.feedRetailBeaconsData.aggregate([" + "{'$match':{'Feed.dateTime':{'$gte': '"+_date+"'}}}," + "{'$project':{'Feed.idApp':1,'Feed.dateTime':1,'x':1}}," + "{'$group': {'_id':'$Feed.idApp'}}," + "{'$group': {'_id':'$x', 'numeroUtenti':{'$sum':1} } }," + "{'$project':{'_id':1,'numeroUtenti':1}} " + "])";
sofia2.queryWithQueryType ( queryMongo, ontoSmartRetail, "NATIVE", null, loadNumberOfUserInStoreActual);….
Esempio di codice per la richiesta del dato Utenti Fidelizzati nello store.