homematic update to pyhomematic 0.1.9

This commit is contained in:
Pascal Vizeli 2016-07-13 23:15:21 +02:00
parent ce4891fe8e
commit c023d1d656
4 changed files with 161 additions and 50 deletions

View file

@ -4,71 +4,120 @@ Support for Homematic devices.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/homematic/ https://home-assistant.io/components/homematic/
""" """
import os
import time import time
import logging import logging
from functools import partial from functools import partial
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN import voluptuous as vol
from homeassistant.helpers import discovery
from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN,
CONF_USERNAME, CONF_PASSWORD)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers import discovery
from homeassistant.config import load_yaml_config_file
DOMAIN = 'homematic' DOMAIN = 'homematic'
REQUIREMENTS = ['pyhomematic==0.1.8'] REQUIREMENTS = ["pyhomematic==0.1.9"]
HOMEMATIC = None HOMEMATIC = None
HOMEMATIC_LINK_DELAY = 0.5 HOMEMATIC_LINK_DELAY = 0.5
DISCOVER_SWITCHES = "homematic.switch" DISCOVER_SWITCHES = 'homematic.switch'
DISCOVER_LIGHTS = "homematic.light" DISCOVER_LIGHTS = 'homematic.light'
DISCOVER_SENSORS = "homematic.sensor" DISCOVER_SENSORS = 'homematic.sensor'
DISCOVER_BINARY_SENSORS = "homematic.binary_sensor" DISCOVER_BINARY_SENSORS = 'homematic.binary_sensor'
DISCOVER_ROLLERSHUTTER = "homematic.rollershutter" DISCOVER_ROLLERSHUTTER = 'homematic.rollershutter'
DISCOVER_THERMOSTATS = "homematic.thermostat" DISCOVER_THERMOSTATS = 'homematic.thermostat'
ATTR_DISCOVER_DEVICES = "devices" ATTR_DISCOVER_DEVICES = 'devices'
ATTR_PARAM = "param" ATTR_PARAM = 'param'
ATTR_CHANNEL = "channel" ATTR_CHANNEL = 'channel'
ATTR_NAME = "name" ATTR_NAME = 'name'
ATTR_ADDRESS = "address" ATTR_ADDRESS = 'address'
EVENT_KEYPRESS = "homematic.keypress" EVENT_KEYPRESS = 'homematic.keypress'
EVENT_IMPULSE = 'homematic.impulse'
SERVICE_VIRTUALKEY = 'virtualkey'
HM_DEVICE_TYPES = { HM_DEVICE_TYPES = {
DISCOVER_SWITCHES: ["Switch", "SwitchPowermeter"], DISCOVER_SWITCHES: ['Switch', 'SwitchPowermeter'],
DISCOVER_LIGHTS: ["Dimmer"], DISCOVER_LIGHTS: ['Dimmer'],
DISCOVER_SENSORS: ["SwitchPowermeter", "Motion", "MotionV2", DISCOVER_SENSORS: ['SwitchPowermeter', 'Motion', 'MotionV2',
"RemoteMotion", "ThermostatWall", "AreaThermostat", 'RemoteMotion', 'ThermostatWall', 'AreaThermostat',
"RotaryHandleSensor", "WaterSensor"], 'RotaryHandleSensor', 'WaterSensor', 'PowermeterGas',
DISCOVER_THERMOSTATS: ["Thermostat", "ThermostatWall", "MAXThermostat"], 'LuxSensor'],
DISCOVER_BINARY_SENSORS: ["ShutterContact", "Smoke", "SmokeV2", DISCOVER_THERMOSTATS: ['Thermostat', 'ThermostatWall', 'MAXThermostat'],
"Motion", "MotionV2", "RemoteMotion"], DISCOVER_BINARY_SENSORS: ['ShutterContact', 'Smoke', 'SmokeV2', 'Motion',
DISCOVER_ROLLERSHUTTER: ["Blind"] 'MotionV2', 'RemoteMotion'],
DISCOVER_ROLLERSHUTTER: ['Blind']
} }
HM_IGNORE_DISCOVERY_NODE = [ HM_IGNORE_DISCOVERY_NODE = [
"ACTUAL_TEMPERATURE" 'ACTUAL_TEMPERATURE'
] ]
HM_ATTRIBUTE_SUPPORT = { HM_ATTRIBUTE_SUPPORT = {
"LOWBAT": ["Battery", {0: "High", 1: "Low"}], 'LOWBAT': ['Battery', {0: 'High', 1: 'Low'}],
"ERROR": ["Sabotage", {0: "No", 1: "Yes"}], 'ERROR': ['Sabotage', {0: 'No', 1: 'Yes'}],
"RSSI_DEVICE": ["RSSI", {}], 'RSSI_DEVICE': ['RSSI', {}],
"VALVE_STATE": ["Valve", {}], 'VALVE_STATE': ['Valve', {}],
"BATTERY_STATE": ["Battery", {}], 'BATTERY_STATE': ['Battery', {}],
"CONTROL_MODE": ["Mode", {0: "Auto", 1: "Manual", 2: "Away", 3: "Boost"}], 'CONTROL_MODE': ['Mode', {0: 'Auto', 1: 'Manual', 2: 'Away', 3: 'Boost'}],
"POWER": ["Power", {}], 'POWER': ['Power', {}],
"CURRENT": ["Current", {}], 'CURRENT': ['Current', {}],
"VOLTAGE": ["Voltage", {}] 'VOLTAGE': ['Voltage', {}]
} }
HM_PRESS_EVENTS = [ HM_PRESS_EVENTS = [
"PRESS_SHORT", 'PRESS_SHORT',
"PRESS_LONG", 'PRESS_LONG',
"PRESS_CONT", 'PRESS_CONT',
"PRESS_LONG_RELEASE" 'PRESS_LONG_RELEASE'
]
HM_IMPULSE_EVENTS = [
'SEQUENCE_OK'
] ]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_RESOLVENAMES_OPTIONS = [
'metadata',
'json',
'xml',
False
]
CONF_LOCAL_IP = 'local_ip'
CONF_LOCAL_PORT = 'local_port'
CONF_REMOTE_IP = 'remote_ip'
CONF_REMOTE_PORT = 'remote_port'
CONF_RESOLVENAMES = 'resolvenames'
CONF_DELAY = 'delay'
PLATFORM_SCHEMA = vol.Schema({
vol.Required(CONF_LOCAL_IP): vol.Coerce(str),
vol.Optional(CONF_LOCAL_PORT, default=8943):
vol.All(vol.Coerce(int),
vol.Range(min=1, max=65535)),
vol.Required(CONF_REMOTE_IP): vol.Coerce(str),
vol.Optional(CONF_REMOTE_PORT, default=2001):
vol.All(vol.Coerce(int),
vol.Range(min=1, max=65535)),
vol.Optional(CONF_RESOLVENAMES, default=False):
vol.In(CONF_RESOLVENAMES_OPTIONS),
vol.Optional(CONF_USERNAME, default="Admin"): vol.Coerce(str),
vol.Optional(CONF_PASSWORD, default=""): vol.Coerce(str),
vol.Optional(CONF_DELAY, default=0.5): vol.Coerce(float)
})
SCHEMA_SERVICE_VIRTUALKEY = vol.Schema({
vol.Required(ATTR_ADDRESS): vol.Coerce(str),
vol.Required(ATTR_CHANNEL): vol.Coerce(int),
vol.Required(ATTR_PARAM): vol.Coerce(str)
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup(hass, config): def setup(hass, config):
@ -77,14 +126,14 @@ def setup(hass, config):
from pyhomematic import HMConnection from pyhomematic import HMConnection
local_ip = config[DOMAIN].get("local_ip", None) local_ip = config[DOMAIN][0].get(CONF_LOCAL_IP)
local_port = config[DOMAIN].get("local_port", 8943) local_port = config[DOMAIN][0].get(CONF_LOCAL_PORT)
remote_ip = config[DOMAIN].get("remote_ip", None) remote_ip = config[DOMAIN][0].get(CONF_REMOTE_IP)
remote_port = config[DOMAIN].get("remote_port", 2001) remote_port = config[DOMAIN][0].get(CONF_REMOTE_PORT)
resolvenames = config[DOMAIN].get("resolvenames", False) resolvenames = config[DOMAIN][0].get(CONF_RESOLVENAMES)
username = config[DOMAIN].get("username", "Admin") username = config[DOMAIN][0].get(CONF_USERNAME)
password = config[DOMAIN].get("password", "") password = config[DOMAIN][0].get(CONF_PASSWORD)
HOMEMATIC_LINK_DELAY = config[DOMAIN].get("delay", 0.5) HOMEMATIC_LINK_DELAY = config[DOMAIN][0].get(CONF_DELAY)
if remote_ip is None or local_ip is None: if remote_ip is None or local_ip is None:
_LOGGER.error("Missing remote CCU/Homegear or local address") _LOGGER.error("Missing remote CCU/Homegear or local address")
@ -109,6 +158,15 @@ def setup(hass, config):
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
hass.config.components.append(DOMAIN) hass.config.components.append(DOMAIN)
# regeister homematic services
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_VIRTUALKEY,
_hm_service_virtualkey,
descriptions[DOMAIN][SERVICE_VIRTUALKEY],
SCHEMA_SERVICE_VIRTUALKEY)
return True return True
@ -302,7 +360,7 @@ def _hm_event_handler(hass, device, caller, attribute, value):
_LOGGER.debug("Event %s for %s channel %i", attribute, _LOGGER.debug("Event %s for %s channel %i", attribute,
hmdevice.NAME, channel) hmdevice.NAME, channel)
# a keypress event # keypress event
if attribute in HM_PRESS_EVENTS: if attribute in HM_PRESS_EVENTS:
hass.bus.fire(EVENT_KEYPRESS, { hass.bus.fire(EVENT_KEYPRESS, {
ATTR_NAME: hmdevice.NAME, ATTR_NAME: hmdevice.NAME,
@ -311,9 +369,42 @@ def _hm_event_handler(hass, device, caller, attribute, value):
}) })
return return
# impulse event
if attribute in HM_IMPULSE_EVENTS:
hass.bus.fire(EVENT_KEYPRESS, {
ATTR_NAME: hmdevice.NAME,
ATTR_CHANNEL: channel
})
return
_LOGGER.warning("Event is unknown and not forwarded to HA") _LOGGER.warning("Event is unknown and not forwarded to HA")
def _hm_service_virtualkey(call):
"""Callback for handle virtualkey services."""
address = call.data.get(ATTR_ADDRESS)
channel = call.data.get(ATTR_CHANNEL)
param = call.data.get(ATTR_PARAM)
if address not in HOMEMATIC.devices:
_LOGGER.error("%s not found for service virtualkey!", address)
return
hmdevice = HOMEMATIC.devices.get(address)
# if param exists for this device
if param not in hmdevice.ACTIONNODE:
_LOGGER.error("%s not datapoint in hm device %s", param, address)
return
# channel exists?
if channel > hmdevice.ELEMENT:
_LOGGER.error("%i is not a channel in hm device %s", channel, address)
return
# call key
hmdevice.actionNodeData(param, 1, channel)
class HMDevice(Entity): class HMDevice(Entity):
"""The Homematic device base object.""" """The Homematic device base object."""
@ -465,7 +556,7 @@ class HMDevice(Entity):
channel = self._channel channel = self._channel
# Prepare for subscription # Prepare for subscription
try: try:
if int(channel) > 0: if int(channel) >= 0:
channels_to_sub.update({int(channel): True}) channels_to_sub.update({int(channel): True})
except (ValueError, TypeError): except (ValueError, TypeError):
_LOGGER("Invalid channel in metadata from %s", _LOGGER("Invalid channel in metadata from %s",

View file

@ -28,7 +28,10 @@ HM_UNIT_HA_CAST = {
"POWER": "W", "POWER": "W",
"CURRENT": "mA", "CURRENT": "mA",
"VOLTAGE": "V", "VOLTAGE": "V",
"ENERGY_COUNTER": "Wh" "ENERGY_COUNTER": "Wh",
"GAS_POWER": "m3",
"GAS_ENERGY_COUNTER": "m3",
"LUX": "lux"
} }

View file

@ -14,3 +14,20 @@ persistent_notification:
notification_id: notification_id:
description: Target ID of the notification, will replace a notification with the same Id. [Optional] description: Target ID of the notification, will replace a notification with the same Id. [Optional]
example: 1234 example: 1234
homematic:
virtualkey:
description: Press a virtual key from CCU/Homegear or simulate keypress
fields:
address:
description: Address of homematic device or BidCoS-RF for virtual remote
example: BidCoS-RF
channel:
description: Channel for calling a keypress
example: 1
param:
description: Event to send i.e. PRESS_LONG, PRESS_SHORT
example: PRESS_LONG

View file

@ -280,7 +280,7 @@ pyenvisalink==1.0
pyfttt==0.3 pyfttt==0.3
# homeassistant.components.homematic # homeassistant.components.homematic
pyhomematic==0.1.8 pyhomematic==0.1.9
# homeassistant.components.device_tracker.icloud # homeassistant.components.device_tracker.icloud
pyicloud==0.8.3 pyicloud==0.8.3