changeset 1290:4fa09ec19c86

rm old bluetooth tracking service. 'beacon' is the new one. Ignore-this: d4c47f2b8c0b44766725bc2365e207f0 darcs-hash:5744332ed7cfcd62adb2d4d6bb78bb255bf6f0e3
author drewp <drewp@bigasterisk.com>
date Sun, 21 Apr 2019 01:24:50 -0700
parents add5df9cd476
children c1b0813372cc
files service/bluetooth/bluetoothService.py service/bluetooth/index.xhtml service/bluetooth/phones.n3 service/bluetooth/pretty.js
diffstat 4 files changed, 0 insertions(+), 380 deletions(-) [+]
line wrap: on
line diff
--- a/service/bluetooth/bluetoothService.py	Sun Apr 21 01:24:19 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#!/usr/bin/python
-
-"""
-watch for bluetooth devices
-
-this discoverer finds me if my treo has its screen on only, so I
-have to wake up my own treo for a few seconds. 
-
-I can use 'hcitool cc <addr> && hcitool rssi <addr>' to wake it up and
-get its signal strength, but that pattern crashes my treo easily. I
-still don't have an access that wakes up the treo and then doesn't
-crash it. Maybe I could pretend to be a headset or something.
-
-depends on ubuntu package: python-bluez
-
-"""
-from __future__ import absolute_import
-import logging, time, datetime, restkit, jsonlib, sys, socket
-import cyclone.web, pystache
-from dateutil.tz import tzutc, tzlocal
-from bluetooth import discover_devices, lookup_name
-from twisted.internet import reactor, task
-from twisted.internet.threads import deferToThread
-from rdflib.Graph import Graph
-from rdflib import Literal, Namespace, RDFS, URIRef
-from pymongo import Connection
-from dateutil import tz
-
-sys.path.append("/my/proj/homeauto/lib")
-from cycloneerr import PrettyErrorHandler
-from logsetup import log
-
-mongo = Connection('bang', 27017, tz_aware=True)['visitor']['visitor']
-
-ROOM = Namespace("http://projects.bigasterisk.com/room/")
-
-# the mongodb serves as a much bigger cache, but I am expecting that
-# 1) i won't fill memory with too many names; 2) this process will see
-# each new device before it leaves, so I'll have the leaving name in
-# my cache
-nameCache = {} # addr : name
-
-def lookupPastName(addr):
-    row = mongo.find_one({"address" : addr,
-                          'name' : {'$exists' : True}},
-                         sort=[("created",-1)])
-    if row is None:
-        return None
-    return row['name']
-
-def getNearbyDevices():
-    addrs = discover_devices()
-
-    for a in addrs:
-        if a not in nameCache:
-            n = lookup_name(a) or lookupPastName(a)
-            if n is not None:
-                nameCache[a] = n
-                
-    log.debug("discover found %r", addrs)
-    return addrs
-
-hub = restkit.Resource(
-    # PSHB not working yet; "http://bang:9030/"
-    "http://slash:9049/"
-    )
-
-def mongoInsert(msg):
-    try:
-        js = jsonlib.dumps(msg)
-    except UnicodeDecodeError:
-        pass
-    else:
-        if (msg.get('name', '') and
-            msg['name'] not in ['THINKPAD_T43'] and
-            msg['action'] == 'arrive'):
-            hub.post("visitorNet", payload=js) # sans datetime
-    msg['created'] = datetime.datetime.now(tz.gettz('UTC'))
-    mongo.insert(msg, safe=True)
-
-def deviceUri(addr):
-    return URIRef("http://bigasterisk.com/bluetooth/%s" % addr)
-
-class Poller(object):
-    def __init__(self):
-        self.lastAddrs = set() # addresses
-        self.currentGraph = Graph()
-        self.lastPollTime = 0
-
-    def poll(self):
-        log.debug("get devices")
-        devs = deferToThread(getNearbyDevices)
-
-        devs.addCallback(self.compare)
-        devs.addErrback(log.error)
-        return devs
-
-    def compare(self, addrs):
-        self.lastPollTime = time.time()
-
-        newGraph = Graph()
-        addrs = set(addrs)
-        for addr in addrs.difference(self.lastAddrs):
-            self.recordAction('arrive', addr)
-        for addr in self.lastAddrs.difference(addrs):
-            self.recordAction('leave', addr)
-        for addr in addrs:
-            uri = deviceUri(addr)
-            newGraph.add((ROOM['bluetooth'], ROOM['senses'], uri))
-            if addr in nameCache:
-                newGraph.add((uri, RDFS.label, Literal(nameCache[addr])))
-        self.lastAddrs = addrs
-        self.currentGraph = newGraph
-
-    def recordAction(self, action, addr):
-        doc = {"sensor" : "bluetooth",
-               "address" : addr,
-               "action" : action}
-        if addr in nameCache:
-            doc["name"] = nameCache[addr]
-        log.info("action: %s", doc)
-        mongoInsert(doc)
-
-class Index(PrettyErrorHandler, cyclone.web.RequestHandler):
-    def get(self):
-        age = time.time() - self.settings.poller.lastPollTime
-        if age > self.settings.config['period'] + 30:
-            raise ValueError("poll data is stale. age=%s" % age)
-
-        self.set_header("Content-Type", "application/xhtml+xml")
-        self.write(pystache.render(
-            open("index.xhtml").read(),
-            dict(host=socket.gethostname(),
-                 )))
-
-class Recent(PrettyErrorHandler, cyclone.web.RequestHandler):
-    def get(self):
-        name = {}  # addr : name
-        events = []
-        hours = float(self.get_argument("hours", default="3"))
-        t1 = datetime.datetime.now(tzutc()) - datetime.timedelta(seconds=60*60*hours)
-        for row in mongo.find({"sensor":"bluetooth",
-                               "created":{"$gt":t1}}, sort=[("created", 1)]):
-            if 'name' in row:
-                name[row['address']] = row['name']
-            row['t'] = int(row['created'].astimezone(tzlocal()).strftime("%s"))
-            del row['created']
-            del row['_id']
-            events.append(row)
-
-        for r in events:
-            r['name'] = name.get(r['address'], r['address'])
-        self.set_header("Content-Type", "application/json")
-        self.write(jsonlib.dumps({"events" : events}))
-           
-
-class Static(PrettyErrorHandler, cyclone.web.RequestHandler):
-    def get(self, fn):
-        self.write(open(fn).read())
-
-if __name__ == '__main__':
-    config = {
-        "period" : 60,
-        }
-    log.setLevel(logging.INFO)
-    poller = Poller()
-    reactor.listenTCP(9077, cyclone.web.Application([
-        (r'/', Index),
-        (r'/recent', Recent),
-        (r'/(underscore-min.js|pretty.js)', Static),
-        # graph, json, table, ...
-        ], poller=poller, config=config))
-    task.LoopingCall(poller.poll).start(config['period'])
-    reactor.run()
--- a/service/bluetooth/index.xhtml	Sun Apr 21 01:24:19 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title></title>
-    <style type="text/css" media="all">
-      /* <![CDATA[ */
-      body {
-	  font-family: sans-serif;
-	  font-size: 12px;
-      }
-      .stripChart {
-	  background: none repeat scroll 0 0 #EAEAEA;
-	  border-bottom: 1px solid #b7b7b7;
-	  display: inline-block;
-	  height: 22px;
-	  margin: 0;
-	  padding: 0;
-	  white-space: nowrap;
-      }
-      .chartArea {
-	  width: 300px;
-	  height: 20px;
-	  border: 1px solid gray;
-	  display: inline-block;
-	  position: relative;
-	  background: white;
-      }
-      .name {
-	  display: inline-block;
-	  width: 16em;
-      } 
-
-      .chartArea > span {
-	  position: absolute;
-	  height: 20px;
-	  background: #d3e1ed;
-	  background: -moz-linear-gradient(left, #d3e1ed 0%, #86aecc 100%);
-	  background: -webkit-gradient(linear, left top, right top, color-stop(0%,#d3e1ed), color-stop(100%,#86aecc));
-	  background: -webkit-linear-gradient(left, #d3e1ed 0%,#86aecc 100%);
-	  background: -o-linear-gradient(left, #d3e1ed 0%,#86aecc 100%);
-	  background: linear-gradient(left, #d3e1ed 0%,#86aecc 100%);
-      }
-
-      .stripChart > .timeLeft, .stripChart > .timeRight { 
-	  font-size: 10px;
-	  vertical-align: super;
-	  padding: 0 4px;
-      }
-     
-      /* ]]> */
-    </style>
-
-  </head>
-  <body>
-    <h1>bluetooth watcher on {{host}}</h1>
-
-    <p>Recent activity</p>
-
-    <div id="activity"/>
-    <script type="text/javascript" src="//bigasterisk.com/lib/jquery-2.0.3.min.js"/>
-      <script type="text/javascript" src="//bigasterisk.com/lib/underscore-1.5.2.min.js"/>
-      <script type="text/javascript" src="pretty.js"/>
-
-    <script type="text/javascript">
-    // <![CDATA[
-    
-    function StripChart(parent) {
-        var strips = [[null, null]]; // [[starttime, endtime], ...]
-        this.addEvent = function (ev) {
-            // must pass events in order
-            if (ev.action == "arrive") {
-                if (_.isNull(_.last(strips)[1])) {
-		    if (_.isNull(_.last(strips)[0])) {
-			_.last(strips)[0] = ev.t;
-		    } else {
-			// two arrives in a row
-		    }
-                } else {
-                    strips.push([ev.t, null]);
-                }
-            }
-            if (ev.action == "leave") {
-                if (_.isNull(_.last(strips)[1])) {
-                    _.last(strips)[1] = ev.t;
-                } else {
-                    // two leaves in a row
-                }
-            }
-        };
-        function stripIsComplete(se) {
-            return !_.isNull(se[0]) && !_.isNull(se[1]); 
-        }
-	function displayTime(secs) {
-	    var iso = new Date(secs*1000).toJSON().replace(/\.\d+/,"");
-	    return prettyDate(iso);
-	}
-        this.draw = function () {
-	    var now = .001*new Date();
-            if (_.isNull(_.last(strips)[1])) {
-                _.last(strips)[1] = now;
-            }
-            var complete = _.select(strips, stripIsComplete);
-            if (_.isEmpty(complete)) {
-                return;
-            }
-            var t1 = _.first(complete)[0], t2 = now;
-            function xForTime(t) {
-                return 300 * (t - t1) / (t2 - t1)
-            }
-	    parent.append($("<span>").addClass("timeLeft").text(displayTime(t1)));
-	    var out = $("<span>").addClass("chartArea")
-	    parent.append(out);
-	    var lastX = 0;
-            $.each(complete, function (i, se) {
-                var x1 = xForTime(se[0]), x2 = xForTime(se[1]);
-		if (x1 < lastX) {
-		    // culls ok, but may leave gaps. I'd rather
-		    // something that joins the slivers intead of
-		    // skipping them
-		    return;
-		}
-		var w = Math.max(2, x2 - x1)
-                out.append($("<span>").css({left: x1, width: w}));
-		lastX = x1 + w;
-            });
-	    parent.append($("<span>").addClass("timeRight").text("now"));
-        };
-    }
-
-    $(function() { 
-        var addressRow = {}; // address : row
-        var chart = {} // address : StripChart
-
-        $.getJSON("recent", {hours:24*7}, function (data) {
-            
-            $.each(data.events, function (i, ev) {
-                if (!addressRow[ev.address]) {
-                    var row = $("<li>").append($("<span>").addClass("name").text(ev.name)).append($("<span>").addClass("stripChart"));
-                    $("#activity").append(row);
-                    addressRow[ev.address] = row;
-                    chart[ev.address] = new StripChart(row.find(".stripChart"));
-                }
-                chart[ev.address].addEvent(ev);
-            });
-            $.each(chart, function (k, c) {
-                c.draw();
-            });
-        });
-    });
-    // ]]>
-</script>
-
-
-  </body>
-</html>
--- a/service/bluetooth/phones.n3	Sun Apr 21 01:24:19 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-@prefix : <http://projects.bigasterisk.com/room/>.
-
-<http://bigasterisk.com/foaf.rdf#drewp> :carries :drewTreo .
-
-:drewTreo :bluetoothAddress "00:07:E0:5C:8A:DD" .
-
-:johnTreo :bluetoothAddress "00:07:E0:1E:F5:5C" .
-
-:kelsiTreo :bluetoothAddress "00:07:E0:BE:AD:B2" .
-
-# 00:1D:FE:37:89:D0 drew's pre
-
-#1199324300.71 2008-01-02 17:38:20,705 INFO  io.bluetooth:105: no matches for Jawbone (00:17:84:11:E5:D1)
--- a/service/bluetooth/pretty.js	Sun Apr 21 01:24:19 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * JavaScript Pretty Date
- * Copyright (c) 2008 John Resig (jquery.com)
- * Licensed under the MIT license.
- */
-
-// Takes an ISO time and returns a string representing how
-// long ago the date represents.
-function prettyDate(time){
-	var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
-		diff = (((new Date()).getTime() - date.getTime()) / 1000),
-		day_diff = Math.floor(diff / 86400);
-			
-	if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
-		return;
-			
-	return day_diff == 0 && (
-			diff < 60 && "just now" ||
-			diff < 120 && "1 minute ago" ||
-			diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
-			diff < 7200 && "1 hour ago" ||
-			diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
-		day_diff == 1 && "Yesterday" ||
-		day_diff < 7 && day_diff + " days ago" ||
-		day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
-}
-
-// If jQuery is included in the page, adds a jQuery plugin to handle it as well
-if ( typeof jQuery != "undefined" )
-	jQuery.fn.prettyDate = function(){
-		return this.each(function(){
-			var date = prettyDate(this.title);
-			if ( date )
-				jQuery(this).text( date );
-		});
-	};