如何让coroutine等待串口输入?

时间:2017-01-28 10:02:01

标签: serial-port python-asyncio

我的结构类似于Equivalent of asyncio.Queues with worker "threads"中描述的结构。

差异是我的生产者"将打开一个串行线并异步解析输入,直到"令牌"被识别(而不是生成随机数)。然后通过asyncio.Queue将标记传递给" consumer"。

暂定代码包括:

@asyncio.coroutine
def produce():
    with open('infile.cmd', 'r') as ifd:
        while True:
            cmd = yield from ifd.readline()
            if cmd is None:
                break
            print("received {}".format(cmd))
            yield from q.put(cmd)

但由于" RuntimeError:任务收益率不高,因此无法正常工作:' p'"在ifd.readline()行。

我还尝试使用Reader(cfr。:Using asyncio to read the output of a serial port):

event_loop = asyncio.get_event_loop()
try:
    with open('infile.cmd', 'r') as ifd:
        event_loop.add_reader(ifd, produce)
    event_loop.create_task(consume())
    print('entering event loop')
    event_loop.run_forever()

但这次爆炸与:

Traceback (most recent call last):
  File "/home/mcon/trasmissione-telematica/Communications/prove/asio.py", line 32, in <module>
    event_loop.add_reader(ifd, produce)
  File "/usr/lib/python3.5/asyncio/selector_events.py", line 337, in add_reader
    return self._add_reader(fd, callback, *args)
  File "/usr/lib/python3.5/asyncio/selector_events.py", line 267, in _add_reader
    (handle, None))
  File "/usr/lib/python3.5/selectors.py", line 412, in register
    self._epoll.register(key.fd, epoll_events)
PermissionError: [Errno 1] Operation not permitted

我怎样才能异步读取某些东西?

注意:在这个例子中我是从文件中读取的,但最后我必须从非阻塞的串行线读取二进制数据(/ dev / ttySx或命名管道),所以允许面向行的输入;数据必须在可用时立即阅读,并且&#34;生产者&#34;有责任了解&#34; cmd&#34;已经完成了。

1 个答案:

答案 0 :(得分:0)

使用aiofiles和python 3.5+,以下代码效果很好:

async def produce():
    async with aiofiles.open('test.cmd', mode = 'r') as ifd:
        while True:
            cmd = await ifd.readline()
            #readlines ourput is not stripped
            cmd = cmd.strip()
            if not cmd or cmd=='stop':
                print("finished")
                break
            print("cmd {}".format(cmd))
            await q.put(cmd)

loop = asyncio.get_event_loop()
q = asyncio.Queue()
loop.run_until_complete(produce())

TEST.CMD

mv hello
cp world
stop

输出:

cmd mv hello
cmd cp world
finished