Esempio n. 1
0
 def _sendUpdatePatch(self, handler: Optional[PatchSink] = None):
     """
     send a patch event out this handler to bring it up to date with
     self.statements
     """
     now = time.time()
     selected = self.handlers
     if handler is not None:
         if handler not in self.handlers:
             log.error("called _sendUpdatePatch on a handler that's gone")
             return
         selected = {handler}
     # reduce loops here- prepare all patches at once
     for h in selected:
         period = .9
         if 'Raspbian' in h.request.headers.get('user-agent', ''):
             period = 5
         if h.lastPatchSentTime > now - period:
             continue
         p = self.statements.makeSyncPatch(h,
                                           set(self._sourcesForHandler(h)))
         log.debug('makeSyncPatch for %r: %r', h, p.jsonRepr)
         if not p.isNoop():
             log.debug("send patch %s to %s", p.shortSummary(), h)
             # This can be a giant line, which was a problem
             # once. Might be nice for this service to try to break
             # it up into multiple sends, although there's no
             # guarantee at all since any single stmt could be any
             # length.
             h.sendEvent(message=jsonFromPatch(p).encode('utf8'),
                         event=b'patch')
             h.lastPatchSentTime = now
         else:
             log.debug('nothing to send to %s', h)
Esempio n. 2
0
    def poll(self):
        ret = None
        startTime = time.time()
        try:
            url = (f'http://{deviceIp}/cgi-bin/cgi_manager').encode('ascii')
            resp = yield fetch(
                url,
                method=b'POST',
                headers={b'Authorization': [b'Basic %s' % auth]},
                postdata=(f'''<LocalCommand>
                              <Name>get_usage_data</Name>
                              <MacId>0x{macId}</MacId>
                            </LocalCommand>
                            <LocalCommand>
                              <Name>get_price_blocks</Name>
                              <MacId>0x{macId}</MacId>
                            </LocalCommand>''').encode('ascii'),
                timeout=10)
            ret = json.loads(resp.body)
            log.debug(ret)
            if ret['demand_units'] != 'kW':
                raise ValueError
            if ret['summation_units'] != 'kWh':
                raise ValueError
            pts = [
                dict(measurement='housePowerW',
                     fields=dict(value=float(ret['demand']) * 1000),
                     tags=dict(house='berkeley'),
                     time=int(startTime))]
            sd = float(ret['summation_delivered'])
            if sd > 0: # Sometimes nan
                pts.append(dict(measurement='housePowerSumDeliveredKwh',
                                fields=dict(value=float()),
                                tags=dict(house='berkeley'),
                                time=int(startTime)))
            if 'price' in ret:
                pts.append(dict(
                    measurement='price',
                    fields=dict(price=float(ret['price']),
                                price_units=float(ret['price_units'])),
                    tags=dict(house='berkeley'),
                    time=int(startTime),
                ))

            self.influx.write_points(pts, time_precision='s')

            self.graph.patchObject(context=ROOM['powerEagle'],
                                         subject=ROOM['housePower'],
                                         predicate=ROOM['instantDemandWatts'],
                                         newObject=Literal(float(ret['demand']) * 1000))
        except Exception as e:
            traceback.print_exc()
            log.error("failed: %r", e)
            log.error(repr(ret))
            os.abort()

        now = time.time()
        goal = startTime + periodSec - .2
        reactor.callLater(max(1, goal - now), self.poll)
Esempio n. 3
0
    def poll(self):
        ret = None
        startTime = time.time()
        try:
            url = (f'http://{deviceIp}/cgi-bin/cgi_manager').encode('ascii')
            resp = yield fetch(
                url,
                method=b'POST',
                headers={b'Authorization': [b'Basic %s' % auth]},
                postdata=(f'''<LocalCommand>
                              <Name>get_usage_data</Name>
                              <MacId>0x{macId}</MacId>
                            </LocalCommand>
                            <LocalCommand>
                              <Name>get_price_blocks</Name>
                              <MacId>0x{macId}</MacId>
                            </LocalCommand>''').encode('ascii'),
                timeout=10)
            ret = json.loads(resp.body)
            log.debug(f"response body {ret}")
            if ret['demand_units'] != 'kW':
                raise ValueError
            if ret['summation_units'] != 'kWh':
                raise ValueError

            demandW = float(ret['demand']) * 1000
            self.out['w'].set(demandW)

            sd = float(ret['summation_delivered'])
            if sd > 0:  # Sometimes nan
                self.out['kwh'].set(sd)

            if 'price' in ret:
                self.out['price'].set(float(ret['price']))

            self.graph.patchObject(context=ROOM['powerEagle'],
                                   subject=ROOM['housePower'],
                                   predicate=ROOM['instantDemandWatts'],
                                   newObject=Literal(demandW))
            POLL_SUCCESSES.inc()
        except Exception as e:
            POLL_ERRORS.inc()
            traceback.print_exc()
            log.error("failed: %r", e)
            log.error(repr(ret))

        now = time.time()
        goal = startTime + periodSec - .2
        reactor.callLater(max(1, goal - now), self.poll)
Esempio n. 4
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
Esempio n. 5
0
    def poll(self):
        ms = get_idle_time()
        ctx = DEV['xidle/%s' % host]
        subj = URIRef("http://bigasterisk.com/host/%s/xidle" % host)
        lastMinActive = ms < 60 * 1000
        now = int(time.time())

        nextGraphUpdate = self.lastGraphSentTime + min(10, ms / 1000 / 2)
        if self.lastGraphSent != lastMinActive or now > nextGraphUpdate:
            masterGraph.patchObject(ctx, subj, ROOM['idleTimeMs'], Literal(ms))
            masterGraph.patchObject(ctx, subj, ROOM['idleTimeMinutes'],
                                    Literal(round(ms / 1000 / 60, 2)))
            self.lastGraphSent = lastMinActive
            self.lastGraphSentTime = now

        if self.lastSent != lastMinActive or now > self.lastSentTime + 3600:
            self.points.append({
                "measurement": "presence",
                "tags": {
                    "host": host,
                    "sensor": "xidle"
                },
                "fields": {
                    "value": 1 if lastMinActive else 0
                },
                "time": now
            })
            self.lastSent = lastMinActive
            self.lastSentTime = now

            try:
                client.write_points(self.points, time_precision='s')
            except influxdb.exceptions.InfluxDBServerError as e:
                log.error(repr(e))
                reactor.crash()
            self.points = []
Esempio n. 6
0
 def poll(self):
     try:
         newAddrs = yield self.wifi.getPresentMacAddrs()
         self.onNodes(newAddrs)
     except Exception as e:
         log.error("poll error: %r\n%s", e, traceback.format_exc())
Esempio n. 7
0
this

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')