def setSourceState(self, source: SourceUri, state: URIRef): """ 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 _onStatement(self, stmt): log.info(f'incoming statement: {stmt}') ignored = True for dev, attrs in devs.items(): if stmt[0] == ROOM['frontWindow']: ignored = ignored and self._publishFrontScreenText(stmt) if stmt[0:2] == (dev, ROOM['brightness']): log.info(f'brightness request: {stmt}') brightness = stmt[2].toPython() if attrs.get('values', '') == 'binary': self._publishOnOff(attrs, brightness) else: self._publishRgbw(attrs, brightness) ignored = False if stmt[0:2] == (dev, ROOM['inputSelector']): self._publish(topic=attrs['root'], message='input_' + str(stmt[2].toPython())) ignored = False if stmt[0:2] == (dev, ROOM['volumeChange']): delta = int(stmt[2].toPython()) which = 'up' if delta > 0 else 'down' self._publish(topic=f'theater_blaster/ir_out/volume_{which}', message=json.dumps({'timed': abs(delta)})) ignored = False if ignored: log.warn("ignoring %s", stmt)
def post(self): body = json.loads(self.request.body) log.info('POST bluetoothButton %r', body) if body['addr'] == 'zz:zz:zz:zz:zz:zz' and body['key'] == 'top': log.info('unlock for %r', body['addr']) self.settings.mqtt.publish( espName + b"/switch/strike/command", b'ON')
def post(self): body = json.loads(self.request.body) log.info('POST bluetoothButton %r', body) if body['addr'] == 'zz:zz:zz:zz:zz:zz' and body['key'] == 'top': log.info('unlock for %r', body['addr']) self.settings.mqtt.publish( espName + b"/switch/strike/command", b'ON')
def _getSound(self, uri): resp = yield treq.get(uri.encode('utf8')) body = yield treq.content(resp) path = '/tmp/sound_%s' % hash(uri) with open(path, 'wb') as out: out.write(body) log.info('write %s bytes to %s', len(body), path) self.buffers[uri] = path print('donesave')
def _onStatement(self, stmt): log.info(f'incoming statement: {stmt}') ignored = True for dev, attrs in devs.items(): if stmt[0] == ROOM['frontWindow']: ignored = ignored and self._publishFrontScreenText(stmt) if stmt[0:2] == (dev, ROOM['brightness']): log.info(f'brightness request: {stmt}') brightness = stmt[2].toPython() if attrs.get('values', '') == 'binary': self._publishOnOff(attrs, brightness) else: self._publishRgbw(attrs, brightness) ignored = False if stmt[0:2] == (dev, ROOM['inputSelector']): choice = stmt[2].toPython().decode('utf8') self._publish(topic=attrs['root'], message=f'input_{choice}') ignored = False if stmt[0:2] == (dev, ROOM['volumeChange']): delta = int(stmt[2].toPython()) which = 'up' if delta > 0 else 'down' self._publish(topic=f'theater_blaster/ir_out/volume_{which}', message=json.dumps({'timed': abs(delta)})) ignored = False if stmt[0:2] == (dev, ROOM['color']): h = stmt[2].toPython() msg = {} if h.endswith(b'K'): # accept "0.7*2200K" (brightness 0.7) # see https://www.zigbee2mqtt.io/information/mqtt_topics_and_message_structure.html#zigbee2mqttfriendly_nameset bright, kelvin = map(float, h[:-1].split(b'*')) msg['state'] = 'ON' msg["color_temp"] = round(1000000 / kelvin, 2) msg['brightness'] = int(bright * 255) # 1..20 look about the same else: r, g, b = int(h[1:3], 16), int(h[3:5], 16), int(h[5:7], 16) msg = { 'state': 'ON' if r or g or b else 'OFF', 'color': { 'r': r, 'g': g, 'b': b }, } if attrs.get('hasWhite', False): msg['white_value'] = max(r, g, b) msg.update(attrs.get('defaults', {})) self._publish(topic=attrs['root'], message=json.dumps(msg)) ignored = False if ignored: log.warn("ignoring %s", stmt)
def _onStatement(self, user, stmt): log.info('put statement %r', stmt) if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): if stmt[2] == ROOM['unlocked']: log.info('unlock for %r', user) self.settings.autoLock.onUnlockedStmt() if stmt[2] == ROOM['locked']: self.settings.autoLock.onLockedStmt() self.settings.mqtt.publish(espName + b"/switch/strike/command", mqttMessageFromState(stmt[2])) return log.warn("ignoring %s", stmt)
def _onStatement(self, user, stmt): log.info('put statement %r', stmt) if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): if stmt[2] == ROOM['unlocked']: log.info('unlock for %r', user) self.settings.autoLock.onUnlockedStmt() if stmt[2] == ROOM['locked']: self.settings.autoLock.onLockedStmt() self.settings.mqtt.publish(espName + b"/switch/strike/command", mqttMessageFromState(stmt[2])) return log.warn("ignoring %s", stmt)
def removeSseHandler(self, handler: PatchSink): 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)): # still in use break else: self._stopClient(source) self.handlers.remove(handler)
def onMsg(self, toBot: Bot, fromUser: URIRef, msg: str): log.info(r'onMsg {vars()}') try: if msg == 'chattest': yield self.chat.sendMsg(toBot, fromUser, 'not saving %s test' % toBot.name) return uri = yield toBot.save(userUri=fromUser, msg=msg) except Exception as e: yield self.chat.sendMsg(toBot, fromUser, r'failed to save: {e:r}') raise yield self.chat.sendMsg(toBot, fromUser, 'saved %s' % uri)
def addSseHandler(self, handler: PatchSink): 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: log.debug('connect to patch source %s', source) self._localStatements.setSourceState(source, ROOM['connect']) self.clients[source] = ReconnectingPatchSource( source, listener=lambda p, fullGraph, source=source: self._onPatch( source, p, fullGraph), reconnectSecs=10) log.debug('bring new client up to date') self._sendUpdatePatch(handler)
def main(): arg = docopt(""" Usage: report.py [options] -v Verbose """) verboseLogging(arg['-v']) log.info('startup') masterGraph = PatchableGraph() eventsInGraph: Set[URIRef] = set() coll = MongoClient( 'mongodb', tz_aware=True).get_database('timebank').get_collection('webproxy') class Application(cyclone.web.Application): def __init__(self): handlers = [ (r"/()", cyclone.web.StaticFileHandler, { "path": ".", "default_filename": "index.html" }), (r'/build/(bundle\.js)', cyclone.web.StaticFileHandler, { "path": "build" }), (r'/graph/webevents', CycloneGraphHandler, { 'masterGraph': masterGraph }), (r'/graph/webevents/events', CycloneGraphEventsHandler, { 'masterGraph': masterGraph }), ] cyclone.web.Application.__init__(self, handlers, masterGraph=masterGraph, coll=coll) task.LoopingCall(update, masterGraph, eventsInGraph, coll).start(10) reactor.listenTCP(10001, Application()) log.info('serving') reactor.run()
def post(self): """ payload is an rdf graph. The statements are momentarily added to the input graph for exactly one update. todo: how do we go from a transition like doorclosed-to-open to a oneshot event? the upstream shouldn't have to do it. Do we make those oneshot events here? for every object change? there are probably special cases regarding startup time when everything appears to be a 'change'. """ try: log.info('POST to oneShot, headers=%s', self.request.headers) ct = self.request.headers.get( 'Content-Type', self.request.headers.get('content-type', '')) dt = self.settings.reasoning.inputGraph.addOneShotFromString( self.request.body, ct) self.set_header('x-graph-ms', str(1000 * dt)) except Exception as e: traceback.print_exc() log.error(e) raise
def onNodes(self, newAddrs: List[SeenNode]): now = int(time.time()) newWithSignal = [a for a in newAddrs if a.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)) 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 self.lastAddrs = newAddrs self.lastPollTime = now self.updateGraph(masterGraph)
def graphChanged(self, inputGraph: InputGraph, oneShot=False, oneShotGraph: Graph = 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 %s stmts):", oneShot, len(oneShotGraph) if oneShotGraph is not None else 0) if oneShotGraph: for stmt in oneShotGraph: log.info(" oneshot -> %s", ntStatement(stmt)) 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.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)) if not oneShot: self.copyOutput()
Usage: this [-v] [--cam host] [--port to_serve] Options: -v --verbose more log --port n http server [default: 10020] --cam host hostname of esphome server ''') verboseLogging(arguments['--verbose']) logging.getLogger('aioesphomeapi.connection').setLevel(logging.INFO) loop = asyncio.get_event_loop() recv = CameraReceiver(loop, arguments['--cam']) detector = apriltag.Detector() f = recv.start() loop.create_task(f) start_time = time.time() app = web.Application() app.router.add_route('GET', '/stream', stream) app.router.add_route('GET', '/', index) try: web.run_app(app, host='0.0.0.0', port=int(arguments['--port'])) except RuntimeError as e: log.error(e) log.info(f'run_app stopped after {time.time() - start_time} sec')
brokerHost='mosquitto-ext.default.svc.cluster.local', brokerPort=1883) # deprecated internalMqtt = MqttClient(clientId='mqtt_to_rdf', brokerHost=brokerHost, brokerPort=brokerPort) srcs = [] for src in sorted(config.subjects(RDF.type, ROOM['MqttStatementSource'])): srcs.append( MqttStatementSource(src, config, masterGraph, mqtt=mqtt, internalMqtt=internalMqtt, debugPageData=debugPageData)) log.info(f'set up {len(srcs)} sources') port = 10018 reactor.listenTCP( port, cyclone.web.Application([ (r"/()", cyclone.web.StaticFileHandler, { "path": ".", "default_filename": "index.html" }), (r"/build/(bundle.js)", cyclone.web.StaticFileHandler, { "path": "build" }), (r"/graph/mqtt", CycloneGraphHandler, { 'masterGraph': masterGraph }),
def messageReceived(self, message): log.info("got message %s" % 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 relock(self): log.info('autolock is up: requesting lock') self.mqtt.publish(espName + b"/switch/strike/command", mqttMessageFromState(ROOM['locked']))
def toGraph(payload): log.info('mqtt->graph %r', payload) masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], stateFromMqtt(payload))
def setEspState(payload): log.info('esp state change %r', payload) masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'], ROOM['mqtt' + payload.decode('ascii').capitalize()])
def toGraph(payload): log.info('mqtt->graph %r', payload) masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], stateFromMqtt(payload))
def setEspState(payload): log.info('esp state change %r', payload) masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'], ROOM['mqtt' + payload.decode('ascii').capitalize()])
def relock(self): log.info('autolock is up: requesting lock') self.mqtt.publish(espName + b"/switch/strike/command", mqttMessageFromState(ROOM['locked']))
def hello(): log.info('hi devices') log.info(w1thermsensor.W1ThermSensor.get_available_sensors())