From 7a52bbdf241ce5f79f49633a17b8bb404abd9f13 Mon Sep 17 00:00:00 2001
From: Alexei Chetroi <lexoid@gmail.com>
Date: Thu, 13 Sep 2018 03:22:50 -0400
Subject: [PATCH] Allow only_cache parameter in zha.safe_read() (#16553)

* Allow only_cache parameter in zha.safe_read()

* Use cache_only for binary_sensor.zha initial update.

* Use cache_only for fan.zha initial update.

* Use cache_only for sensor.zha initial update.

* Use cache_only for switch.zha initial update.

* Use cache_only for light.zha initial update.

* Refactor cached only read in zha platform.
---
 homeassistant/components/binary_sensor/zha.py |  3 ++-
 homeassistant/components/fan/zha.py           |  4 +++-
 homeassistant/components/light/zha.py         | 16 ++++++++++++----
 homeassistant/components/sensor/zha.py        |  9 +++++----
 homeassistant/components/switch/zha.py        |  4 +++-
 homeassistant/components/zha/__init__.py      |  6 +++++-
 6 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/homeassistant/components/binary_sensor/zha.py b/homeassistant/components/binary_sensor/zha.py
index 0842ab7db6e..aa07a673c97 100644
--- a/homeassistant/components/binary_sensor/zha.py
+++ b/homeassistant/components/binary_sensor/zha.py
@@ -132,7 +132,8 @@ class BinarySensor(zha.Entity, BinarySensorDevice):
 
         result = await zha.safe_read(self._endpoint.ias_zone,
                                      ['zone_status'],
-                                     allow_cache=False)
+                                     allow_cache=False,
+                                     only_cache=(not self._initialized))
         state = result.get('zone_status', self._state)
         if isinstance(state, (int, uint16_t)):
             self._state = result.get('zone_status', self._state) & 3
diff --git a/homeassistant/components/fan/zha.py b/homeassistant/components/fan/zha.py
index d86e0c3c99b..b5615f18d73 100644
--- a/homeassistant/components/fan/zha.py
+++ b/homeassistant/components/fan/zha.py
@@ -101,7 +101,9 @@ class ZhaFan(zha.Entity, FanEntity):
 
     async def async_update(self):
         """Retrieve latest state."""
-        result = await zha.safe_read(self._endpoint.fan, ['fan_mode'])
+        result = await zha.safe_read(self._endpoint.fan, ['fan_mode'],
+                                     allow_cache=False,
+                                     only_cache=(not self._initialized))
         new_value = result.get('fan_mode', None)
         self._state = VALUE_TO_SPEED.get(new_value, None)
 
diff --git a/homeassistant/components/light/zha.py b/homeassistant/components/light/zha.py
index dc5c4977944..dd675ee674d 100644
--- a/homeassistant/components/light/zha.py
+++ b/homeassistant/components/light/zha.py
@@ -154,23 +154,31 @@ class Light(zha.Entity, light.Light):
 
     async def async_update(self):
         """Retrieve latest state."""
-        result = await zha.safe_read(self._endpoint.on_off, ['on_off'])
+        result = await zha.safe_read(self._endpoint.on_off, ['on_off'],
+                                     allow_cache=False,
+                                     only_cache=(not self._initialized))
         self._state = result.get('on_off', self._state)
 
         if self._supported_features & light.SUPPORT_BRIGHTNESS:
             result = await zha.safe_read(self._endpoint.level,
-                                         ['current_level'])
+                                         ['current_level'],
+                                         allow_cache=False,
+                                         only_cache=(not self._initialized))
             self._brightness = result.get('current_level', self._brightness)
 
         if self._supported_features & light.SUPPORT_COLOR_TEMP:
             result = await zha.safe_read(self._endpoint.light_color,
-                                         ['color_temperature'])
+                                         ['color_temperature'],
+                                         allow_cache=False,
+                                         only_cache=(not self._initialized))
             self._color_temp = result.get('color_temperature',
                                           self._color_temp)
 
         if self._supported_features & light.SUPPORT_COLOR:
             result = await zha.safe_read(self._endpoint.light_color,
-                                         ['current_x', 'current_y'])
+                                         ['current_x', 'current_y'],
+                                         allow_cache=False,
+                                         only_cache=(not self._initialized))
             if 'current_x' in result and 'current_y' in result:
                 xy_color = (round(result['current_x']/65535, 3),
                             round(result['current_y']/65535, 3))
