Mercurial > code > home > repos > homeauto
diff espNode/readcam.py @ 1740:c77b5ab7b99d
camera work
author | drewp@bigasterisk.com |
---|---|
date | Fri, 01 Sep 2023 17:13:51 -0700 |
parents | bc3516d02762 |
children |
line wrap: on
line diff
--- a/espNode/readcam.py Fri Sep 01 17:12:06 2023 -0700 +++ b/espNode/readcam.py Fri Sep 01 17:13:51 2023 -0700 @@ -1,59 +1,56 @@ #!camtest/bin/python3 +import asyncio import binascii +import io +import json import logging -import time -import io import os -import json -from docopt import docopt -from standardservice.logsetup import log, verboseLogging +import time -logging.basicConfig(level=logging.INFO) +import apriltag +import cv2 +import numpy +from aioesphomeapi.client import APIClient +from aioesphomeapi.model import CameraState from aiohttp import web from aiohttp.web import Response from aiohttp_sse import sse_response - -import asyncio +from docopt import docopt -from aioesphomeapi import APIClient -from aioesphomeapi.model import CameraState -import apriltag -import cv2 -import numpy +logging.basicConfig(level=logging.INFO) +log = logging.getLogger(__name__) + class CameraReceiver: - def __init__(self, loop, host): + + def __init__(self, host): self.lastFrameTime = None - self.loop = loop self.host = host self.lastFrame = b"", '' self.recent = [] async def start(self): try: - self.c = c = APIClient(self.loop, - self.host, - 6053, 'MyPassword') + self.c = c = APIClient(self.host, 6053, 'MyPassword') await c.connect(login=True) await c.subscribe_states(on_state=self.on_state) except OSError: - loop.stop() return - self.loop.create_task(self.start_requesting_image_stream_forever()) + self.t = asyncio.create_task( + self.start_requesting_image_stream_forever()) async def start_requesting_image_stream_forever(self): while True: try: await self.c.request_image_stream() except AttributeError: - self.loop.stop() return # https://github.com/esphome/esphome/blob/dev/esphome/components/esp32_camera/esp32_camera.cpp#L265 says a 'stream' is 5 sec long await asyncio.sleep(4) def on_state(self, s): if isinstance(s, CameraState): - jpg = s.image + jpg = s.data if len(self.recent) > 10: self.recent = self.recent[-10:] @@ -64,8 +61,7 @@ print('other on_state', s) def analyze(self, jpg): - img = cv2.imdecode(numpy.asarray(bytearray(jpg)), - cv2.IMREAD_GRAYSCALE) + img = cv2.imdecode(numpy.asarray(bytearray(jpg)), cv2.IMREAD_GRAYSCALE) result = detector.detect(img) msg = {} if result: @@ -92,6 +88,7 @@ def imageUri(jpg): return 'data:image/jpeg;base64,' + binascii.b2a_base64(jpg).decode('ascii') + async def stream(request): async with sse_response(request) as resp: await resp.send(imageUri(recv.lastFrame[0])) @@ -101,6 +98,7 @@ await resp.send(imageUri(frame)) return resp + async def index(request): d = r""" <html> @@ -146,31 +144,26 @@ this Usage: - this [-v] [--cam host] [--port to_serve] +this [-v] [--cam host] [--port to_serve] Options: - -v --verbose more log - --port n http server [default: 10020] - --cam host hostname of esphome server +--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(arguments['--cam']) -recv = CameraReceiver(loop, arguments['--cam']) detector = apriltag.Detector() f = recv.start() -loop.create_task(f) +async def starter(app): + asyncio.create_task(f) start_time = time.time() app = web.Application() +app.on_startup.append(starter) 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') \ No newline at end of file +web.run_app(app, port=int(arguments['--port'])) \ No newline at end of file