mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Improve stability of netatmo sensor (#24190)
* Improve stability of netatmo sensor * Improve stability of netatmo sensor * Improve stability of netatmo sensor * netatmo, except timeout * netatmo, except timeout * netatmo, except timeout * netatmo, except timeout * Always release lock
This commit is contained in:
parent
9aeb75f28d
commit
b0e6f34976
@ -1,20 +1,21 @@
|
|||||||
"""Support for the Netatmo Weather Service."""
|
"""Support for the Netatmo Weather Service."""
|
||||||
from datetime import timedelta
|
|
||||||
import logging
|
import logging
|
||||||
from time import time
|
|
||||||
import threading
|
import threading
|
||||||
|
from datetime import timedelta
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
import requests
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_NAME, CONF_MODE, CONF_MONITORED_CONDITIONS,
|
CONF_NAME, CONF_MODE, CONF_MONITORED_CONDITIONS,
|
||||||
TEMP_CELSIUS, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE,
|
TEMP_CELSIUS, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE,
|
||||||
DEVICE_CLASS_BATTERY)
|
DEVICE_CLASS_BATTERY)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
import homeassistant.helpers.config_validation as cv
|
from homeassistant.helpers.event import call_later
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
|
|
||||||
from .const import DATA_NETATMO_AUTH
|
from .const import DATA_NETATMO_AUTH
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -101,7 +102,6 @@ MODULE_TYPE_INDOOR = 'NAModule4'
|
|||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
"""Set up the available Netatmo weather sensors."""
|
"""Set up the available Netatmo weather sensors."""
|
||||||
dev = []
|
dev = []
|
||||||
not_handled = {}
|
|
||||||
auth = hass.data[DATA_NETATMO_AUTH]
|
auth = hass.data[DATA_NETATMO_AUTH]
|
||||||
|
|
||||||
if config.get(CONF_AREAS) is not None:
|
if config.get(CONF_AREAS) is not None:
|
||||||
@ -121,45 +121,55 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
area[CONF_MODE]
|
area[CONF_MODE]
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
for data_class in all_product_classes():
|
def _retry(_data):
|
||||||
|
try:
|
||||||
|
_dev = find_devices(_data)
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
return call_later(hass, NETATMO_UPDATE_INTERVAL,
|
||||||
|
lambda _: _retry(_data))
|
||||||
|
if _dev:
|
||||||
|
add_entities(_dev, True)
|
||||||
|
|
||||||
|
import pyatmo
|
||||||
|
for data_class in [pyatmo.WeatherStationData, pyatmo.HomeCoachData]:
|
||||||
data = NetatmoData(auth, data_class, config.get(CONF_STATION))
|
data = NetatmoData(auth, data_class, config.get(CONF_STATION))
|
||||||
module_items = []
|
|
||||||
# Test if manually configured
|
# Test if manually configured
|
||||||
if CONF_MODULES in config:
|
if CONF_MODULES in config:
|
||||||
module_items = config[CONF_MODULES].items()
|
module_items = config[CONF_MODULES].items()
|
||||||
else:
|
|
||||||
# otherwise add all modules and conditions
|
|
||||||
for module_name in data.get_module_names():
|
|
||||||
monitored_conditions = \
|
|
||||||
data.station_data.monitoredConditions(module_name)
|
|
||||||
module_items.append(
|
|
||||||
(module_name, monitored_conditions))
|
|
||||||
|
|
||||||
for module_name, monitored_conditions in module_items:
|
for module_name, monitored_conditions in module_items:
|
||||||
# Test if module exists
|
|
||||||
if module_name not in data.get_module_names():
|
|
||||||
not_handled[module_name] = \
|
|
||||||
not_handled[module_name]+1 \
|
|
||||||
if module_name in not_handled else 1
|
|
||||||
else:
|
|
||||||
# Only create sensors for monitored properties
|
|
||||||
for condition in monitored_conditions:
|
for condition in monitored_conditions:
|
||||||
dev.append(NetatmoSensor(
|
dev.append(NetatmoSensor(
|
||||||
data, module_name, condition.lower(),
|
data, module_name, condition.lower(),
|
||||||
config.get(CONF_STATION)))
|
config.get(CONF_STATION)))
|
||||||
|
continue
|
||||||
|
|
||||||
for module_name, _ in not_handled.items():
|
# otherwise add all modules and conditions
|
||||||
_LOGGER.error('Module name: "%s" not found', module_name)
|
try:
|
||||||
|
dev.extend(find_devices(data))
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
call_later(hass, NETATMO_UPDATE_INTERVAL,
|
||||||
|
lambda _: _retry(data))
|
||||||
|
|
||||||
if dev:
|
if dev:
|
||||||
add_entities(dev, True)
|
add_entities(dev, True)
|
||||||
|
|
||||||
|
|
||||||
def all_product_classes():
|
def find_devices(data):
|
||||||
"""Provide all handled Netatmo product classes."""
|
"""Find all devices."""
|
||||||
import pyatmo
|
dev = []
|
||||||
|
not_handled = []
|
||||||
|
for module_name in data.get_module_names():
|
||||||
|
if (module_name not in data.get_module_names()
|
||||||
|
and module_name not in not_handled):
|
||||||
|
not_handled.append(not_handled)
|
||||||
|
continue
|
||||||
|
for condition in data.station_data.monitoredConditions(module_name):
|
||||||
|
dev.append(NetatmoSensor(
|
||||||
|
data, module_name, condition.lower(), data.station))
|
||||||
|
|
||||||
return [pyatmo.WeatherStationData, pyatmo.HomeCoachData]
|
for module_name in not_handled:
|
||||||
|
_LOGGER.error('Module name: "%s" not found', module_name)
|
||||||
|
return dev
|
||||||
|
|
||||||
|
|
||||||
class NetatmoSensor(Entity):
|
class NetatmoSensor(Entity):
|
||||||
@ -515,22 +525,6 @@ class NetatmoData:
|
|||||||
self.update()
|
self.update()
|
||||||
return self.data.keys()
|
return self.data.keys()
|
||||||
|
|
||||||
def _detect_platform_type(self):
|
|
||||||
"""Return the XXXData object corresponding to the specified platform.
|
|
||||||
|
|
||||||
The return can be a WeatherStationData or a HomeCoachData.
|
|
||||||
"""
|
|
||||||
from pyatmo import NoDevice
|
|
||||||
try:
|
|
||||||
station_data = self.data_class(self.auth)
|
|
||||||
_LOGGER.debug("%s detected!", str(self.data_class.__name__))
|
|
||||||
return station_data
|
|
||||||
except NoDevice:
|
|
||||||
_LOGGER.warning("No Weather or HomeCoach devices found for %s",
|
|
||||||
str(self.station)
|
|
||||||
)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Call the Netatmo API to update the data.
|
"""Call the Netatmo API to update the data.
|
||||||
|
|
||||||
@ -541,14 +535,20 @@ class NetatmoData:
|
|||||||
if time() < self._next_update or \
|
if time() < self._next_update or \
|
||||||
not self._update_in_progress.acquire(False):
|
not self._update_in_progress.acquire(False):
|
||||||
return
|
return
|
||||||
|
try:
|
||||||
from pyatmo import NoDevice
|
from pyatmo import NoDevice
|
||||||
try:
|
try:
|
||||||
self.station_data = self._detect_platform_type()
|
self.station_data = self.data_class(self.auth)
|
||||||
|
_LOGGER.debug("%s detected!", str(self.data_class.__name__))
|
||||||
except NoDevice:
|
except NoDevice:
|
||||||
|
_LOGGER.warning("No Weather or HomeCoach devices found for %s",
|
||||||
|
str(self.station)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
_LOGGER.warning("Timed out when connecting to Netatmo server.")
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
if self.station is not None:
|
if self.station is not None:
|
||||||
data = self.station_data.lastData(
|
data = self.station_data.lastData(
|
||||||
station=self.station, exclude=3600)
|
station=self.station, exclude=3600)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user