def on_transition(mosq, userdata, msg): if msg.retain == 1: return print msg.payload base_topic, suffix = twosplit(msg.topic) try: data = json.loads(str(msg.payload)) except: return if '_type' not in data or data['_type'] != 'transition': print "-- not a transition payload" return if 't' not in data or data['t'] != 'b': print "-- not a 't:b' payload" return tst = data.get("tst", 0) tid = data.get("tid", "--") if data['event'] == 'enter' and 'desc' in data: # clear region entry when leaving region regionTopic = "%s/%s" % (mqttConf.get('regionprefix'), base_topic) payload = {'tid': tid, 'tst': tst, 'region': data['desc']} regionPayload = json.dumps(payload) mqttc.publish(regionTopic, regionPayload, qos=2, retain=False) elif data['event'] == 'leave': # clear closestBeacon entry when leaving region if base_topic in closestBeacons: del closestBeacons[base_topic]; # clear featured content when leaving region featured_topic = "%s/%s" % (base_topic, 'cmd') payload = {'_type': 'cmd', 'tst': tst, 'action': 'action'} featured_payload = json.dumps(payload) mqttc.publish(featured_topic, featured_payload, qos=2, retain=False) # clear beacon entry when leaving region beaconTopic = "%s/%s" % (mqttConf.get('beaconprefix'), base_topic) mqttc.publish(beaconTopic, None, qos=2, retain=False) # clear region entry when leaving region regionTopic = "%s/%s" % (mqttConf.get('regionprefix'), base_topic) mqttc.publish(regionTopic, None, qos=2, retain=False) # clear position entry when leaving region if base_topic in devices: del devices[base_topic]; positionTopic = "%s/%s" % (mqttConf.get('positionprefix'), base_topic) mqttc.publish(positionTopic, None, qos=2, retain=False)
def on_beacon(mosq, userdata, msg): if msg.retain == 1 or len(msg.payload) == 0: return data = None base_topic, suffix = twosplit(msg.topic) try: data = json.loads(str(msg.payload)) except: return if '_type' not in data or data['_type'] != 'beacon': print "-- not a beacon payload" return uuid = data.get("uuid", '12345678-ABCD-EF01-2345-000000000001') major = data.get("major", 0) minor = data.get("minor", 0) acc = data.get("acc", 99) * beaconfactor prox = data.get("prox", 9) rssi = data.get("rssi", -99) tst = data.get("tst", 0) tid = data.get("tid", 0) print tid, tst, uuid, major, minor, acc, prox, rssi if base_topic in closestBeacons: me = closestBeacons[base_topic] else: me = {'uuid': '', 'major': 0, 'minor': 0, 'rssi': -99, 'prox': 9, 'acc': 99} if prox < me['prox'] or (me['uuid'] == uuid and me['major'] == major and me['minor'] == minor): me['uuid'] = uuid me['major'] = major me['minor'] = minor me['acc'] = acc me['prox'] = prox me['rssi'] = rssi closestBeacons[base_topic] = me # build featured content message featured_topic = "%s/%s" % (base_topic, 'cmd') featured_content = "no matching beacon found\n%s:%d:%d" % (uuid, major, minor) url = None (beaconName, beacon) = find_beacon(uuid, major, minor) if beacon is not None: featured_content = "%s\n\n%s" % (beacon['desc'], beacon['URL']) url = beacon['URL'] payload = {'_type': 'cmd', 'tst': tst, 'action': 'action', 'content': featured_content, 'url': url} featured_payload = json.dumps(payload) mqttc.publish(featured_topic, featured_payload, qos=2, retain=False) # build beacon message beaconTopic = "%s/%s" % (mqttConf.get('beaconprefix'), base_topic) beaconJson = {'tid': tid, 'tst': tst, 'uuid': uuid, 'major': major, 'minor': minor} if beacon != None: beaconJson['name'] = beaconName beaconJson['room'] = beacon['room'] beaconPayload = json.dumps(beaconJson) print beaconName, beaconPayload mqttc.publish(beaconTopic, beaconPayload, qos=2, retain=False) # get device if base_topic in devices: device = devices[base_topic] else: device = {'tid': tid, 'visibleBeacons': {} } # get beacon beaconString = "%s:%d:%d" % (uuid, major, minor) visibleBeacons = device['visibleBeacons'] if beaconString in visibleBeacons: beacon = visibleBeacons[beaconString] else: beacon = {'uuid': uuid, 'major': major, 'minor': minor, 'measurements': []} # measurement keep up to 5 past measurements measurements = beacon['measurements'] measurement = {'prox': prox, 'rssi': rssi, 'acc': acc, 'tst': tst} measurements.append(measurement) if len(measurements) > 5: del(measurements[0]) # store beacon['measurements'] = measurements visibleBeacons[beaconString] = beacon device['visibleBeacons'] = visibleBeacons devices[base_topic] = device if len(visibleBeacons) < 3: return # get 3 closest visible beacons m3 = [] for visibleBeaconString in visibleBeacons: visibleBeacon = visibleBeacons[visibleBeaconString] # get average of last measurements measurements = visibleBeacon['measurements'] n = 0 total = 0 for measurement in measurements: n = n + 1 total = total + measurement['acc'] mid = total / n # select 3 closest beacons i = 0; while i < len(m3): if mid < m3[i]['r']: break i = i + 1 (beaconName, beacon) = find_beacon(visibleBeacon['uuid'], visibleBeacon['major'], visibleBeacon['minor']) if beacon is not None: m = {} m['x'] = beacon['x'] / mapfactor m['y'] = beacon['y'] / mapfactor m['r'] = mid m3.insert(i, m) print m3 positionTopic = "%s/%s" % (mqttConf.get('positionprefix'), base_topic) x = 0; y = 0; if len(m3) >= 3: (x, y) = trilateration( m3[0]['x'], m3[0]['y'], m3[0]['r'], m3[1]['x'], m3[1]['y'], m3[1]['r'], m3[2]['x'], m3[2]['y'], m3[2]['r'] ) if numpy.isnan(x) or numpy.isnan(y): x = 0; y = 0; if x != 0 or y != 0: positionDict = {'tid': tid, 'tst': tst, 'x': x * mapfactor, 'y': y * mapfactor} positionPayload = json.dumps(positionDict) mqttc.publish(positionTopic, positionPayload, qos=2, retain=False) return