From cac98eeb05331d7ed4ff2e609b1a9be3dacfb7c5 Mon Sep 17 00:00:00 2001 From: gluap Date: Sat, 30 May 2020 13:40:37 +0200 Subject: [PATCH] This is an experiment targeted at #7. What we observe might be a connection hanging. --- pyess/aio_ess.py | 7 +++++-- pyess/ess.py | 2 +- pyess/essmqtt.py | 32 +++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/pyess/aio_ess.py b/pyess/aio_ess.py index e7e3148..23d5c13 100755 --- a/pyess/aio_ess.py +++ b/pyess/aio_ess.py @@ -37,8 +37,10 @@ def __init__(self, name, pw, ip=None): self.name = name self.pw = pw self.ip = ip + self.logged_in = False self.auth_key = None - self.session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) + self.session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False), read_timeout=60, + conn_timeout=60, timeout=120) async def _login(self, retry=1): """ @@ -69,6 +71,7 @@ async def _login(self, retry=1): time.sleep(retry) return await self._login(retry=retry * 2) self.auth_key = auth_key + self.logged_in = True return auth_key async def get_graph(self, device: str, timespan: str, date: datetime.datetime): @@ -87,7 +90,7 @@ async def get_graph(self, device: str, timespan: str, date: datetime.datetime): return await self.post_json_with_auth(url, extra_json_data={ GRAPH_PARAMS[timespan]: date.strftime(GRAPH_TFORMATS[GRAPH_PARAMS[timespan]])}) - async def post_json_with_auth(self, url: str, retries: int = 1, extra_json_data: dict = None): + async def post_json_with_auth(self, url: str, retries: int = 15, extra_json_data: dict = None): """ wrapper that posts json data after adding auth data. Optionally takes an extra_json_data argument. :param url: URL to fetch diff --git a/pyess/ess.py b/pyess/ess.py index 98abd89..422b526 100755 --- a/pyess/ess.py +++ b/pyess/ess.py @@ -90,7 +90,7 @@ def post_json_with_auth(self, url: str, retries: int = 0, extra_json_data: dict if extra_json_data: json.update(extra_json_data) try: - r = requests.post(url, json=json, verify=False, headers={"Content-Type": "application/json"}) + r = requests.post(url, json=json, verify=False, headers={"Content-Type": "application/json"}, timeout=(3,3)) except (requests.ConnectionError, requests.ConnectTimeout): error = True if not error and (r.status_code == 200 or (r.json() != {'auth': 'auth_key failed'})): diff --git a/pyess/essmqtt.py b/pyess/essmqtt.py index fe3367d..100ac1a 100644 --- a/pyess/essmqtt.py +++ b/pyess/essmqtt.py @@ -26,7 +26,7 @@ def on_message(client, userdata, msg): print(msg.topic + " " + str(msg.payload)) -async def send_loop(client, ess, once=False, interval_seconds=10, common_divisor=1): +async def send_loop(ess, mqtt_client=None, graphite_client=None, once=False, interval_seconds=10, common_divisor=1): logger.info("starting send loop") i=0 while True: @@ -36,16 +36,18 @@ async def send_loop(client, ess, once=False, interval_seconds=10, common_divisor for key in home: for key2 in home[key]: try: - await client.publish("ess/home/" + key + "/" + key2, home[key][key2]) + await mqtt_client.publish("ess/home/" + key + "/" + key2, home[key][key2]) except: + logger.exception("exception while sending to mqtt") pass if i % common_divisor == 0: common = await ess.get_state("common") for key in common: for key2 in common[key]: try: - await client.publish("ess/common/" + key + "/" + key2, common[key][key2]) + await mqtt_client.publish("ess/common/" + key + "/" + key2, common[key][key2]) except: + logger.exception("exception while sending to mqtt") pass i+=1 if once: @@ -118,18 +120,26 @@ async def handle_control(client,control,path): except ValueError: logger.warning(f"ignoring incompatible value {msg} for switching") - - async with Client(args.mqtt_server, port=args.mqtt_port, logger=logger, username=args.mqtt_user, + if args.mqtt_server is not None: + async with Client(args.mqtt_server, port=args.mqtt_port, logger=logger, username=args.mqtt_user, password=args.mqtt_password) as client: + # seems that a leading slash is frowned upon in mqtt, but we keep this for backwards compatibility + await client.subscribe('/ess/control/#') + asyncio.create_task(handle_control(client, switch_winter, "/ess/control/winter_mode")) + asyncio.create_task(handle_control(client, switch_fastcharge, "/ess/control/fastcharge")) + asyncio.create_task(handle_control(client, switch_active, "/ess/control/active")) - await client.subscribe('/ess/control/#') - asyncio.create_task(handle_control(client, switch_winter, "/ess/control/winter_mode")) - asyncio.create_task(handle_control(client, switch_fastcharge, "/ess/control/fastcharge")) - asyncio.create_task(handle_control(client, switch_active, "/ess/control/active")) + # also subscribe without leading slash for better style + await client.subscribe('ess/control/#') + asyncio.create_task(handle_control(client, switch_winter, "ess/control/winter_mode")) + asyncio.create_task(handle_control(client, switch_fastcharge, "ess/control/fastcharge")) + asyncio.create_task(handle_control(client, switch_active, "ess/control/active")) - await send_loop(client, ess, once=args.once, interval_seconds=args.interval_seconds, - common_divisor=args.common_divisor) + await send_loop(ess, client, once=args.once, interval_seconds=args.interval_seconds, + common_divisor=args.common_divisor) + else: + pass if __name__ == "__main__": main(sys.argv[1:])