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