I'm trying to use aremote.py togother with picoweb, and thing works werid
Closed this issue · 3 comments
I'm doing something like this:
ROUTES = [
# You can specify exact URI string matches...
("/", lambda req, resp: (yield from app.sendfile(resp, "index.html"))),
("/favicon.ico", lambda req, resp: (yield from app.sendfile(resp, "favicon.ico"))),
("/tinycolorpicker.css", lambda req, resp: (yield from app.sendfile(resp, "tinycolorpicker.css"))),
("/tinycolorpicker.js", lambda req, resp: (yield from app.sendfile(resp, "tinycolorpicker.js"))),
("/text-color.png", lambda req, resp: (yield from app.sendfile(resp, "text-color.png"))),
("/rgb/", rgb),
]
def cb(data, addr):
if data == REPEAT:
print('Repeat')
elif data >= 0:
print(hex(data), hex(addr))
else:
print('{} Address: {}'.format(data, hex(addr)))
print('Test for IR receiver. Assumes NEC protocol.')
machine.freq(160000000)
p = machine.Pin(14, machine.Pin.IN)
ir = NEC_IR(p, cb, True) # Assume r/c uses extended addressing
app = picoweb.WebApp(__name__, ROUTES)
app.run(debug=False, host="0.0.0.0")
and aremote seem to be working fine, but every http request is blocked until pressing a remote key.
couldn't figure out what fishy here...
That's got me beat, too. I haven't used picoweb but from a quick look at the code they should play together. While waiting for a signal from the remote, at line 57 in aremote.py, it waits on the Event instance's __iter__
/ __await__
method which waits on sleep(0)
. So other coroutines should be scheduled in round-robin fashion. You could try putting debug print statements there to verify that's what's happening.
I'd also be tempted as a test to omit the IR stuff and write a simple coro which does something like periodically print "hello" to prove picoweb behaves sociably.
It may be a few days before I get a chance to look at this more closely.
OK, I found some time to look at this. I think we have a bug in uasyncio. For a quick workround/test please can you alter asyn.py so that the Event object's __await__
method reads:
def __await__(self):
while not self._flag:
yield from asyncio.sleep_ms(5)
It seems that an awaitable object yielding 0 blocks streamreaders (although the scheduler is still running and I could schedule other coros). To prove the point I produced the following, which has the Event class stripped down to an awaitable Bar
which just waits forever. The foo
coro works correctly regardless of the sleep time. But with a sleep time of zero the webapp fails. With it > 0 it runs.
import ure as re
import picoweb
import uasyncio as asyncio
def index(req, resp):
# You can construct an HTTP response completely yourself, having
# a full control of headers sent...
yield from resp.awrite("HTTP/1.0 200 OK\r\n")
yield from resp.awrite("Content-Type: text/html\r\n")
yield from resp.awrite("\r\n")
yield from resp.awrite("I can show you a table of <a href='squares'>squares</a>.<br/>")
yield from resp.awrite("Or my <a href='file'>source</a>.")
def squares(req, resp):
# Or can use a convenience function start_response() (see its source for
# extra params it takes).
yield from picoweb.start_response(resp)
yield from app.render_template(resp, "squares.tpl", (req,))
def hello(req, resp):
yield from picoweb.start_response(resp)
# Here's how you extract matched groups from a regex URI match
yield from resp.awrite("Hello " + req.url_match.group(1))
ROUTES = [
# You can specify exact URI string matches...
("/", index),
("/squares", squares),
("/file", lambda req, resp: (yield from app.sendfile(resp, "example_webapp.py"))),
# ... or match using a regex, a match result available as req.url_match
# for group extraction in your view.
(re.compile("^/iam/(.+)"), hello),
]
import logging
logging.basicConfig(level=logging.INFO)
#logging.basicConfig(level=logging.DEBUG)
class Bar():
def __await__(self):
while True:
yield from asyncio.sleep_ms(5) # Change this to 0 and the webapp fails
__iter__ = __await__
bar = Bar()
async def foo():
print('Starting foo. Should never finish.')
await bar
print('foo finished.')
loop = asyncio.get_event_loop()
loop.create_task(foo())
app = picoweb.WebApp(__name__, ROUTES)
app.run(debug=True, host='0.0.0.0')
I'll try to find a simpler testcase and raise an issue.