コード例 #1
0
ファイル: collector.py プロジェクト: drewp/homeauto
 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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: playSound.py プロジェクト: prashant-oswal/homeauto
 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
ファイル: rdf_to_mqtt.py プロジェクト: drewp/homeauto
    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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: collector.py プロジェクト: drewp/homeauto
    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
ファイル: collector.py プロジェクト: drewp/homeauto
    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
ファイル: report.py プロジェクト: drewp/webfilter
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
ファイル: wifi.py プロジェクト: prashant-oswal/homeauto
    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
ファイル: mqtt_to_rdf.py プロジェクト: drewp/homeauto
                      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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 def relock(self):
     log.info('autolock is up: requesting lock')
     self.mqtt.publish(espName + b"/switch/strike/command",
                       mqttMessageFromState(ROOM['locked']))
コード例 #22
0
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 def toGraph(payload):
     log.info('mqtt->graph %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'],
                             stateFromMqtt(payload))
コード例 #23
0
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 def toGraph(payload):
     log.info('mqtt->graph %r', payload)
     masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'],
                             stateFromMqtt(payload))
コード例 #25
0
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 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
ファイル: front_door_lock.py プロジェクト: drewp/homeauto
 def relock(self):
     log.info('autolock is up: requesting lock')
     self.mqtt.publish(espName + b"/switch/strike/command",
                       mqttMessageFromState(ROOM['locked']))
コード例 #27
0
ファイル: devices.py プロジェクト: prashant-oswal/homeauto
def hello():
    log.info('hi devices')

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