Make homematic climate dynamic for datapoints. (#5993)
* Make homematic climate dynamic for datapoints. * Code cleanup * Add more option * add options * Pump version 0.1.22 * optimazepull/6006/head
parent
039559882b
commit
80bc2666ac
|
@ -56,9 +56,6 @@ class HMBinarySensor(HMDevice, BinarySensorDevice):
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self):
|
||||||
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
||||||
if not self.available:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# If state is MOTION (RemoteMotion works only)
|
# If state is MOTION (RemoteMotion works only)
|
||||||
if self._state == "MOTION":
|
if self._state == "MOTION":
|
||||||
return "motion"
|
return "motion"
|
||||||
|
|
|
@ -13,6 +13,8 @@ from homeassistant.loader import get_component
|
||||||
|
|
||||||
DEPENDENCIES = ['homematic']
|
DEPENDENCIES = ['homematic']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
STATE_MANUAL = "manual"
|
STATE_MANUAL = "manual"
|
||||||
STATE_BOOST = "boost"
|
STATE_BOOST = "boost"
|
||||||
|
|
||||||
|
@ -22,7 +24,17 @@ HM_STATE_MAP = {
|
||||||
"BOOST_MODE": STATE_BOOST,
|
"BOOST_MODE": STATE_BOOST,
|
||||||
}
|
}
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
HM_TEMP_MAP = [
|
||||||
|
'ACTUAL_TEMPERATURE',
|
||||||
|
'TEMPERATURE',
|
||||||
|
]
|
||||||
|
|
||||||
|
HM_HUMI_MAP = [
|
||||||
|
'ACTUAL_HUMIDITY',
|
||||||
|
'HUMIDITY',
|
||||||
|
]
|
||||||
|
|
||||||
|
HM_CONTROL_MODE = 'CONTROL_MODE'
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_callback_devices, discovery_info=None):
|
def setup_platform(hass, config, add_callback_devices, discovery_info=None):
|
||||||
|
@ -50,7 +62,7 @@ class HMThermostat(HMDevice, ClimateDevice):
|
||||||
@property
|
@property
|
||||||
def current_operation(self):
|
def current_operation(self):
|
||||||
"""Return current operation ie. heat, cool, idle."""
|
"""Return current operation ie. heat, cool, idle."""
|
||||||
if not self.available:
|
if HM_CONTROL_MODE not in self._data:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# read state and search
|
# read state and search
|
||||||
|
@ -62,8 +74,6 @@ class HMThermostat(HMDevice, ClimateDevice):
|
||||||
@property
|
@property
|
||||||
def operation_list(self):
|
def operation_list(self):
|
||||||
"""List of available operation modes."""
|
"""List of available operation modes."""
|
||||||
if not self.available:
|
|
||||||
return None
|
|
||||||
op_list = []
|
op_list = []
|
||||||
|
|
||||||
# generate list
|
# generate list
|
||||||
|
@ -76,31 +86,29 @@ class HMThermostat(HMDevice, ClimateDevice):
|
||||||
@property
|
@property
|
||||||
def current_humidity(self):
|
def current_humidity(self):
|
||||||
"""Return the current humidity."""
|
"""Return the current humidity."""
|
||||||
if not self.available:
|
for node in HM_HUMI_MAP:
|
||||||
return None
|
if node in self._data:
|
||||||
return self._data.get('ACTUAL_HUMIDITY', None)
|
return self._data[node]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_temperature(self):
|
def current_temperature(self):
|
||||||
"""Return the current temperature."""
|
"""Return the current temperature."""
|
||||||
if not self.available:
|
for node in HM_TEMP_MAP:
|
||||||
return None
|
if node in self._data:
|
||||||
return self._data.get('ACTUAL_TEMPERATURE', None)
|
return self._data[node]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_temperature(self):
|
def target_temperature(self):
|
||||||
"""Return the target temperature."""
|
"""Return the target temperature."""
|
||||||
if not self.available:
|
return self._data.get(self._state)
|
||||||
return None
|
|
||||||
return self._data.get('SET_TEMPERATURE', None)
|
|
||||||
|
|
||||||
def set_temperature(self, **kwargs):
|
def set_temperature(self, **kwargs):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
temperature = kwargs.get(ATTR_TEMPERATURE)
|
temperature = kwargs.get(ATTR_TEMPERATURE)
|
||||||
if not self.available or temperature is None:
|
if temperature is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self._hmdevice.set_temperature(temperature)
|
self._hmdevice.writeNodeData(self._state, float(temperature))
|
||||||
|
|
||||||
def set_operation_mode(self, operation_mode):
|
def set_operation_mode(self, operation_mode):
|
||||||
"""Set new target operation mode."""
|
"""Set new target operation mode."""
|
||||||
|
@ -122,10 +130,12 @@ class HMThermostat(HMDevice, ClimateDevice):
|
||||||
def _init_data_struct(self):
|
def _init_data_struct(self):
|
||||||
"""Generate a data dict (self._data) from the Homematic metadata."""
|
"""Generate a data dict (self._data) from the Homematic metadata."""
|
||||||
# Add state to data dict
|
# Add state to data dict
|
||||||
self._data.update({"CONTROL_MODE": STATE_UNKNOWN,
|
self._state = next(iter(self._hmdevice.WRITENODE.keys()))
|
||||||
"SET_TEMPERATURE": STATE_UNKNOWN,
|
self._data[self._state] = STATE_UNKNOWN
|
||||||
"ACTUAL_TEMPERATURE": STATE_UNKNOWN})
|
|
||||||
|
|
||||||
# support humidity
|
# support state
|
||||||
if 'ACTUAL_HUMIDITY' in self._hmdevice.SENSORNODE:
|
if HM_CONTROL_MODE in self._hmdevice.ATTRIBUTENODE:
|
||||||
self._data.update({'ACTUAL_HUMIDITY': STATE_UNKNOWN})
|
self._data[HM_CONTROL_MODE] = STATE_UNKNOWN
|
||||||
|
|
||||||
|
for node in self._hmdevice.SENSORNODE.keys():
|
||||||
|
self._data[node] = STATE_UNKNOWN
|
||||||
|
|
|
@ -44,18 +44,15 @@ class HMCover(HMDevice, CoverDevice):
|
||||||
|
|
||||||
None is unknown, 0 is closed, 100 is fully open.
|
None is unknown, 0 is closed, 100 is fully open.
|
||||||
"""
|
"""
|
||||||
if self.available:
|
return int(self._hm_get_state() * 100)
|
||||||
return int(self._hm_get_state() * 100)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def set_cover_position(self, **kwargs):
|
def set_cover_position(self, **kwargs):
|
||||||
"""Move the cover to a specific position."""
|
"""Move the cover to a specific position."""
|
||||||
if self.available:
|
if ATTR_POSITION in kwargs:
|
||||||
if ATTR_POSITION in kwargs:
|
position = float(kwargs[ATTR_POSITION])
|
||||||
position = float(kwargs[ATTR_POSITION])
|
position = min(100, max(0, position))
|
||||||
position = min(100, max(0, position))
|
level = position / 100.0
|
||||||
level = position / 100.0
|
self._hmdevice.set_level(level, self._channel)
|
||||||
self._hmdevice.set_level(level, self._channel)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
|
@ -68,18 +65,15 @@ class HMCover(HMDevice, CoverDevice):
|
||||||
|
|
||||||
def open_cover(self, **kwargs):
|
def open_cover(self, **kwargs):
|
||||||
"""Open the cover."""
|
"""Open the cover."""
|
||||||
if self.available:
|
self._hmdevice.move_up(self._channel)
|
||||||
self._hmdevice.move_up(self._channel)
|
|
||||||
|
|
||||||
def close_cover(self, **kwargs):
|
def close_cover(self, **kwargs):
|
||||||
"""Close the cover."""
|
"""Close the cover."""
|
||||||
if self.available:
|
self._hmdevice.move_down(self._channel)
|
||||||
self._hmdevice.move_down(self._channel)
|
|
||||||
|
|
||||||
def stop_cover(self, **kwargs):
|
def stop_cover(self, **kwargs):
|
||||||
"""Stop the device if in motion."""
|
"""Stop the device if in motion."""
|
||||||
if self.available:
|
self._hmdevice.stop(self._channel)
|
||||||
self._hmdevice.stop(self._channel)
|
|
||||||
|
|
||||||
def _init_data_struct(self):
|
def _init_data_struct(self):
|
||||||
"""Generate a data dict (self._data) from hm metadata."""
|
"""Generate a data dict (self._data) from hm metadata."""
|
||||||
|
|
|
@ -22,7 +22,7 @@ from homeassistant.helpers.event import track_time_interval
|
||||||
from homeassistant.config import load_yaml_config_file
|
from homeassistant.config import load_yaml_config_file
|
||||||
|
|
||||||
DOMAIN = 'homematic'
|
DOMAIN = 'homematic'
|
||||||
REQUIREMENTS = ["pyhomematic==0.1.21"]
|
REQUIREMENTS = ["pyhomematic==0.1.22"]
|
||||||
|
|
||||||
SCAN_INTERVAL_HUB = timedelta(seconds=300)
|
SCAN_INTERVAL_HUB = timedelta(seconds=300)
|
||||||
SCAN_INTERVAL_VARIABLES = timedelta(seconds=30)
|
SCAN_INTERVAL_VARIABLES = timedelta(seconds=30)
|
||||||
|
@ -63,7 +63,7 @@ HM_DEVICE_TYPES = {
|
||||||
'TemperatureSensor', 'CO2Sensor', 'IPSwitchPowermeter', 'HMWIOSwitch'],
|
'TemperatureSensor', 'CO2Sensor', 'IPSwitchPowermeter', 'HMWIOSwitch'],
|
||||||
DISCOVER_CLIMATE: [
|
DISCOVER_CLIMATE: [
|
||||||
'Thermostat', 'ThermostatWall', 'MAXThermostat', 'ThermostatWall2',
|
'Thermostat', 'ThermostatWall', 'MAXThermostat', 'ThermostatWall2',
|
||||||
'MAXWallThermostat'],
|
'MAXWallThermostat', 'IPThermostat'],
|
||||||
DISCOVER_BINARY_SENSORS: [
|
DISCOVER_BINARY_SENSORS: [
|
||||||
'ShutterContact', 'Smoke', 'SmokeV2', 'Motion', 'MotionV2',
|
'ShutterContact', 'Smoke', 'SmokeV2', 'Motion', 'MotionV2',
|
||||||
'RemoteMotion', 'WeatherSensor', 'TiltSensor', 'IPShutterContact',
|
'RemoteMotion', 'WeatherSensor', 'TiltSensor', 'IPShutterContact',
|
||||||
|
@ -119,6 +119,8 @@ CONF_LOCAL_IP = 'local_ip'
|
||||||
CONF_LOCAL_PORT = 'local_port'
|
CONF_LOCAL_PORT = 'local_port'
|
||||||
CONF_IP = 'ip'
|
CONF_IP = 'ip'
|
||||||
CONF_PORT = 'port'
|
CONF_PORT = 'port'
|
||||||
|
CONF_CALLBACK_IP = "callback_ip"
|
||||||
|
CONF_CALLBACK_PORT = "callback_port"
|
||||||
CONF_RESOLVENAMES = 'resolvenames'
|
CONF_RESOLVENAMES = 'resolvenames'
|
||||||
CONF_VARIABLES = 'variables'
|
CONF_VARIABLES = 'variables'
|
||||||
CONF_DEVICES = 'devices'
|
CONF_DEVICES = 'devices'
|
||||||
|
@ -160,6 +162,8 @@ CONFIG_SCHEMA = vol.Schema({
|
||||||
vol.In(CONF_RESOLVENAMES_OPTIONS),
|
vol.In(CONF_RESOLVENAMES_OPTIONS),
|
||||||
vol.Optional(CONF_DEVICES, default=DEFAULT_DEVICES): cv.boolean,
|
vol.Optional(CONF_DEVICES, default=DEFAULT_DEVICES): cv.boolean,
|
||||||
vol.Optional(CONF_PRIMARY, default=DEFAULT_PRIMARY): cv.boolean,
|
vol.Optional(CONF_PRIMARY, default=DEFAULT_PRIMARY): cv.boolean,
|
||||||
|
vol.Optional(CONF_CALLBACK_IP): cv.string,
|
||||||
|
vol.Optional(CONF_CALLBACK_PORT): cv.port,
|
||||||
}},
|
}},
|
||||||
vol.Optional(CONF_LOCAL_IP, default=DEFAULT_LOCAL_IP): cv.string,
|
vol.Optional(CONF_LOCAL_IP, default=DEFAULT_LOCAL_IP): cv.string,
|
||||||
vol.Optional(CONF_LOCAL_PORT, default=DEFAULT_LOCAL_PORT): cv.port,
|
vol.Optional(CONF_LOCAL_PORT, default=DEFAULT_LOCAL_PORT): cv.port,
|
||||||
|
@ -252,6 +256,8 @@ def setup(hass, config):
|
||||||
remotes[rname][CONF_RESOLVENAMES] = rconfig.get(CONF_RESOLVENAMES)
|
remotes[rname][CONF_RESOLVENAMES] = rconfig.get(CONF_RESOLVENAMES)
|
||||||
remotes[rname][CONF_USERNAME] = rconfig.get(CONF_USERNAME)
|
remotes[rname][CONF_USERNAME] = rconfig.get(CONF_USERNAME)
|
||||||
remotes[rname][CONF_PASSWORD] = rconfig.get(CONF_PASSWORD)
|
remotes[rname][CONF_PASSWORD] = rconfig.get(CONF_PASSWORD)
|
||||||
|
remotes[rname]['callbackip'] = rconfig.get(CONF_CALLBACK_IP)
|
||||||
|
remotes[rname]['callbackport'] = rconfig.get(CONF_CALLBACK_PORT)
|
||||||
|
|
||||||
if server not in hosts or rconfig.get(CONF_PRIMARY):
|
if server not in hosts or rconfig.get(CONF_PRIMARY):
|
||||||
hosts[server] = {
|
hosts[server] = {
|
||||||
|
|
|
@ -38,8 +38,6 @@ class HMLight(HMDevice, Light):
|
||||||
@property
|
@property
|
||||||
def brightness(self):
|
def brightness(self):
|
||||||
"""Return the brightness of this light between 0..255."""
|
"""Return the brightness of this light between 0..255."""
|
||||||
if not self.available:
|
|
||||||
return None
|
|
||||||
# Is dimmer?
|
# Is dimmer?
|
||||||
if self._state is "LEVEL":
|
if self._state is "LEVEL":
|
||||||
return int(self._hm_get_state() * 255)
|
return int(self._hm_get_state() * 255)
|
||||||
|
@ -61,9 +59,6 @@ class HMLight(HMDevice, Light):
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the light on."""
|
"""Turn the light on."""
|
||||||
if not self.available:
|
|
||||||
return
|
|
||||||
|
|
||||||
if ATTR_BRIGHTNESS in kwargs and self._state is "LEVEL":
|
if ATTR_BRIGHTNESS in kwargs and self._state is "LEVEL":
|
||||||
percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
|
percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
|
||||||
self._hmdevice.set_level(percent_bright, self._channel)
|
self._hmdevice.set_level(percent_bright, self._channel)
|
||||||
|
@ -72,8 +67,7 @@ class HMLight(HMDevice, Light):
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the light off."""
|
"""Turn the light off."""
|
||||||
if self.available:
|
self._hmdevice.off(self._channel)
|
||||||
self._hmdevice.off(self._channel)
|
|
||||||
|
|
||||||
def _init_data_struct(self):
|
def _init_data_struct(self):
|
||||||
"""Generate a data dict (self._data) from the Homematic metadata."""
|
"""Generate a data dict (self._data) from the Homematic metadata."""
|
||||||
|
|
|
@ -65,9 +65,6 @@ class HMSensor(HMDevice):
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if not self.available:
|
|
||||||
return STATE_UNKNOWN
|
|
||||||
|
|
||||||
# Does a cast exist for this class?
|
# Does a cast exist for this class?
|
||||||
name = self._hmdevice.__class__.__name__
|
name = self._hmdevice.__class__.__name__
|
||||||
if name in HM_STATE_HA_CAST:
|
if name in HM_STATE_HA_CAST:
|
||||||
|
@ -79,9 +76,6 @@ class HMSensor(HMDevice):
|
||||||
@property
|
@property
|
||||||
def unit_of_measurement(self):
|
def unit_of_measurement(self):
|
||||||
"""Return the unit of measurement of this entity, if any."""
|
"""Return the unit of measurement of this entity, if any."""
|
||||||
if not self.available:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return HM_UNIT_HA_CAST.get(self._state, None)
|
return HM_UNIT_HA_CAST.get(self._state, None)
|
||||||
|
|
||||||
def _init_data_struct(self):
|
def _init_data_struct(self):
|
||||||
|
|
|
@ -53,13 +53,11 @@ class HMSwitch(HMDevice, SwitchDevice):
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the switch on."""
|
"""Turn the switch on."""
|
||||||
if self.available:
|
self._hmdevice.on(self._channel)
|
||||||
self._hmdevice.on(self._channel)
|
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
if self.available:
|
self._hmdevice.off(self._channel)
|
||||||
self._hmdevice.off(self._channel)
|
|
||||||
|
|
||||||
def _init_data_struct(self):
|
def _init_data_struct(self):
|
||||||
"""Generate a data dict (self._data) from the Homematic metadata."""
|
"""Generate a data dict (self._data) from the Homematic metadata."""
|
||||||
|
|
|
@ -473,7 +473,7 @@ pyharmony==1.0.12
|
||||||
pyhik==0.0.7
|
pyhik==0.0.7
|
||||||
|
|
||||||
# homeassistant.components.homematic
|
# homeassistant.components.homematic
|
||||||
pyhomematic==0.1.21
|
pyhomematic==0.1.22
|
||||||
|
|
||||||
# homeassistant.components.device_tracker.icloud
|
# homeassistant.components.device_tracker.icloud
|
||||||
pyicloud==0.9.1
|
pyicloud==0.9.1
|
||||||
|
|
Loading…
Reference in New Issue