Mercurial > code > home > repos > homeauto
comparison espNode/readcam.py @ 773:bc3516d02762
old changes in espNode
Ignore-this: cbdcaf859b465e76c2c98e0d4510a1d3
author | drewp@bigasterisk.com |
---|---|
date | Sun, 28 Jun 2020 14:05:12 -0700 |
parents | b14020802f8a |
children | c77b5ab7b99d |
comparison
equal
deleted
inserted
replaced
772:2500a3ee9102 | 773:bc3516d02762 |
---|---|
3 import logging | 3 import logging |
4 import time | 4 import time |
5 import io | 5 import io |
6 import os | 6 import os |
7 import json | 7 import json |
8 from docopt import docopt | |
9 from standardservice.logsetup import log, verboseLogging | |
10 | |
8 logging.basicConfig(level=logging.INFO) | 11 logging.basicConfig(level=logging.INFO) |
9 from aiohttp import web | 12 from aiohttp import web |
10 from aiohttp.web import Response | 13 from aiohttp.web import Response |
11 from aiohttp_sse import sse_response | 14 from aiohttp_sse import sse_response |
12 | 15 |
17 import apriltag | 20 import apriltag |
18 import cv2 | 21 import cv2 |
19 import numpy | 22 import numpy |
20 | 23 |
21 class CameraReceiver: | 24 class CameraReceiver: |
22 def __init__(self, loop): | 25 def __init__(self, loop, host): |
23 self.lastFrameTime = None | 26 self.lastFrameTime = None |
24 self.loop = loop | 27 self.loop = loop |
28 self.host = host | |
25 self.lastFrame = b"", '' | 29 self.lastFrame = b"", '' |
26 self.recent = [] | 30 self.recent = [] |
27 | 31 |
28 async def start(self): | 32 async def start(self): |
29 self.c = c = APIClient(self.loop, '10.2.0.21', 6053, 'MyPassword') | 33 try: |
30 await c.connect(login=True) | 34 self.c = c = APIClient(self.loop, |
31 await c.subscribe_states(on_state=self.on_state) | 35 self.host, |
32 await c.request_image_stream() | 36 6053, 'MyPassword') |
37 await c.connect(login=True) | |
38 await c.subscribe_states(on_state=self.on_state) | |
39 except OSError: | |
40 loop.stop() | |
41 return | |
42 self.loop.create_task(self.start_requesting_image_stream_forever()) | |
43 | |
44 async def start_requesting_image_stream_forever(self): | |
45 while True: | |
46 try: | |
47 await self.c.request_image_stream() | |
48 except AttributeError: | |
49 self.loop.stop() | |
50 return | |
51 # https://github.com/esphome/esphome/blob/dev/esphome/components/esp32_camera/esp32_camera.cpp#L265 says a 'stream' is 5 sec long | |
52 await asyncio.sleep(4) | |
33 | 53 |
34 def on_state(self, s): | 54 def on_state(self, s): |
35 if isinstance(s, CameraState): | 55 if isinstance(s, CameraState): |
36 jpg = s.image | 56 jpg = s.image |
37 if len(self.recent) > 10: | 57 if len(self.recent) > 10: |
38 self.recent = self.recent[-10:] | 58 self.recent = self.recent[-10:] |
39 | 59 |
40 self.recent.append(jpg) | 60 self.recent.append(jpg) |
41 print('recent lens: %s' % (','.join(str(len(x)) | 61 #print('recent lens: %s' % (','.join(str(len(x)) |
42 for x in self.recent))) | 62 # for x in self.recent))) |
43 else: | 63 else: |
44 print('other on_state', s) | 64 print('other on_state', s) |
45 | 65 |
46 def analyze(self, jpg): | 66 def analyze(self, jpg): |
47 img = cv2.imdecode(numpy.asarray(bytearray(jpg)), | 67 img = cv2.imdecode(numpy.asarray(bytearray(jpg)), |
64 msg = self.analyze(jpg) | 84 msg = self.analyze(jpg) |
65 yield jpg, msg | 85 yield jpg, msg |
66 self.lastFrame = jpg, msg | 86 self.lastFrame = jpg, msg |
67 self.lastFrameTime = time.time() | 87 self.lastFrameTime = time.time() |
68 else: | 88 else: |
69 await asyncio.sleep(.5) | 89 await asyncio.sleep(.05) |
70 | 90 |
71 loop = asyncio.get_event_loop() | |
72 | |
73 recv = CameraReceiver(loop) | |
74 detector = apriltag.Detector() | |
75 | |
76 loop.create_task(recv.start()) | |
77 | 91 |
78 def imageUri(jpg): | 92 def imageUri(jpg): |
79 return 'data:image/jpeg;base64,' + binascii.b2a_base64(jpg).decode('ascii') | 93 return 'data:image/jpeg;base64,' + binascii.b2a_base64(jpg).decode('ascii') |
80 | 94 |
81 async def stream(request): | 95 async def stream(request): |
126 </body> | 140 </body> |
127 </html> | 141 </html> |
128 """ | 142 """ |
129 return Response(text=d, content_type='text/html') | 143 return Response(text=d, content_type='text/html') |
130 | 144 |
145 arguments = docopt(''' | |
146 this | |
131 | 147 |
148 Usage: | |
149 this [-v] [--cam host] [--port to_serve] | |
150 | |
151 Options: | |
152 -v --verbose more log | |
153 --port n http server [default: 10020] | |
154 --cam host hostname of esphome server | |
155 ''') | |
156 | |
157 verboseLogging(arguments['--verbose']) | |
158 logging.getLogger('aioesphomeapi.connection').setLevel(logging.INFO) | |
159 | |
160 loop = asyncio.get_event_loop() | |
161 | |
162 recv = CameraReceiver(loop, arguments['--cam']) | |
163 detector = apriltag.Detector() | |
164 | |
165 f = recv.start() | |
166 loop.create_task(f) | |
167 | |
168 start_time = time.time() | |
132 app = web.Application() | 169 app = web.Application() |
133 app.router.add_route('GET', '/stream', stream) | 170 app.router.add_route('GET', '/stream', stream) |
134 app.router.add_route('GET', '/', index) | 171 app.router.add_route('GET', '/', index) |
135 web.run_app(app, host='0.0.0.0', port=10020) | 172 try: |
173 web.run_app(app, host='0.0.0.0', port=int(arguments['--port'])) | |
174 except RuntimeError as e: | |
175 log.error(e) | |
176 log.info(f'run_app stopped after {time.time() - start_time} sec') |