From 9b1ec1e3ce31637ba54a3031a6436a9f8fbc5e51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?=
 =?UTF-8?q?=D0=A2=D1=83=D0=BC=D0=B0=D0=B9=D0=BA=D0=B8=D0=BD?=
 <AATumaykin@tsum.ru>
Date: Wed, 2 Jun 2021 09:46:38 +0300
Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80?=
 =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D0=BE=D0=BF=D1=80=D0=BE=D1=81=20=D1=81?=
 =?UTF-8?q?=D1=82=D0=B0=D1=82=D1=83=D1=81=D0=B0=20=D1=83=D1=81=D1=82=D1=80?=
 =?UTF-8?q?=D0=BE=D0=B9=D1=81=D1=82=D0=B2,=20=D0=B5=D1=81=D0=BB=D0=B8=20?=
 =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=BE=D1=88=D0=B5=D0=BB=20=D1=81?=
 =?UTF-8?q?=D0=B1=D0=BE=D0=B9=20=D0=BF=D1=80=D0=B8=20=D0=BE=D0=B1=D1=80?=
 =?UTF-8?q?=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BA=20=D1=81=D0=B5?=
 =?UTF-8?q?=D1=80=D0=B2=D0=B5=D1=80=D1=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 custom_components/electrolux_remote/api.py    | 80 +++++++++++--------
 custom_components/electrolux_remote/const.py  |  2 +-
 .../electrolux_remote/manifest.json           |  2 +-
 info.md                                       |  5 ++
 4 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/custom_components/electrolux_remote/api.py b/custom_components/electrolux_remote/api.py
index 2b376be..25b7864 100644
--- a/custom_components/electrolux_remote/api.py
+++ b/custom_components/electrolux_remote/api.py
@@ -3,6 +3,7 @@
 import logging
 import abc
 import async_timeout
+import time
 
 from aiohttp import ClientSession, ClientError
 from asyncio import TimeoutError, get_event_loop
@@ -31,6 +32,7 @@
 ERROR_INCORRECT_LOGIN_OR_PASSWORD = "106"
 ERROR_INCORRECT_PHONE = "112"  # Слишком короткий номер телефона
 ERROR_TOKEN_NOT_FOUND = "121"  # Токен не найден
+ERROR_WRITE_PARAM_UNAVAILABLE = "130"  # Параметр не доступен для записи: <param>
 ERROR_USER_NOT_FOUND = "136"  # Пользователь не найден
 ERROR_DEVICE_UNAVAILABLE = "153"  # Ошибка - устройство не в сети или неизвестный тип
 
@@ -43,6 +45,7 @@
 }
 
 TIMEOUT = 10
+SLEEP = 3
 
 
 class ApiInterface(metaclass=abc.ABCMeta):
@@ -146,38 +149,51 @@ async def _request(self, url: str, payload: dict) -> dict:
         _LOGGER.debug(f"request: {url}")
         _LOGGER.debug(f"payload: {payload}")
 
-        try:
-            async with async_timeout.timeout(TIMEOUT, loop=get_event_loop()):
-                response = await self._session.post(f"{self._host}/{url}", json=payload, headers=HEADERS)
-                json = await response.json()
-
-                _LOGGER.debug(f"response: {json}")
-
-                if json is None:
-                    raise InvalidResponse(f"Response error: json is None")
-
-                return json
-        except TimeoutError as exception:
-            _LOGGER.error(
-                "Timeout error fetching information from %s - %s",
-                url,
-                exception,
-            )
-
-        except (KeyError, TypeError) as exception:
-            _LOGGER.error(
-                "Error parsing information from %s - %s",
-                url,
-                exception,
-            )
-        except (ClientError, gaierror) as exception:
-            _LOGGER.error(
-                "Error fetching information from %s - %s",
-                url,
-                exception,
-            )
-        except Exception as exception:  # pylint: disable=broad-except
-            _LOGGER.error("Something really wrong happened! - %s", exception)
+        for i in range(0, 3):
+            while True:
+                try:
+                    async with async_timeout.timeout(TIMEOUT, loop=get_event_loop()):
+                        response = await self._session.post(f"{self._host}/{url}", json=payload, headers=HEADERS)
+                        json = await response.json()
+
+                        _LOGGER.debug(f"response: {json}")
+
+                        if json is None:
+                            raise InvalidResponse(f"Response error: json is None")
+
+                        return json
+                except TimeoutError as exception:
+                    _LOGGER.error(
+                        "Timeout error fetching information from %s - %s",
+                        url,
+                        exception,
+                    )
+
+                    time.sleep(SLEEP)
+                    continue
+                except (KeyError, TypeError) as exception:
+                    _LOGGER.error(
+                        "Error parsing information from %s - %s",
+                        url,
+                        exception,
+                    )
+
+                    time.sleep(SLEEP)
+                    continue
+                except (ClientError, gaierror) as exception:
+                    _LOGGER.error(
+                        "Error fetching information from %s - %s",
+                        url,
+                        exception,
+                    )
+
+                    time.sleep(SLEEP)
+                    continue
+                except Exception as exception:  # pylint: disable=broad-except
+                    _LOGGER.error("Something really wrong happened! - %s", exception)
+
+                    time.sleep(SLEEP)
+                    continue
 
     async def _update_device_params(self, params: dict) -> dict:
         if self._token is None:
diff --git a/custom_components/electrolux_remote/const.py b/custom_components/electrolux_remote/const.py
index e969f1e..7dd609e 100644
--- a/custom_components/electrolux_remote/const.py
+++ b/custom_components/electrolux_remote/const.py
@@ -3,7 +3,7 @@
 NAME = "{{ Electrolux remote }}"
 DOMAIN = "electrolux_remote"
 DOMAIN_DATA = f"{DOMAIN}_data"
-VERSION = "1.0.1"
+VERSION = "1.1.0"
 ISSUE_URL = "https://github.com/Ailme/home_assistant_electrolux_remote/issues"
 
 CONF_APPCODE = "appcode"
diff --git a/custom_components/electrolux_remote/manifest.json b/custom_components/electrolux_remote/manifest.json
index 66a8666..0e6aedc 100644
--- a/custom_components/electrolux_remote/manifest.json
+++ b/custom_components/electrolux_remote/manifest.json
@@ -13,5 +13,5 @@
     "@Ailme"
   ],
   "iot_class": "cloud_polling",
-  "version": "1.0.1"
+  "version": "1.1.0"
 }
diff --git a/info.md b/info.md
index 7f2021a..7c2d9e2 100644
--- a/info.md
+++ b/info.md
@@ -28,6 +28,11 @@
 This is **only** intended for development!
 
 {%- elif (version_installed.replace("v", "").split(".")[0] | int) < 1 %}
+## Version 1.1.0
+
+### Features
+- повторный опрос статуса устройств, если произошел сбой при обращении к серверу
+
 ## Version 1.0.1
 
 ### Fix