Η χρήση κινητού τηλεφώνου σε όλο τον κόσμο αυξάνεται συνεχώς. Από το 2013, περίπου το 73% των χρηστών του Διαδικτύου κατανάλωσαν περιεχόμενο μέσω κινητής συσκευής και το ποσοστό αυτό αναμένεται να φτάσει κοντά στο 90% έως το 2017.
Υπάρχουν, φυσικά, πολλοί λόγοι για την κινητή επανάσταση. Αλλά ένα από τα πιο σημαντικά είναι ότι οι εφαρμογές για κινητά έχουν γενικά πρόσβαση σε πλουσιότερο περιβάλλον, καθώς σχεδόν όλα τα smartphone σήμερα είναι εξοπλισμένα με αισθητήρες τοποθεσίας, αισθητήρες κίνησης, bluetooth και wifi. Χρησιμοποιώντας τα δεδομένα τους, οι εφαρμογές μπορούν να επιτύχουν «ευαισθητοποίηση περιβάλλοντος» που μπορεί να αυξήσει δραματικά τις δυνατότητες και την αξία τους και να τις κάνει πραγματικά να ξεχωρίζει στα καταστήματα εφαρμογών.
Σε αυτό το σεμινάριο, θα διερευνήσουμε τη δημιουργία εφαρμογών με γνώμονα το περιβάλλον μέσω ενός σύνθετου παραδείγματος επεξεργασίας συμβάντων. Θα χρησιμοποιήσουμε ένα αρκετά απλό παράδειγμα: μια εφαρμογή τιμής καυσίμου που βρίσκει τις καλύτερες τιμές καυσίμων στην περιοχή σας.
Σε Σχεδιασμός ήρεμης τεχνολογίας , Μαρκ Γουίσερ και Τζον Σέλι Μπράουν περιγράφει ήρεμη τεχνολογία ως «αυτό που ενημερώνει αλλά δεν απαιτεί την εστίαση ή την προσοχή μας».
Οι εφαρμογές για κινητά με γνώμονα το περιβάλλον είναι πολύ συνεπείς με αυτήν την έννοια και αποτελούν ένα σημαντικό και πολύτιμο βήμα προς τα κάτω. Χρησιμοποιούν πληροφορίες με βάση τα συμφραζόμενα που συλλέγονται από τους αισθητήρες τους ώστε να παρέχουν προληπτικά στον χρήστη πολύτιμες πληροφορίες και το κάνουν με ελάχιστη προσπάθεια εκ μέρους του χρήστη. Οι Mark Weiser και John Seely Brown αναμφίβολα θα χειροκροτούν αυτήν την τεχνολογική πρόοδο.
Η συνειδητοποίηση περιβάλλοντος είναι η ιδέα ότι μια εφαρμογή μπορεί να αντιληφθεί και να αντιδράσει με βάση τα δεδομένα περιβάλλοντος στα οποία έχει πρόσβαση. Μια τέτοια εφαρμογή χρησιμοποιεί πλούσια δεδομένα αισθητήρων που είναι διαθέσιμα σε μια κινητή συσκευή για να παρέχει ακριβείς και σχετικές πληροφορίες στον χρήστη στο κατάλληλο περιβάλλον. Μέσα από τις τάσεις που παρατηρεί κατά τη διάρκεια της χρήσης της συσκευής ή / και μέσω των σχολίων που παρέχει ο χρήστης, μια τέτοια εφαρμογή μπορεί στην πραγματικότητα να «μάθει» με την πάροδο του χρόνου, καθιστώντας έτσι «πιο έξυπνο» και πιο χρήσιμο.
Σύνθετη επεξεργασία συμβάντων (CEP) είναι μια μορφή επεξεργασίας συμβάντων που χρησιμοποιεί πιο εξελιγμένες αναλύσεις πολλαπλών συμβάντων (δηλαδή, με την πάροδο του χρόνου, από διαφορετικές πηγές και ούτω καθεξής), που ενσωματώνει και αναλύει το περιεχόμενό τους για να συναγάγει πιο σημαντικές πληροφορίες και μοτίβα.
Σε μια εφαρμογή για κινητά, το CEP μπορεί να εφαρμοστεί σε συμβάντα που δημιουργούνται από τους αισθητήρες της κινητής συσκευής, καθώς και από εξωτερικές πηγές δεδομένων στις οποίες έχει πρόσβαση η εφαρμογή.
Για τους σκοπούς του σύνθετου οδηγού επεξεργασίας εκδηλώσεων, ας υποθέσουμε ότι οι λειτουργίες της εφαρμογής τιμής καυσίμου περιορίζονται στα ακόλουθα:
Εντάξει, ας ξεκινήσουμε.
Ας ξεκινήσουμε με τη λογική για να εντοπίζουμε αυτόματα τις τοποθεσίες σπιτιού και εργασίας του χρήστη. Προκειμένου να διατηρήσουμε τα πράγματα απλά για το περίπλοκο παράδειγμα επεξεργασίας συμβάντων, θα υποθέσουμε ότι ο χρήστης έχει ένα αρκετά κανονικό πρόγραμμα εργασίας. Μπορούμε λοιπόν να υποθέσουμε ότι ο χρήστης συνήθως θα βρίσκεται στο σπίτι μεταξύ 2 και 3 π.μ., και συνήθως θα βρίσκεται στο γραφείο του μεταξύ 2 και 3 μ.μ.
Με βάση αυτές τις υποθέσεις, ορίζουμε δύο κανόνες CEP και συλλέγουμε δεδομένα τοποθεσίας και χρόνου από το smartphone του χρήστη:
Ο αλγόριθμος υψηλού επιπέδου για την ανίχνευση τοποθεσιών απεικονίζεται παρακάτω.
Ας υποθέσουμε την ακόλουθη απλή δομή δεδομένων JSON για δεδομένα τοποθεσίας:
ποιο εργαλείο θα χρησιμοποιούσε ένας προγραμματιστής για να οπτικοποιήσει τη σχέση μεταξύ των μονάδων
{ 'uid': 'some unique identifier for device/user', 'location': [longitude, latitude] 'time': 'time in user's timezone' }
Σημείωση: Είναι πάντα καλή πρακτική να κάνετε αμετάβλητα δεδομένα αισθητήρα (ή τύπο τιμής), έτσι ώστε να μπορούν να χρησιμοποιηθούν με ασφάλεια από διαφορετικές ενότητες στη ροή εργασίας CEP.
Θα εφαρμόσουμε τον αλγόριθμό μας χρησιμοποιώντας ένα συνθετικό μοτίβο ενότητας , όπου κάθε ενότητα εκτελεί μόνο μία εργασία και καλεί στη συνέχεια όταν ολοκληρωθεί η εργασία. Αυτό συμμορφώνεται με το Unix Κανόνας αρθρωτότητας φιλοσοφία.
Συγκεκριμένα, κάθε ενότητα είναι μια συνάρτηση που δέχεται ένα config
αντικείμενο και ένα next
συνάρτηση που καλείται να μεταδώσει τα δεδομένα στην επόμενη ενότητα. Κατά συνέπεια, κάθε μονάδα επιστρέφει μια λειτουργία που μπορεί να δεχτεί δεδομένα αισθητήρα. Εδώ είναι η βασική υπογραφή μιας ενότητας:
// nominal structure of each composable module function someModule(config, next) { // do initialization if required return function(data) { // do runtime processing, handle errors, etc. var nextData = SomeFunction(data); // optionally call next with nextData next(nextData); } }
Για να εφαρμόσουμε τον αλγόριθμό μας για τον υπολογισμό των τοποθεσιών σπιτιού και εργασίας του χρήστη, θα χρειαζόμαστε τις ακόλουθες ενότητες:
Κάθε μία από αυτές τις ενότητες περιγράφεται λεπτομερέστερα στις υποενότητες που ακολουθούν.
Το φίλτρο χρόνου μας είναι μια απλή λειτουργία που λαμβάνει τα συμβάντα δεδομένων τοποθεσίας ως είσοδο και μεταβιβάζει δεδομένα μόνο στο next
ενότητα εάν το συμβάν συνέβη εντός της χρονικής περιόδου ενδιαφέροντος. Το config
Τα δεδομένα για αυτήν την ενότητα αποτελούνται συνεπώς από τους χρόνους έναρξης και λήξης της χρονικής περιόδου ενδιαφέροντος. (Μια πιο εξελιγμένη έκδοση της ενότητας θα μπορούσε να φιλτράρει βάσει πολλαπλών χρονικών διαστάσεων.)
Εδώ είναι μια εφαρμογή ψευδοκώδικα της ενότητας φίλτρου χρόνου:
function timeFilter(config, next) { function isWithin(timeval) { // implementation to compare config.start <= timeval <= config.end // return true if within time slice, false otherwise } return function (data) { if(isWithin(data.time)) { next(data); } }; }
Η ευθύνη του συσσωρευτή είναι απλώς να συλλέγει δεδομένα τοποθεσίας και στη συνέχεια να μεταβιβάζεται στο next
μονάδα μέτρησης. Αυτή η λειτουργία διατηρεί έναν εσωτερικό κάδο σταθερού μεγέθους για την αποθήκευση δεδομένων. Κάθε νέα τοποθεσία που αντιμετωπίζεται προστίθεται στον κάδο έως ότου γεμίσει ο κάδος. Στη συνέχεια, τα συσσωρευμένα δεδομένα τοποθεσίας στον κάδο αποστέλλονται στην επόμενη ενότητα ως πίνακας.
Υποστηρίζονται δύο τύποι κάδων συσσωρευτών. Ο τύπος κάδου επηρεάζει τι γίνεται στα περιεχόμενα του κάδου μετά την προώθηση των δεδομένων στην επόμενη φάση, ως εξής:
Περιστρεφόμενος κάδος παραθύρου (type = 'tumbling'
): μετά την προώθηση δεδομένων, αδειάζει ολόκληρος ο κάδος και ξεκινά φρέσκος (μειωμένο μέγεθος κάδου πίσω στο 0)
Τύπος παραθύρου εκτέλεσης (type = 'running'
): μετά την προώθηση δεδομένων, απορρίπτει μόνο το παλαιότερο στοιχείο δεδομένων στον κάδο (μειώνει το μέγεθος κάδου κατά 1)
Εδώ είναι μια βασική εφαρμογή της ενότητας συσσωρευτών:
function accumulate(config, next) { var bucket = []; return function (data) { bucket.unshift(data); if(bucket.length >= config.size) { var newSize = (config.type === 'tumbling' ? 0 : bucket.length - 1); next(bucket.slice(0)); bucket.length = newSize; } }; }
Υπάρχουν φυσικά πολλές εξελιγμένες τεχνικές στη γεωμετρία συντεταγμένων για την ομαδοποίηση δεδομένων 2D. Εδώ είναι ένας απλός τρόπος συγκέντρωσης δεδομένων τοποθεσίας:
Ακολουθεί μια εφαρμογή αυτού του αλγορίθμου συμπλέγματος (χρησιμοποιώντας Lo-Dash
):
var _ = require('lodash'); function createClusters(location_data, radius) { var clusters = []; var min_points = 5; // Minimum cluster size function neighborOf(this_location, all_locations) { return _.filter(all_locations, function(neighbor) { var distance = distance(this_point.location, neighbor.location); // maximum allowed distance between neighbors is 500 meters. return distance && (500 > distance); } } _.each(location_data, function (loc_point) { // Find neighbors of loc_point var neighbors = neighborOf(loc_point, location_data, radius); _.each(clusters, function (cluster, index) { // Check whether some of the neighbors belong to cluster. if(_.intersection(cluster, neighbors).length){ // Expand neighbors neighbors = _.union(cluster, neighbors); // Remove existing cluster. We will add updated cluster later. clusters[index] = void 0; } }); if(neighbors.length >= min_points){ // Add new cluster. clusters.unshift(neighbors); } }); return _.filter(clusters, function(cluster){ return cluster !== void 0; }); }
Ο παραπάνω κώδικας προϋποθέτει την ύπαρξη distance()
συνάρτηση που υπολογίζει την απόσταση (σε μέτρα) μεταξύ δύο γεωγραφικών θέσεων. Δέχεται δύο σημεία τοποθεσίας με τη μορφή [longitude, latitude]
και επιστρέφει την απόσταση μεταξύ τους. Ακολουθεί ένα δείγμα υλοποίησης μιας τέτοιας συνάρτησης:
function distance(point1, point2) { var EARTH_RADIUS = 6371000; var lng1 = point1[0] * Math.PI / 180; var lat1 = point1[1] * Math.PI / 180; var lng2 = point2[0] * Math.PI / 180; var lat2 = point2[1] * Math.PI / 180; var dLat = lat2 - lat1; var dLon = lng2 - lng1; var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); var arc = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); var distance = EARTH_RADIUS * arc; return distance; }
Με τον καθορισμό και την εφαρμογή του αλγορίθμου συμπλέγματος (στη λειτουργία createClusters()
που παρουσιάστηκε νωρίτερα), μπορούμε να τον χρησιμοποιήσουμε ως βάση για τη μονάδα συμπλέγματος:
function clusterize(config, next) { return function(data) { var clusters = createClusters(data, config.radius); next(clusters); }; }
Όλες οι απαιτούμενες λειτουργίες εξαρτημάτων έχουν πλέον καθοριστεί, οπότε είμαστε έτοιμοι να κωδικοποιήσουμε τους κανόνες τοποθεσίας σπιτιού / εργασίας μας.
Εδώ, για παράδειγμα, είναι μια πιθανή εφαρμογή του κανόνα τοποθεσίας κατοικίας:
var CLUSTER_RADIUS = 150; // use cluster radius of 150 meters var BUCKET_SIZE = 500; // collect 500 location points var BUCKET_TYPE = 'tumbling'; // use a tumbling bucket in our accumulator var home_cluster = clusterize({radius: CLUSTER_RADIUS}, function(clusters) { // Save clusters in db }); var home_accumulator = accumulate({size: BUCKET_SIZE, type: BUCKET_TYPE}, home_cluster); var home_rule = timeFilter({start: '2AM', end: '3AM'}, home_accumulator);
Τώρα όποτε λαμβάνονται δεδομένα τοποθεσίας από έξυπνο τηλέφωνο (μέσω websocket, TCP, HTTP) προωθούμε αυτά τα δεδομένα στο home_rule
λειτουργία η οποία με τη σειρά της ανιχνεύει συστάδες για το σπίτι του χρήστη.
Στη συνέχεια, η 'τοποθεσία κατοικίας' του χρήστη θεωρείται ότι είναι το κέντρο του συμπλέγματος τοποθεσίας κατοικίας.
Σημείωση: Αν και αυτό μπορεί να μην είναι απολύτως ακριβές, αρκεί για το απλό μας παράδειγμα, ειδικά επειδή ο στόχος αυτής της εφαρμογής σε κάθε περίπτωση είναι απλώς να γνωρίζει την περιοχή γύρω από το σπίτι του χρήστη, αντί να γνωρίζει την ακριβή τοποθεσία του σπιτιού του χρήστη.
Ακολουθεί μια απλή συνάρτηση παραδείγματος που υπολογίζει το 'κέντρο' ενός συνόλου σημείων σε ένα σύμπλεγμα κατά μέσο όρο τα γεωγραφικά πλάτη και μήκη όλων των σημείων στο σύνολο συμπλέγματος:
function getCentre(cluster_data) { var len = cluster_data.length; var sum = _.reduce(cluster_data, function(memo, cluster_point){ memo[0] += cluster_point[0]; memo[1] += cluster_point[1]; return memo; }, [0, 0]); return [sum[0] / len, sum[1] / len]; }
Μια παρόμοια προσέγγιση θα μπορούσε να χρησιμοποιηθεί για τον υπολογισμό της θέσης εργασίας, με τη μόνη διαφορά ότι θα χρησιμοποιούσε ένα φίλτρο χρόνου μεταξύ 2 και 3 μ.μ. (σε αντίθεση με τις 2 και 3 π.μ.).
Η εφαρμογή καυσίμων μας είναι έτσι ικανή αυτομάτως εντοπίστε τις θέσεις εργασίας και οικίας του χρήστη χωρίς να απαιτείται παρέμβαση του χρήστη. Αυτός είναι ο υπολογιστής με γνώμονα το περιβάλλον και είναι ο καλύτερος!
Η σκληρή δουλειά για την επίτευξη συνειδητοποίησης περιβάλλοντος έχει γίνει τώρα, αλλά χρειαζόμαστε ακόμη έναν ακόμη κανόνα για να προσδιορίσουμε ποιες τιμές σταθμών καυσίμων θα παρακολουθούνται (δηλαδή, ποιοι σταθμοί καυσίμων είναι αρκετά κοντά στο σπίτι ή την τοποθεσία εργασίας του χρήστη για να είναι σχετικοί) Αυτός ο κανόνας χρειάζεται πρόσβαση σε όλες τις τοποθεσίες σταθμών καυσίμων για όλες τις περιοχές που υποστηρίζονται από την εφαρμογή καυσίμων. Ο κανόνας έχει ως εξής:
Αυτό μπορεί εύκολα να εφαρμοστεί χρησιμοποιώντας τη λειτουργία απόστασης που παρουσιάστηκε νωρίτερα ως φίλτρο θέσης για εφαρμογή σε όλους τους σταθμούς καυσίμων που είναι γνωστοί στην εφαρμογή.
Μόλις η εφαρμογή καυσίμου αποκτήσει τη λίστα των προτιμώμενων (π.χ. κοντινών) σταθμών καυσίμων για το χρήστη, μπορεί εύκολα να παρακολουθήσει τις καλύτερες τιμές καυσίμου σε αυτούς τους σταθμούς. Μπορεί επίσης να ειδοποιεί τον χρήστη όταν ένας από αυτούς τους σταθμούς καυσίμων έχει ειδικές τιμές ή προσφορές, ειδικά όταν ο χρήστης εντοπίζεται ότι βρίσκεται κοντά σε αυτούς τους σταθμούς καυσίμων.
Σε αυτό το σύνθετο σεμινάριο επεξεργασίας συμβάντων, έχουμε σχεδόν μόλις χαράξει την επιφάνεια του πληροφοριακού περιβάλλοντος.
Στο απλό μας παράδειγμα, προσθέσαμε το περιβάλλον τοποθεσίας σε μια κατά τα άλλα απλή εφαρμογή αναφοράς τιμής καυσίμου και το κάναμε πιο έξυπνο. Η εφαρμογή συμπεριφέρεται πλέον διαφορετικά σε κάθε συσκευή και με την πάροδο του χρόνου εντοπίζει τα μοτίβα τοποθεσίας για να βελτιώσει αυτόματα την αξία των πληροφοριών που παρέχει στους χρήστες της.
Σίγουρα μπορούν να προστεθούν πολύ περισσότερα δεδομένα λογικής και αισθητήρα για να αυξηθεί η ακρίβεια και η χρησιμότητα της εφαρμογής μας με γνώμονα το περιβάλλον. ΕΝΑ έξυπνος προγραμματιστής για κινητά θα μπορούσαν, για παράδειγμα, να χρησιμοποιήσουν δεδομένα κοινωνικού δικτύου, δεδομένα καιρού, δεδομένα συναλλαγών τερματικού POS και ούτω καθεξής για να προσθέσουν ακόμη περισσότερη συνειδητοποίηση περιβάλλοντος στην εφαρμογή μας και Κάντε το πιο βιώσιμο και εμπορεύσιμο .
Αρχές ορισμού σχεδιαστικού ρυθμού
Με τον υπολογισμό με γνώμονα το περιβάλλον, οι δυνατότητες είναι ατελείωτες. Όλο και περισσότερες έξυπνες εφαρμογές θα συνεχίσουν να εμφανίζονται σε καταστήματα εφαρμογών που χρησιμοποιούν αυτήν την ισχυρή τεχνολογία για να κάνουν τη ζωή μας πιο απλή.