def poll(self): now = time.time() self.flushOldReads(now) try: for tag in self.reader.getTags(): # blocks for a bit uid = tag.uid() log.debug('detected tag uid=%r', uid) cardIdUri = uidUri(uid) is_new = cardIdUri not in self.log self.log[cardIdUri] = now if is_new: STATS.newCardReads += 1 tag.connect() try: textLit = Literal(tag.readBlock(1).rstrip('\x00')) if self.overwrite_any_tag and not looksLikeBigasterisk( textLit): log.info("block 1 was %r; rewriting it", textLit) tag.writeBlock(1, randomBody()) textLit = Literal(tag.readBlock(1).rstrip('\x00')) finally: # This might not be appropriate to call after # readBlock fails. I am getting double # exceptions. tag.disconnect() self.startCardRead(cardIdUri, textLit) except AuthFailedError as e: log.error(e) except (NfcError, OSError) as e: traceback.print_exc() log.error(e) reactor.stop()
def poll(self): now = time.time() self.flushOldReads(now) try: for tag in self.reader.getTags(): # blocks for a bit uid = tag.uid() log.debug('detected tag uid=%r', uid) cardIdUri = uidUri(uid) is_new = cardIdUri not in self.log self.log[cardIdUri] = now if is_new: STATS.newCardReads += 1 tag.connect() try: textLit = Literal(tag.readBlock(1).rstrip('\x00')) if self.overwrite_any_tag and not looksLikeBigasterisk(textLit): log.info("block 1 was %r; rewriting it", textLit) tag.writeBlock(1, randomBody()) textLit = Literal(tag.readBlock(1).rstrip('\x00')) finally: # This might not be appropriate to call after # readBlock fails. I am getting double # exceptions. tag.disconnect() self.startCardRead(cardIdUri, textLit) except AuthFailedError as e: log.error(e) except (NfcError, OSError) as e: traceback.print_exc() log.error(e) reactor.stop()
def setSourceState(self, source, state): """ add a patch to the COLLECTOR graph about the state of this source. state=None to remove the source. """ oldState = self._sourceState.get(source, None) if state == oldState: return log.info('source state %s -> %s', source, state) if oldState is None: self._sourceState[source] = state self.applyPatch(COLLECTOR, Patch(addQuads=[ (COLLECTOR, ROOM['source'], source, COLLECTOR), (source, ROOM['state'], state, COLLECTOR), ])) elif state is None: del self._sourceState[source] self.applyPatch(COLLECTOR, Patch(delQuads=[ (COLLECTOR, ROOM['source'], source, COLLECTOR), (source, ROOM['state'], oldState, COLLECTOR), ])) else: self._sourceState[source] = state self.applyPatch(COLLECTOR, Patch( addQuads=[ (source, ROOM['state'], state, COLLECTOR), ], delQuads=[ (source, ROOM['state'], oldState, COLLECTOR), ]))
def getCompleteTemps(self, maxTime=120): ret = {} tries = 0 now = time.time() giveUp = now + maxTime self.requestTemps() sensors = set(self.allSensors()) while now < giveUp: tries += 1 ret.update(self.getTemps(sensors - set(ret.keys()))) if len(ret) >= self.expectedSensors: log.info("after %s tries, temps=%s" % (tries, ret)) break log.debug("..only have %s measurements; still trying for %d secs" % (len(ret), giveUp - now)) self.initOnewire() self.requestTemps() yield deferLater(reactor, .5, lambda: None) now = time.time() else: log.info("giving up after %s secs, only got %s measurements" % (maxTime, len(ret))) returnValue(dict([(s.address,val) for s, val in ret.items()]))
def startCardRead(self, cardUri, text): self.masterGraph.patch(Patch(addQuads=[ (sensor, ROOM['reading'], cardUri, ctx), (cardUri, ROOM['cardText'], text, ctx)], delQuads=[])) log.info('%s :cardText %s .', cardUri.n3(), text.n3()) self._sendOneshot([(sensor, ROOM['startReading'], cardUri), (cardUri, ROOM['cardText'], text)])
def startCardRead(self, cardUri, text): self.masterGraph.patch( Patch(addQuads=[(sensor, ROOM['reading'], cardUri, ctx), (cardUri, ROOM['cardText'], text, ctx)], delQuads=[])) log.info('%s :cardText %s .', cardUri.n3(), text.n3()) self._sendOneshot([(sensor, ROOM['startReading'], cardUri), (cardUri, ROOM['cardText'], text)])
def reset(self): log.info("reopening serial port") for port in ['/dev/serial/by-id/usb-0557_2008-if00-port0']: try: self.comm = Comm(port) break except SerialException, e: pass
def supervisorRestart(cmds, supervisor="http://localhost:9001"): serv = xmlrpclib.ServerProxy(supervisor) for c in cmds: log.info("restarting %s", c) try: serv.supervisor.stopProcessGroup(c) except xmlrpclib.ResponseError, e: log.warn("supervisor.stopProcessGroup error %r, ignoring", e) serv.supervisor.startProcess(c)
def doEntranceMusic(self, action): import restkit, jsonlib dt = self.deltaSinceLastArrive(action['name']) log.debug("dt=%s", dt) if dt > datetime.timedelta(hours=1): hub = restkit.Resource( # PSHB not working yet; "http://bang:9030/" "http://slash:9049/" ) action = action.copy() del action['created'] del action['_id'] log.info("post to %s", hub) hub.post("visitorNet", payload=jsonlib.dumps(action))
def removeSseHandler(self, handler): log.info('removeSseHandler %r', handler) self.statements.discardHandler(handler) for source in self._sourcesForHandler(handler): for otherHandler in self.handlers: if (otherHandler != handler and source in self._sourcesForHandler(otherHandler)): break else: self._stopClient(source) self.handlers.remove(handler)
def addSseHandler(self, handler): log.info('addSseHandler %r %r', handler, handler.streamId) # fail early if id doesn't match sources = self._sourcesForHandler(handler) self.handlers.add(handler) for source in sources: if source not in self.clients and source != COLLECTOR: self._localStatements.setSourceState(source, ROOM['connect']) self.clients[source] = ReconnectingPatchSource( source, listener=lambda p, fullGraph, source=source: self._onPatch( source, p, fullGraph)) self._sendUpdatePatch(handler)
def post(self): code = json.loads(self.request.body) if not code['code'].startswith("music "): raise ValueError("this service only knows music barcodes, not %r" % code) rows = list(mpdPaths.find({'_id' : int(code['code'].split()[1])})) if not rows: raise ValueError("code %r unknown" % code) song = rows[0]['mpdPath'] post = "http://star:9009/addAndPlay/%s" % urllib.quote(song, safe='') result = (yield cyclone.httpclient.fetch( method="POST", url=post)).body log.info("post result: %r", result) self.write(result)
def poll(self): connectedField = 'connected' now = int(time.time()) # UVA mode: addDhcpData = lambda *args: None try: newAddrs = yield self.wifi.getPresentMacAddrs() addDhcpData(newAddrs) newWithSignal = [a for a in newAddrs if a.get('connected')] actions = self.computeActions(newWithSignal) points = [] for action in actions: log.info("action: %s", action) action['created'] = datetime.datetime.now(tz.gettz('UTC')) mongo.save(action) points.append( self.influxPoint(now, action['address'].lower(), 1 if action['action'] == 'arrive' else 0)) try: self.doEntranceMusic(action) except Exception, e: log.error("entrancemusic error: %r", e) if now // 3600 > self.lastPollTime // 3600: log.info('hourly writes') for addr in newWithSignal: points.append(self.influxPoint(now, addr['mac'].lower(), 1)) influx.write_points(points, time_precision='s') self.lastWithSignal = newWithSignal if actions: # this doesn't currently include signal strength changes fetch(reasoning + "immediateUpdate", method='PUT', timeout=2, headers={'user-agent': ['tomatoWifi']}).addErrback(log.warn) self.lastAddrs = newAddrs self.lastPollTime = now
def post(self): # there should be per-pin debounce settings so we don't log # all the noise of a transition change msg = simplejson.loads(self.request.body) msg['t'] = datetime.datetime.now(tzutc()) msg['name'] = {9: 'downstairsDoorOpen', 10: 'downstairsDoorMotion', }[msg['pin']] log.info("pinchange post %r", msg) self.settings.mongo.insert(msg) history = self.settings.history if msg['pin'] == 10: history['motionHistory'] = (history.get('motionHistory', []) + [(msg['t'], msg['level'])])[-50:] if msg['level'] == 1: if history.get('prevMotion', 0) == 0: history['motionStart'] = msg['t'] history['prevMotion'] = msg['level']
def post(self): agent = URIRef(self.request.headers['x-foaf-agent']) body = json.loads(self.request.body) _, uid = reader.read_id() log.info('current card id: %r %r', _, uid) if uid is None: self.set_status(404, "no card present") # maybe retry a few more times since the card might be nearby return text = randomBody() log.info('%s rewrites %s to %s, to be owned by %s', agent, uid, text, body['user']) #reader.KEY = private.rfid_key reader.write(uid, text) log.info('done with write')
def graphChanged(self, inputGraph, oneShot=False, oneShotGraph=None): """ If we're getting called for a oneShot event, the oneShotGraph statements are already in inputGraph.getGraph(). """ log.info("----------------------") log.info("graphChanged (oneShot=%s):", oneShot) t1 = time.time() oldInferred = self.inferred try: ruleStatStmts, ruleParseSec = self.updateRules() self.inferred, inferSec = self._makeInferred(inputGraph.getGraph()) self.inferred += unquoteOutputStatements(self.inferred) self.inferred += ruleStatStmts if oneShot: # It's possible a oneShotGraph statement didn't # trigger a rule to do something, but was itself the # output statement. Probably we could just mix in the # whole inputGraph here and not special-case the # oneShotGraph. self.inferred += oneShotGraph t3 = time.time() self.actions.putResults(self.inputGraph.getGraph(), self.inferred) putResultsTime = time.time() - t3 finally: if oneShot: self.inferred = oldInferred log.info("graphChanged took %.1f ms (rule parse %.1f ms, infer %.1f ms, putResults %.1f ms)" % ((time.time() - t1) * 1000, ruleParseSec * 1000, inferSec * 1000, putResultsTime * 1000))
def post(self): msg = simplejson.loads(self.request.body) msg['t'] = datetime.datetime.now(tzutc()) log.info(msg) self.settings.mongo.insert(msg)
d.addErrback(err) if __name__ == '__main__': arg = docopt(""" Usage: rfid.py [options] -v Verbose --overwrite_any_tag Rewrite any unknown tag with a new random body -n Fake reader """) log.setLevel(logging.INFO) if arg['-v']: enableTwistedLog() log.setLevel(logging.DEBUG) log.info(f'cyclone {cyclone.__version__}') defer.setDebugging(True) masterGraph = PatchableGraph() reader = NfcDevice() if not arg['-n'] else FakeNfc() ie = InfluxExporter(Graph()) ie.exportStats( STATS, [ 'root.cardReadPoll.count', 'root.cardReadPoll.95percentile', 'root.newCardReads', ], period_secs=10, retain_days=7,
def connectionMade(self, *args, **kwargs): log.info("websocket opened") liveClients.add(self) def connectionLost(self, reason): log.info("websocket closed") liveClients.remove(self) def messageReceived(self, message): log.info("got message %s" % message) self.sendMessage(message) if __name__ == '__main__': from twisted.python import log as twlog #twlog.startLogging(sys.stdout) task.LoopingCall(pushThermostat).start(1) port = 9102 reactor.listenTCP(port, cyclone.web.Application(handlers=[ (r'/content', Content), (r'/content/map', ContentMap), (r'/live', Live), (r'/refreshTemperature', RefreshTemperature), (r'/(.*)', cyclone.web.StaticFileHandler, {"path" : ".", # security hole- serves this dir too "default_filename" : "index.html"}), ])) log.info("serving on %s" % port) reactor.run()
self.reset() LoopingCall(self.poll).start(interval=10) def reset(self): log.info("reopening serial port") for port in ['/dev/serial/by-id/usb-0557_2008-if00-port0']: try: self.comm = Comm(port) break except SerialException, e: pass else: # among other things, a serial exception for too many open files log.error(e) os.abort() log.info("version: %r", self.comm.request(device=1, number=0, command="getVersion")) def poll(self): try: watts = self.comm.requestNumeric(device=1, number=0, command="getPowerNow") self.carbon.send('system.house.solar.power_w', watts) except Sleeping: log.debug("sleeping") except ValueError: log.error(traceback.format_exc()) self.reset() except Exception: traceback.print_exc() os.abort() self.lastPollTime = time.time()
self.set_header("Content-Type", "application/json") self.write(json.dumps({'sensors': out})) class Save(PrettyErrorHandler, cyclone.web.RequestHandler): def post(self): lines = open('saved_points').readlines() lineNum = len(lines) + 1 row = poller.lastValue('00:ea:23:21:e0:a4') with open('saved_points', 'a') as out: out.write('%s %r\n' % (lineNum, row)) self.write('wrote line %s: %r' % (lineNum, row)) db = Db() poller = Poller() locatorEstimatesPoller = LocatorEstimatesPoller() reactor.listenTCP( 9113, cyclone.web.Application([ (r"/(|.*\.(?:js|html|json))$", cyclone.web.StaticFileHandler, { "path": ".", "default_filename": "beaconmap.html"}), (r"/devices", Devices), (r'/points', Points), (r'/sensors', Sensors), (r'/save', Save), (r'/positionEstimates', PositionEstimates), ])) log.info('serving on 9113') reactor.run()
def done(resp): path = '/tmp/sound_%s' % next(soundCount) with open(path, 'w') as out: out.write(resp.body) log.info('write %s bytes to %s', len(resp.body), path) self.buffers[uri] = pygame.mixer.Sound(path)
def startCycle(self): log.info("heater on") yield http('PUT', self.heaterPin, body='1') self._lastOn = time.time()
def step(self): roomF = yield self.getRoomTempF() requestedF = self.getRequest() active = yield self.active() # bug here where, if something else turned off the heater, we # don't count minsOff right minsOff = self.minutesSinceOff() minsOn = self.minutesSinceOn() log.info("roomF=%(roomF)s requestedF=%(requestedF)s active=%(active)s " "minsOn=%(minsOn)s minsOff=%(minsOff)s" % vars()) if not active: if roomF < requestedF - 1: if minsOff > 5: log.info("start heater") self.startCycle() else: log.info("wait to start") else: pass else: if roomF > requestedF + 1: log.info("stop heater") self.stopCycle() elif minsOn > 50: log.info("heater on too long- stopping") self.stopCycle() else: log.info("ok to keep warming")
def stopCycle(self): log.info("heater off") # need to make it be an output! yield http('PUT', self.heaterPin, body='0') self._lastOff = time.time()
def messageReceived(self, message): log.info("got message %s" % message) self.sendMessage(message)
def connectionLost(self, reason): log.info("websocket closed") liveClients.remove(self)
def connectionMade(self, *args, **kwargs): log.info("websocket opened") liveClients.add(self)
def err(e): log.info('oneshot post to %r failed: %s', url, e.getErrorMessage())
if __name__ == '__main__': arg = docopt(""" Usage: rfid.py [options] -v Verbose --overwrite_any_tag Rewrite any unknown tag with a new random body -n Fake reader """) log.setLevel(logging.INFO) if arg['-v']: enableTwistedLog() log.setLevel(logging.DEBUG) log.info(f'cyclone {cyclone.__version__}') defer.setDebugging(True) masterGraph = PatchableGraph() reader = NfcDevice() if not arg['-n'] else FakeNfc() ie=InfluxExporter(Graph()) ie.exportStats(STATS, ['root.cardReadPoll.count', 'root.cardReadPoll.95percentile', 'root.newCardReads', ], period_secs=10, retain_days=7, ) loop = ReadLoop(reader, masterGraph, overwrite_any_tag=arg['--overwrite_any_tag'])
self.totalDialMovement += what['dial'] sendOneShotGraph(g) def updateLoop(self, *prevResults): self.lastUpdateTime = time.time() threads.deferToThread(self.p.read_next).addCallback(self.updateLoop) if __name__ == '__main__': from twisted.python import log as twlog twlog.startLogging(sys.stdout) port = 9103 poller = Poller() reactor.listenTCP( port, cyclone.web.Application( handlers=[ (r'/()', Index, { "path": ".", "default_filename": "index.html" }), (r'/graph', GraphResource), # serves this source code too (r'/(.*)', cyclone.web.StaticFileHandler, { "path": "." }) ], poller=poller)) log.info("serving on %s" % port) reactor.run()
def step(self): now = time.time() try: if hostname == 'bang': if (not haveDevice(Id.bedroomCam) or not haveDevice(Id.bedroomArduino)): if haveDevice(Id.bedroomHub3): yield resetDevice(hubDevice(Id.bedroomHub3)) else: if haveDevice(Id.bedroomHub2): yield resetDevice(hubDevice(Id.bedroomHub2)) else: if haveDevice(Id.bedroomHub1): yield resetDevice(hubDevice(Id.bedroomHub1)) else: if haveDevice(Id.bedroomHub0): yield resetDevice(hubDevice(Id.bedroomHub0)) else: raise ValueError( "don't even have the first hub") resetModules(['gspca_zc3xx']) #supervisorRestart(['webcam_9053']) else: log.debug("usb devices look ok") elif hostname == 'slash': haveFrontHub0 = haveDevice(Id.frontDoorHub0) haveFrontHub1 = haveDevice(Id.frontDoorHub1) haveFrontHub2 = haveDevice(Id.frontDoorHub2) haveFrontHub3 = haveDevice(Id.frontDoorHub3) haveGarageHub0 = haveDevice(Id.garageHub0) haveGarageHub1 = haveDevice(Id.garageHub1) haveFrontDoorCam = haveDevice(Id.frontDoorCam) haveV4lDevice = os.path.exists( "/dev/v4l/by-id/usb-Vimicro_Corp._PC_Camera-video-index0") haveFrontArduinoServe = (yield getOk('http://slash:9080/')) haveFrontWebcamImage = (yield getOk( "http://slash:9023/frontDoor", timeout=10)) log.info(str(vars())) if not haveDevice(Id.ftdi): if haveFrontHub3: yield resetDevice(hubDevice(Id.frontDoorHub3)) else: if haveFrontHub2: yield resetDevice(hubDevice(Id.frontDoorHub2)) else: if haveFrontHub1: yield resetDevice(hubDevice(Id.frontDoorHub1)) else: if haveFrontHub0: yield resetDevice(hubDevice(Id.frontDoorHub0)) else: raise ValueError("don't have the first hub") else: log.debug("front door chain looks ok") if not haveDevice(Id.garagePowerSerial): if haveGarageHub1: yield resetDevice(hubDevice(Id.garageHub1)) else: if haveGarageHub0: yield resetDevice(hubDevice(Id.garageHub0)) else: raise ValueError("don't have the first hub") else: log.debug("garage chain looks ok") if not haveDevice(Id.garageArduino): if haveGarageHub1: yield resetDevice(hubDevice(Id.garageHub1)) else: raise ValueError("don't even have the first hub") resetModules(['gspca_zc3xx']) supervisorRestart(['frontDoorArduino_9080']) else: if not haveFrontArduinoServe: yield resetDevice(hubDevice(Id.frontDoorHub3)) supervisorRestart(['frontDoorArduino_9080']) time.sleep(10) else: log.debug("frontDoorArduino looks ok") if not haveFrontWebcamImage: supervisorRestart(['webcam_frontDoor_9023']) else: log.debug("front webcam looks ok") elif hostname == 'dash': if not os.path.exists("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900gbcG-if00-port0"): yield resetDevice(hubDevice("/dev/bus/usb/003/001")) else: raise NotImplementedError log.debug(" -- finished") self.lastPollTime = now except Exception, e: print "poll error", e traceback.print_exc()
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)
def resetModules(modules): log.info("reloading modules: %s", modules) for m in modules: subprocess.call(['modprobe', '-r', m]) for m in modules: subprocess.check_call(['modprobe', m])
class Save(PrettyErrorHandler, cyclone.web.RequestHandler): def post(self): lines = open('saved_points').readlines() lineNum = len(lines) + 1 row = poller.lastValue('00:ea:23:21:e0:a4') with open('saved_points', 'a') as out: out.write('%s %r\n' % (lineNum, row)) self.write('wrote line %s: %r' % (lineNum, row)) db = Db() poller = Poller() locatorEstimatesPoller = LocatorEstimatesPoller() reactor.listenTCP( 9113, cyclone.web.Application([ (r"/(|.*\.(?:js|html|json))$", cyclone.web.StaticFileHandler, { "path": ".", "default_filename": "beaconmap.html" }), (r"/devices", Devices), (r'/points', Points), (r'/sensors', Sensors), (r'/save', Save), (r'/positionEstimates', PositionEstimates), ])) log.info('serving on 9113') reactor.run()