-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ecoal (esterownik.pl) static fuel boiler and pump controller (#18480)…
… - matkor * Starting work on ecoal boiler controller iface. * Sending some values/states to controller. * Basic status parsing, and simple settings. * Platform configuration. * Temp sensors seems be working. * Switch from separate h/m/s to datetime. * Vocabulary updates. * secondary_central_heating_pump -> central_heating_pump2 * Pumps as switches. * Optional enabling pumps via config. * requests==2.20.1 added to REQUIREMENTS. * Optional enabling temp sensors from configuration yaml. * autopep8, black, pylint. * flake8. * pydocstyle * All style checkers again. * requests==2.20.1 required by homeassistant.components.sensor.ecoal_boiler. * Verify / set switches in update(). Code cleanup. * script/lint + travis issues. * Cleanup, imperative mood. * pylint, travis. * Updated .coveragerc. * Using configuration consts from homeassistant.const * typo. * Replace global ECOAL_CONTR with hass.data[DATA_ECOAL_BOILER]. Remove requests from REQUIREMENTS. * Killed .update()/reread_update() in Entities __init__()s. Removed debug/comments. * Removed debug/comments. * script/lint fixes. * script/gen_requirements_all.py run. * Travis fixes. * Configuration now validated. * Split controller code to separate package. * Replace in module docs with link to https://home-assistant.io . * Correct component module path in .coveragerc. More vals from const.py. Use dict[key] for required config keys. Check if credentials are correct during component setup. Renamed add_devices to add_entities. * Sensor/switch depends on ecoal_boiler component. EcoalSwitch inherits from SwitchDevice. Killed same as default should_poll(). Remove not neede schedule_update_ha_state() calls from turn_on/off. * lint fixes. * Move sensors/switches configuration to component setup. * Lint fixes. * Invalidating ecoal iface cache instead of force read in turn_on/off(). * Fail component setup before adding any platform entities. Kill NOTE. * Disallow setting entity names from config file, use code defined default names. * Rework configuration file to use monitored_conditions like in rainmachine component. * Killed pylint exception. Log error when connection to controller fails. * A few fixes. * Linted.
- Loading branch information
1 parent
f84c0ee
commit 9b7780e
Showing
5 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
""" | ||
Component to control ecoal/esterownik.pl coal/wood boiler controller. | ||
For more details about this component, please refer to the documentation at | ||
https://home-assistant.io/components/ecoal_boiler/ | ||
""" | ||
import logging | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant.const import (CONF_HOST, CONF_PASSWORD, CONF_USERNAME, | ||
CONF_MONITORED_CONDITIONS, CONF_SENSORS, | ||
CONF_SWITCHES) | ||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.helpers.discovery import load_platform | ||
|
||
REQUIREMENTS = ['ecoaliface==0.4.0'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DOMAIN = "ecoal_boiler" | ||
DATA_ECOAL_BOILER = 'data_' + DOMAIN | ||
|
||
DEFAULT_USERNAME = "admin" | ||
DEFAULT_PASSWORD = "admin" | ||
|
||
|
||
# Available pump ids with assigned HA names | ||
# Available as switches | ||
AVAILABLE_PUMPS = { | ||
"central_heating_pump": "Central heating pump", | ||
"central_heating_pump2": "Central heating pump2", | ||
"domestic_hot_water_pump": "Domestic hot water pump", | ||
} | ||
|
||
# Available temp sensor ids with assigned HA names | ||
# Available as sensors | ||
AVAILABLE_SENSORS = { | ||
"outdoor_temp": 'Outdoor temperature', | ||
"indoor_temp": 'Indoor temperature', | ||
"indoor2_temp": 'Indoor temperature 2', | ||
"domestic_hot_water_temp": 'Domestic hot water temperature', | ||
"target_domestic_hot_water_temp": 'Target hot water temperature', | ||
"feedwater_in_temp": 'Feedwater input temperature', | ||
"feedwater_out_temp": 'Feedwater output temperature', | ||
"target_feedwater_temp": 'Target feedwater temperature', | ||
"fuel_feeder_temp": 'Fuel feeder temperature', | ||
"exhaust_temp": 'Exhaust temperature', | ||
} | ||
|
||
SWITCH_SCHEMA = vol.Schema({ | ||
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(AVAILABLE_PUMPS)): | ||
vol.All(cv.ensure_list, [vol.In(AVAILABLE_PUMPS)]) | ||
}) | ||
|
||
SENSOR_SCHEMA = vol.Schema({ | ||
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(AVAILABLE_SENSORS)): | ||
vol.All(cv.ensure_list, [vol.In(AVAILABLE_SENSORS)]) | ||
}) | ||
|
||
CONFIG_SCHEMA = vol.Schema({ | ||
DOMAIN: vol.Schema({ | ||
vol.Required(CONF_HOST): cv.string, | ||
vol.Optional(CONF_USERNAME, | ||
default=DEFAULT_USERNAME): cv.string, | ||
vol.Optional(CONF_PASSWORD, | ||
default=DEFAULT_PASSWORD): cv.string, | ||
vol.Optional(CONF_SWITCHES, default={}): SWITCH_SCHEMA, | ||
vol.Optional(CONF_SENSORS, default={}): SENSOR_SCHEMA, | ||
}) | ||
}, extra=vol.ALLOW_EXTRA) | ||
|
||
|
||
def setup(hass, hass_config): | ||
"""Set up global ECoalController instance same for sensors and switches.""" | ||
from ecoaliface.simple import ECoalController | ||
|
||
conf = hass_config[DOMAIN] | ||
host = conf[CONF_HOST] | ||
username = conf[CONF_USERNAME] | ||
passwd = conf[CONF_PASSWORD] | ||
# Creating ECoalController instance makes HTTP request to controller. | ||
ecoal_contr = ECoalController(host, username, passwd) | ||
if ecoal_contr.version is None: | ||
# Wrong credentials nor network config | ||
_LOGGER.error("Unable to read controller status from %s@%s" | ||
" (wrong host/credentials)", username, host, ) | ||
return False | ||
_LOGGER.debug("Detected controller version: %r @%s", | ||
ecoal_contr.version, host, ) | ||
hass.data[DATA_ECOAL_BOILER] = ecoal_contr | ||
# Setup switches | ||
switches = conf[CONF_SWITCHES][CONF_MONITORED_CONDITIONS] | ||
load_platform(hass, 'switch', DOMAIN, switches, hass_config) | ||
# Setup temp sensors | ||
sensors = conf[CONF_SENSORS][CONF_MONITORED_CONDITIONS] | ||
load_platform(hass, 'sensor', DOMAIN, sensors, hass_config) | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
Allows reading temperatures from ecoal/esterownik.pl controller. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/sensor.ecoal_boiler/ | ||
""" | ||
import logging | ||
|
||
from homeassistant.components.ecoal_boiler import ( | ||
DATA_ECOAL_BOILER, AVAILABLE_SENSORS, ) | ||
from homeassistant.const import TEMP_CELSIUS | ||
from homeassistant.helpers.entity import Entity | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DEPENDENCIES = ['ecoal_boiler'] | ||
|
||
|
||
def setup_platform(hass, config, add_entities, discovery_info=None): | ||
"""Set up the ecoal sensors.""" | ||
if discovery_info is None: | ||
return | ||
devices = [] | ||
ecoal_contr = hass.data[DATA_ECOAL_BOILER] | ||
for sensor_id in discovery_info: | ||
name = AVAILABLE_SENSORS[sensor_id] | ||
devices.append(EcoalTempSensor(ecoal_contr, name, sensor_id)) | ||
add_entities(devices, True) | ||
|
||
|
||
class EcoalTempSensor(Entity): | ||
"""Representation of a temperature sensor using ecoal status data.""" | ||
|
||
def __init__(self, ecoal_contr, name, status_attr): | ||
"""Initialize the sensor.""" | ||
self._ecoal_contr = ecoal_contr | ||
self._name = name | ||
self._status_attr = status_attr | ||
self._state = None | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the sensor.""" | ||
return self._name | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the sensor.""" | ||
return self._state | ||
|
||
@property | ||
def unit_of_measurement(self): | ||
"""Return the unit of measurement.""" | ||
return TEMP_CELSIUS | ||
|
||
def update(self): | ||
"""Fetch new state data for the sensor. | ||
This is the only method that should fetch new data for Home Assistant. | ||
""" | ||
# Old values read 0.5 back can still be used | ||
status = self._ecoal_contr.get_cached_status() | ||
self._state = getattr(status, self._status_attr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
""" | ||
Allows to configuration ecoal (esterownik.pl) pumps as switches. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/switch.ecoal_boiler/ | ||
""" | ||
import logging | ||
from typing import Optional | ||
|
||
from homeassistant.components.switch import SwitchDevice | ||
from homeassistant.components.ecoal_boiler import ( | ||
DATA_ECOAL_BOILER, AVAILABLE_PUMPS, ) | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DEPENDENCIES = ['ecoal_boiler'] | ||
|
||
|
||
def setup_platform(hass, config, add_entities, discovery_info=None): | ||
"""Set up switches based on ecoal interface.""" | ||
if discovery_info is None: | ||
return | ||
ecoal_contr = hass.data[DATA_ECOAL_BOILER] | ||
switches = [] | ||
for pump_id in discovery_info: | ||
name = AVAILABLE_PUMPS[pump_id] | ||
switches.append(EcoalSwitch(ecoal_contr, name, pump_id)) | ||
add_entities(switches, True) | ||
|
||
|
||
class EcoalSwitch(SwitchDevice): | ||
"""Representation of Ecoal switch.""" | ||
|
||
def __init__(self, ecoal_contr, name, state_attr): | ||
""" | ||
Initialize switch. | ||
Sets HA switch to state as read from controller. | ||
""" | ||
self._ecoal_contr = ecoal_contr | ||
self._name = name | ||
self._state_attr = state_attr | ||
# Ecoalcotroller holds convention that same postfix is used | ||
# to set attribute | ||
# set_<attr>() | ||
# as attribute name in status instance: | ||
# status.<attr> | ||
self._contr_set_fun = getattr(self._ecoal_contr, "set_" + state_attr) | ||
# No value set, will be read from controller instead | ||
self._state = None | ||
|
||
@property | ||
def name(self) -> Optional[str]: | ||
"""Return the name of the switch.""" | ||
return self._name | ||
|
||
def update(self): | ||
"""Fetch new state data for the sensor. | ||
This is the only method that should fetch new data for Home Assistant. | ||
""" | ||
status = self._ecoal_contr.get_cached_status() | ||
self._state = getattr(status, self._state_attr) | ||
|
||
def invalidate_ecoal_cache(self): | ||
"""Invalidate ecoal interface cache. | ||
Forces that next read from ecaol interface to not use cache. | ||
""" | ||
self._ecoal_contr.status = None | ||
|
||
@property | ||
def is_on(self) -> bool: | ||
"""Return true if device is on.""" | ||
return self._state | ||
|
||
def turn_on(self, **kwargs) -> None: | ||
"""Turn the device on.""" | ||
self._contr_set_fun(1) | ||
self.invalidate_ecoal_cache() | ||
|
||
def turn_off(self, **kwargs) -> None: | ||
"""Turn the device off.""" | ||
self._contr_set_fun(0) | ||
self.invalidate_ecoal_cache() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters