Files
solar-display/server/apsystems_ecur/__init__.py
T

155 lines
4.4 KiB
Python
Executable File

import logging
import voluptuous as vol
import traceback
from datetime import timedelta
from .APSystemsECUR import APSystemsECUR, APSystemsInvalidData
from homeassistant.helpers.discovery import load_platform
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_HOST
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
UpdateFailed,
)
_LOGGER = logging.getLogger(__name__)
from .const import DOMAIN
CONF_INTERVAL = "interval"
CONFIG_SCHEMA = vol.Schema({
DOMAIN : vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_INTERVAL) : cv.time_period_seconds
})
}, extra=vol.ALLOW_EXTRA)
PLATFORMS = [ "sensor", "binary_sensor" ]
## handle all the communications with the ECUR class and deal with our need for caching, etc
class ECUR():
def __init__(self, ipaddr):
self.ecu = APSystemsECUR(ipaddr)
self.cache_count = 0
self.cache_max = 5
self.data_from_cache = False
self.querying = True
self.error_messge = ""
self.cached_data = {}
async def stop_query(self):
self.querying = False
async def start_query(self):
self.querying = True
async def update(self):
data = {}
# if we aren't actively quering data, pull data form the cache
# this is so we can stop querying after sunset
if not self.querying:
_LOGGER.debug("Not querying ECU due to stopped")
data = self.cached_data
self.data_from_cache = True
data["data_from_cache"] = self.data_from_cache
data["querying"] = self.querying
return self.cached_data
_LOGGER.debug("Querying ECU")
try:
data = await self.ecu.async_query_ecu()
_LOGGER.debug("Got data from ECU")
# we got good results, so we store it and set flags about our
# cache state
self.cached_data = data
self.cache_count = 0
self.data_from_cache = False
self.error_message = ""
except APSystemsInvalidData as err:
msg = f"Using cached data from last successful communication from ECU. Error: {err}"
_LOGGER.warning(msg)
# we got invalid data, so we need to pull from cache
self.error_msg = msg
self.cache_count += 1
self.data_from_cache = True
data = self.cached_data
if self.cache_count > self.cache_max:
raise Exception(f"Error using cached data for more than {self.cache_max} times.")
except Exception as err:
msg = f"Using cached data from last successful communication from ECU. Error: {err}"
_LOGGER.warning(msg)
# we got invalid data, so we need to pull from cache
self.error_msg = msg
self.cache_count += 1
self.data_from_cache = True
data = self.cached_data
if self.cache_count > self.cache_max:
raise Exception(f"Error using cached data for more than {self.cache_max} times.")
data["data_from_cache"] = self.data_from_cache
data["querying"] = self.querying
_LOGGER.debug(f"Returning {data}")
return data
async def async_setup(hass, config):
""" Setup the APsystems platform """
hass.data.setdefault(DOMAIN, {})
host = config[DOMAIN].get(CONF_HOST)
interval = config[DOMAIN].get(CONF_INTERVAL)
if not interval:
interval = timedelta(seconds=60)
ecu = ECUR(host)
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name=DOMAIN,
update_method=ecu.update,
update_interval=interval,
)
await coordinator.async_refresh()
hass.data[DOMAIN] = {
"ecu" : ecu,
"coordinator" : coordinator
}
async def handle_stop_query(call):
await ecu.stop_query()
coordinator.async_refresh()
async def handle_start_query(call):
await ecu.start_query()
coordinator.async_refresh()
hass.services.async_register(DOMAIN, "start_query", handle_start_query)
hass.services.async_register(DOMAIN, "stop_query", handle_stop_query)
for component in PLATFORMS:
load_platform(hass, component, DOMAIN, {}, config)
return True