Пример #1
0
 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),
                   ]))
Пример #2
0
    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)
Пример #3
0
 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')
Пример #4
0
 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')
Пример #5
0
 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')
Пример #6
0
    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)
Пример #7
0
 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)
Пример #8
0
 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)
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
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()
Пример #13
0
    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
Пример #14
0
    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)
Пример #15
0
    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()
Пример #16
0
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')
Пример #17
0
                      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
            }),
Пример #18
0
 def messageReceived(self, message):
     log.info("got message %s" % message)
Пример #19
0
 def connectionLost(self, reason):
     log.info("websocket closed")
     liveClients.remove(self)
Пример #20
0
 def connectionMade(self, *args, **kwargs):
     log.info("websocket opened")
     liveClients.add(self)
Пример #21
0
 def relock(self):
     log.info('autolock is up: requesting lock')
     self.mqtt.publish(espName + b"/switch/strike/command",
                       mqttMessageFromState(ROOM['locked']))
Пример #22
0
 def toGraph(payload):
     log.info('mqtt->graph %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'],
                             stateFromMqtt(payload))
Пример #23
0
 def setEspState(payload):
     log.info('esp state change %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'],
                             ROOM['mqtt' + payload.decode('ascii').capitalize()])
Пример #24
0
 def toGraph(payload):
     log.info('mqtt->graph %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'],
                             stateFromMqtt(payload))
Пример #25
0
 def setEspState(payload):
     log.info('esp state change %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'],
                             ROOM['mqtt' + payload.decode('ascii').capitalize()])
Пример #26
0
 def relock(self):
     log.info('autolock is up: requesting lock')
     self.mqtt.publish(espName + b"/switch/strike/command",
                       mqttMessageFromState(ROOM['locked']))
Пример #27
0
def hello():
    log.info('hi devices')

    log.info(w1thermsensor.W1ThermSensor.get_available_sensors())