Ver código fonte

Automatically switch protocol versions to find the best one

There are two protocol versions that Goldair devices may use. Rather
than requiring that the user know which one and put it in the config, a
more automatic solution is to just switch the version when there is a
communication error. There may be some false positives when network
connectivity is low, but it's a much nicer solution than putting it on
the user.
Nik Rolls 6 anos atrás
pai
commit
4ac9a49cba
2 arquivos alterados com 23 adições e 4 exclusões
  1. 22 3
      custom_components/goldair_climate/__init__.py
  2. 1 1
      custom_updater.json

+ 22 - 3
custom_components/goldair_climate/__init__.py

@@ -15,13 +15,15 @@ import homeassistant.helpers.config_validation as cv
 from homeassistant.const import (CONF_NAME, CONF_HOST, TEMP_CELSIUS)
 from homeassistant.const import (CONF_NAME, CONF_HOST, TEMP_CELSIUS)
 from homeassistant.helpers.discovery import load_platform
 from homeassistant.helpers.discovery import load_platform
 
 
-VERSION = '0.0.6'
+VERSION = '0.0.7'
 
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER = logging.getLogger(__name__)
 
 
 DOMAIN = 'goldair_climate'
 DOMAIN = 'goldair_climate'
 DATA_GOLDAIR_CLIMATE = 'data_goldair_climate'
 DATA_GOLDAIR_CLIMATE = 'data_goldair_climate'
 
 
+API_PROTOCOL_VERSIONS = [3.3, 3.1]
+
 CONF_DEVICE_ID = 'device_id'
 CONF_DEVICE_ID = 'device_id'
 CONF_LOCAL_KEY = 'local_key'
 CONF_LOCAL_KEY = 'local_key'
 CONF_TYPE = 'type'
 CONF_TYPE = 'type'
@@ -83,7 +85,9 @@ class GoldairTuyaDevice(object):
         """
         """
         import pytuya
         import pytuya
         self._name = name
         self._name = name
+        self._api_protocol_version_index = None
         self._api = pytuya.Device(dev_id, address, local_key, 'device')
         self._api = pytuya.Device(dev_id, address, local_key, 'device')
+        self._rotate_api_protocol_version()
 
 
         self._fixed_properties = {}
         self._fixed_properties = {}
         self._reset_cached_state()
         self._reset_cached_state()
@@ -97,7 +101,7 @@ class GoldairTuyaDevice(object):
         # onto the state while we wait for the board to update its switches.
         # onto the state while we wait for the board to update its switches.
         self._FAKE_IT_TIL_YOU_MAKE_IT_TIMEOUT = 10
         self._FAKE_IT_TIL_YOU_MAKE_IT_TIMEOUT = 10
         self._CACHE_TIMEOUT = 20
         self._CACHE_TIMEOUT = 20
-        self._CONNECTION_ATTEMPTS = 2
+        self._CONNECTION_ATTEMPTS = 4
         self._lock = Lock()
         self._lock = Lock()
 
 
     @property
     @property
@@ -118,7 +122,7 @@ class GoldairTuyaDevice(object):
         cached_state = self._get_cached_state()
         cached_state = self._get_cached_state()
         if now - cached_state['updated_at'] >= self._CACHE_TIMEOUT:
         if now - cached_state['updated_at'] >= self._CACHE_TIMEOUT:
             self._cached_state['updated_at'] = time()
             self._cached_state['updated_at'] = time()
-            self._retry_on_failed_connection(lambda: self._refresh_cached_state(), 'Failed to refresh device state.')
+            self._retry_on_failed_connection(lambda: self._refresh_cached_state(), 'Failed to refresh device state for {self.name}.')
 
 
     def get_property(self, dps_id):
     def get_property(self, dps_id):
         cached_state = self._get_cached_state()
         cached_state = self._get_cached_state()
@@ -208,6 +212,8 @@ class GoldairTuyaDevice(object):
                 if i + 1 == self._CONNECTION_ATTEMPTS:
                 if i + 1 == self._CONNECTION_ATTEMPTS:
                     self._reset_cached_state()
                     self._reset_cached_state()
                     _LOGGER.error(error_message)
                     _LOGGER.error(error_message)
+                else:
+                    self._rotate_api_protocol_version()
 
 
     def _get_cached_state(self):
     def _get_cached_state(self):
         cached_state = self._cached_state.copy()
         cached_state = self._cached_state.copy()
@@ -223,6 +229,19 @@ class GoldairTuyaDevice(object):
                                  if now - value['updated_at'] < self._FAKE_IT_TIL_YOU_MAKE_IT_TIMEOUT}
                                  if now - value['updated_at'] < self._FAKE_IT_TIL_YOU_MAKE_IT_TIMEOUT}
         return self._pending_updates
         return self._pending_updates
 
 
+    def _rotate_api_protocol_version(self):
+        if self._api_protocol_version_index is None:
+            self._api_protocol_version_index = 0
+        else:
+            self._api_protocol_version_index += 1
+
+        if self._api_protocol_version_index >= len(API_PROTOCOL_VERSIONS):
+            self._api_protocol_version_index = 0
+
+        new_version = API_PROTOCOL_VERSIONS[self._api_protocol_version_index]
+        _LOGGER.info(f'Setting protocol version for {self.name} to {new_version}')
+        self._api.set_version(new_version)
+
     @staticmethod
     @staticmethod
     def get_key_for_value(obj, value):
     def get_key_for_value(obj, value):
         keys = list(obj.keys())
         keys = list(obj.keys())

+ 1 - 1
custom_updater.json

@@ -1,6 +1,6 @@
 {
 {
     "goldair_climate": {
     "goldair_climate": {
-        "version": "0.0.6",
+        "version": "0.0.7",
         "local_location": "/custom_components/goldair_climate/__init__.py",
         "local_location": "/custom_components/goldair_climate/__init__.py",
         "remote_location": "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/__init__.py",
         "remote_location": "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/__init__.py",
         "visit_repo": "https://github.com/nikrolls/homeassistant-goldair-climate",
         "visit_repo": "https://github.com/nikrolls/homeassistant-goldair-climate",