Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Mi Flora median calculation #16085

Merged
merged 9 commits into from
Sep 4, 2018
38 changes: 21 additions & 17 deletions homeassistant/components/sensor/miflora.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,34 @@
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.miflora/
"""
import asyncio
from datetime import timedelta
import logging

import voluptuous as vol
import async_timeout

from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.helpers.entity import Entity
import homeassistant.helpers.config_validation as cv
from homeassistant.exceptions import PlatformNotReady
from homeassistant.const import (
CONF_FORCE_UPDATE, CONF_MONITORED_CONDITIONS, CONF_NAME, CONF_MAC
)
CONF_FORCE_UPDATE, CONF_MONITORED_CONDITIONS, CONF_NAME, CONF_MAC,
CONF_SCAN_INTERVAL)


REQUIREMENTS = ['miflora==0.4.0']

_LOGGER = logging.getLogger(__name__)

CONF_ADAPTER = 'adapter'
CONF_CACHE = 'cache_value'
CONF_MEDIAN = 'median'
CONF_RETRIES = 'retries'
CONF_TIMEOUT = 'timeout'

DEFAULT_ADAPTER = 'hci0'
DEFAULT_UPDATE_INTERVAL = 1200
DEFAULT_FORCE_UPDATE = False
DEFAULT_MEDIAN = 3
DEFAULT_NAME = 'Mi Flora'
DEFAULT_RETRIES = 2
DEFAULT_TIMEOUT = 10

SCAN_INTERVAL = timedelta(seconds=1200)

# Sensor types are defined like: Name, units
SENSOR_TYPES = {
Expand All @@ -51,14 +49,12 @@
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_MEDIAN, default=DEFAULT_MEDIAN): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_RETRIES, default=DEFAULT_RETRIES): cv.positive_int,
vol.Optional(CONF_CACHE, default=DEFAULT_UPDATE_INTERVAL): cv.positive_int,
vol.Optional(CONF_ADAPTER, default=DEFAULT_ADAPTER): cv.string,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the MiFlora sensor."""
from miflora import miflora_poller
try:
Expand All @@ -70,17 +66,22 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
backend = GatttoolBackend
_LOGGER.debug('Miflora is using %s backend.', backend.__name__)

cache = config.get(CONF_CACHE)
cache = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL).total_seconds()
poller = miflora_poller.MiFloraPoller(
config.get(CONF_MAC), cache_timeout=cache,
adapter=config.get(CONF_ADAPTER), backend=backend)
force_update = config.get(CONF_FORCE_UPDATE)
median = config.get(CONF_MEDIAN)
poller.ble_timeout = config.get(CONF_TIMEOUT)
poller.retries = config.get(CONF_RETRIES)

devs = []

try:
with async_timeout.timeout(9):
await hass.async_add_executor_job(poller.fill_cache)
except asyncio.TimeoutError:
_LOGGER.error('Unable to connect to %s', config.get(CONF_MAC))
raise PlatformNotReady

for parameter in config[CONF_MONITORED_CONDITIONS]:
name = SENSOR_TYPES[parameter][0]
unit = SENSOR_TYPES[parameter][1]
Expand All @@ -92,7 +93,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
devs.append(MiFloraSensor(
poller, parameter, name, unit, force_update, median))

add_entities(devs)
async_add_entities(devs, update_before_add=True)


class MiFloraSensor(Entity):
Expand Down Expand Up @@ -171,5 +172,8 @@ def update(self):
median = sorted(self.data)[int((self.median_count - 1) / 2)]
_LOGGER.debug("Median is: %s", median)
self._state = median
elif self._state is None:
_LOGGER.debug("Set initial state")
self._state = self.data[0]
else:
_LOGGER.debug("Not yet enough data for median calculation")