diff options
author | Edi Feschiyan <edi.feschiyan@konsulko.com> | 2020-05-08 12:11:10 +0300 |
---|---|---|
committer | Edi Feschiyan <edi.feschiyan@konsulko.com> | 2020-05-08 12:11:10 +0300 |
commit | 219e992aa8a8e5a7db48cc9d66bb0ddbbe7c21a3 (patch) | |
tree | b6a39f637851ad41f04420012fac5c659c4fae85 | |
parent | b2db7fb84b44c3c2cc464475b84494570f057882 (diff) |
Adding requirements, work in progress to integrate this thing with pytest
-rw-r--r-- | aglbaseservice.py | 33 | ||||
-rw-r--r-- | bluetooth.py | 2 | ||||
-rw-r--r-- | gps.py | 14 | ||||
-rw-r--r-- | mediaplayer.py | 24 | ||||
-rw-r--r-- | requirements.txt | 18 |
5 files changed, 73 insertions, 18 deletions
diff --git a/aglbaseservice.py b/aglbaseservice.py index 8c4814b..ff35df4 100644 --- a/aglbaseservice.py +++ b/aglbaseservice.py @@ -12,6 +12,7 @@ import json import sys import os import re +from contextlib import asynccontextmanager logging.getLogger('AGLBaseService') logging.basicConfig(level=logging.DEBUG) @@ -31,6 +32,7 @@ def addresponse(msgid, msg): if msgid in msgq.keys(): msgq[msgid]['response'] = msg + class AGLBaseService: api: str url: str @@ -85,7 +87,7 @@ class AGLBaseService: exit(1) URL = f'ws://{self.ip}:{self.port}/api?token={self.token}&uuid={self.uuid}' - self._conn = connect(close_timeout=0, uri=URL, subprotocols=['x-afb-ws-json1'], ping_interval=None) + self._conn = connect(close_timeout=0, uri=URL, subprotocols=['x-afb-ws-json1'], ping_interval=None, timeout=2) self.websocket = await self._conn.__aenter__() return self @@ -102,7 +104,11 @@ class AGLBaseService: return await self.websocket.recv() async def portfinder(self): + # TODO:handle ssh timeouts, asyncssh does not support it apparently, and connect returns context_manager which + # cannot be used with asyncio.wait_for + async with asyncssh.connect(self.ip, username='root') as c: + servicename = await c.run(f"systemctl --all | grep {self.service}-- | awk '{{print $1}}'", check=False) if self.service not in servicename.stdout: logging.error(f"Service matching pattern - '{self.service}' - NOT FOUND") @@ -168,6 +174,31 @@ class AGLBaseService: except Exception as e: self.logger.error("Unhandled seal: " + str(e)) + async def response(self, stdout: bool = False): + try: + msg = await self.websocket.recv() + try: + data = json.loads(msg) + yield data + self.logger.debug('[AGL] -> ' + msg) + if isinstance(data, list): + if stdout: + print(data) + if data[0] == AFBT.RESPONSE and str.isnumeric(data[1]): + msgid = int(data[1]) + if msgid in msgq: + addresponse(msgid, data) + yield data + except JSONDecodeError: + self.logger.warning("Not decoding a non-json message") + + except KeyboardInterrupt: + self.logger.debug("Received keyboard interrupt, exiting") + except asyncio.CancelledError: + self.logger.warning("Websocket listener coroutine stopped") + except Exception as e: + self.logger.error("Unhandled seal: " + str(e)) + async def request(self, verb: str, values: Union[str, dict] = "", msgid: int = randint(0, 9999999), waitresponse: bool = False): l = json.dumps([AFBT.REQUEST, str(msgid), f'{self.api}/{verb}', values]) diff --git a/bluetooth.py b/bluetooth.py index caef235..a28bc3c 100644 --- a/bluetooth.py +++ b/bluetooth.py @@ -64,4 +64,4 @@ async def main(loop): if __name__ == '__main__': loop = asyncio.get_event_loop() - loop.run_until_complete(main(loop))
\ No newline at end of file + loop.run_until_complete(main(loop)) @@ -2,6 +2,8 @@ from aglbaseservice import AGLBaseService import asyncio import os +from concurrent import futures +xc = futures.ThreadPoolExecutor(1) class GPSService(AGLBaseService): service = 'agl-service-gps' @@ -25,10 +27,20 @@ async def main(loop): args = GPSService.parser.parse_args() gpss = await GPSService(args.ipaddr) + r = await loop.run_in_executor(xc, gpss.response) + if args.loglevel: GPSService.logger.setLevel(args.loglevel) if args.location: - print(await gpss.location(waitresponse=True)) + await gpss.location() + async for response in r: + await gpss.location() + print(await r.__anext__()) + + + # loc = await l + # print(loc) + if args.subscribe: await gpss.subscribe(args.subscribe) diff --git a/mediaplayer.py b/mediaplayer.py index e7059b6..b916dd8 100644 --- a/mediaplayer.py +++ b/mediaplayer.py @@ -1,8 +1,6 @@ -import os -import asyncio -import json - from aglbaseservice import AGLBaseService +import asyncio +import os class MediaPlayerService(AGLBaseService): @@ -13,19 +11,15 @@ class MediaPlayerService(AGLBaseService): super().__init__(api='mediaplayer', ip=ip, port=port, service='agl-service-mediaplayer') async def playlist(self, waitresponse=False): - if waitresponse: - return await self.request('playlist', waitresponse=waitresponse) - else: - await self.request('playlist') + return await self.request('playlist', waitresponse=waitresponse) - async def subscribe(self, event='metadata'): - await super().subscribe(event=event) + async def subscribe(self, event='metadata', waitresponse=False): + await super().subscribe(event=event, waitresponse=waitresponse) - async def unsubscribe(self, event='metadata'): - await super().subscribe(event=event) + async def unsubscribe(self, event='metadata', waitresponse=False): + await super().subscribe(event=event, waitresponse=waitresponse) - async def control(self, name, value=None): - verb = 'controls' + async def control(self, name, value=None, waitresponse=False): loopstate = ['off', 'playlist', 'track'] controls = { 'play': None, @@ -59,7 +53,7 @@ class MediaPlayerService(AGLBaseService): assert value in loopstate, f'Tried to set invalid loopstate - {value}, use "off", "playlist" or "track"' msg = {'value': name, controls[name]: str(value)} - await self.request(verb, msg) + await self.request('controls', msg, waitresponse=waitresponse) async def main(loop): diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3d1f9db --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +asyncssh==2.2.0 +attrs==19.3.0 +cffi==1.14.0 +cryptography==2.8 +importlib-metadata==1.6.0 +more-itertools==8.2.0 +packaging==20.3 +parse==1.15.0 +pluggy==0.13.1 +py==1.8.1 +pycparser==2.20 +pyparsing==2.4.7 +pytest==5.4.1 +pytest-asyncio==0.11.0 +six==1.14.0 +wcwidth==0.1.9 +websockets==8.1 +zipp==3.1.0 |