diff --git a/homeassistant/components/sensor/zha.py b/homeassistant/components/sensor/zha.py
index 0a6710f8f6c..9962270dfd7 100644
--- a/homeassistant/components/sensor/zha.py
+++ b/homeassistant/components/sensor/zha.py
@@ -95,7 +95,9 @@ class Sensor(zha.Entity):
         """Retrieve latest state."""
         result = await zha.safe_read(
             list(self._in_clusters.values())[0],
-            [self.value_attribute]
+            [self.value_attribute],
+            allow_cache=False,
+            only_cache=(not self._initialized)
         )
         self._state = result.get(self.value_attribute, self._state)
 
@@ -224,7 +226,6 @@ class ElectricalMeasurementSensor(Sensor):
         _LOGGER.debug("%s async_update", self.entity_id)
 
         result = await zha.safe_read(
-            self._endpoint.electrical_measurement,
-            ['active_power'],
-            allow_cache=False)
+            self._endpoint.electrical_measurement, ['active_power'],
+            allow_cache=False, only_cache=(not self._initialized))
         self._state = result.get('active_power', self._state)
diff --git a/homeassistant/components/switch/zha.py b/homeassistant/components/switch/zha.py
index 7ac93180cd7..4fde3565348 100644
--- a/homeassistant/components/switch/zha.py
+++ b/homeassistant/components/switch/zha.py
@@ -86,5 +86,7 @@ class Switch(zha.Entity, SwitchDevice):
     async def async_update(self):
         """Retrieve latest state."""
         result = await zha.safe_read(self._endpoint.on_off,
-                                     ['on_off'])
+                                     ['on_off'],
+                                     allow_cache=False,
+                                     only_cache=(not self._initialized))
         self._state = result.get('on_off', self._state)
diff --git a/homeassistant/components/zha/__init__.py b/homeassistant/components/zha/__init__.py
index 4c1109f685d..f6b5868ff81 100644
--- a/homeassistant/components/zha/__init__.py
+++ b/homeassistant/components/zha/__init__.py
@@ -336,6 +336,7 @@ class Entity(entity.Entity):
         self._in_listeners = {}
         self._out_listeners = {}
 
+        self._initialized = False
         application_listener.register_entity(ieee, self)
 
     async def async_added_to_hass(self):
@@ -348,6 +349,8 @@ class Entity(entity.Entity):
         for cluster_id, cluster in self._out_clusters.items():
             cluster.add_listener(self._out_listeners.get(cluster_id, self))
 
+        self._initialized = True
+
     @property
     def unique_id(self) -> str:
         """Return a unique ID."""
@@ -384,7 +387,7 @@ def get_discovery_info(hass, discovery_info):
     return all_discovery_info.get(discovery_key, None)
 
 
-async def safe_read(cluster, attributes, allow_cache=True):
+async def safe_read(cluster, attributes, allow_cache=True, only_cache=False):
     """Swallow all exceptions from network read.
 
     If we throw during initialization, setup fails. Rather have an entity that
@@ -395,6 +398,7 @@ async def safe_read(cluster, attributes, allow_cache=True):
         result, _ = await cluster.read_attributes(
             attributes,
             allow_cache=allow_cache,
+            only_cache=only_cache
         )
         return result
     except Exception:  # pylint: disable=broad-except
-- 
GitLab