Beispiel #1
0
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY

    from pyhomematic import HMConnection

    local_ip = config[DOMAIN][0].get(CONF_LOCAL_IP)
    local_port = config[DOMAIN][0].get(CONF_LOCAL_PORT)
    remote_ip = config[DOMAIN][0].get(CONF_REMOTE_IP)
    remote_port = config[DOMAIN][0].get(CONF_REMOTE_PORT)
    resolvenames = config[DOMAIN][0].get(CONF_RESOLVENAMES)
    username = config[DOMAIN][0].get(CONF_USERNAME)
    password = config[DOMAIN][0].get(CONF_PASSWORD)
    HOMEMATIC_LINK_DELAY = config[DOMAIN][0].get(CONF_DELAY)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    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
Beispiel #2
0
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY

    from pyhomematic import HMConnection

    local_ip = config[DOMAIN][0].get(CONF_LOCAL_IP)
    local_port = config[DOMAIN][0].get(CONF_LOCAL_PORT)
    remote_ip = config[DOMAIN][0].get(CONF_REMOTE_IP)
    remote_port = config[DOMAIN][0].get(CONF_REMOTE_PORT)
    resolvenames = config[DOMAIN][0].get(CONF_RESOLVENAMES)
    username = config[DOMAIN][0].get(CONF_USERNAME)
    password = config[DOMAIN][0].get(CONF_PASSWORD)
    HOMEMATIC_LINK_DELAY = config[DOMAIN][0].get(CONF_DELAY)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    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
Beispiel #3
0
class Test_2_PyhomematicDevices(unittest.TestCase):
    def setUp(self):
        LOG.debug("TestPyhomematicDevices.setUp")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("", 0))
        self.localport = s.getsockname()[1]
        s.close()
        self.vccu = vccu.ServerThread(local=DEFAULT_IP,
                                      localport=self.localport)
        self.vccu.start()
        time.sleep(0.5)
        self.client = HMConnection(interface_id=DEFAULT_INTERFACE_CLIENT,
                                   autostart=False,
                                   remotes={
                                       DEFAULT_REMOTE: {
                                           "ip": DEFAULT_IP,
                                           "port": self.localport,
                                           "connect": True
                                       }
                                   })
        self.client.start()
        time.sleep(STARTUP_DELAY)

    def tearDown(self):
        LOG.debug("TestPyhomematicDevices.tearDown")
        self.client.stop()
        self.vccu.stop()

    def test_0_pyhomematic_classes(self):
        LOG.info("TestPyhomematicDevices.test_0_pyhomematic_classes")
        devices = self.client.devices.get(DEFAULT_REMOTE)
        for _, deviceobject in devices.items():
            deviceclass = devicetypes.SUPPORTED.get(deviceobject.TYPE, None)
            devicedata = DEVICES.get(deviceobject.TYPE, {})
            if deviceclass:
                self.assertIsInstance(deviceobject, deviceclass)
            else:
                if not devicedata.get("supported", True):
                    LOG.info("Unsupported device: %s" % deviceobject.TYPE)
                else:
                    LOG.warning("Device class missing for: %s" %
                                deviceobject.TYPE)
Beispiel #4
0
 def setUp(self):
     LOG.debug("TestPyhomematicDevices.setUp")
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.bind(("", 0))
     self.localport = s.getsockname()[1]
     s.close()
     self.vccu = vccu.ServerThread(local=DEFAULT_IP,
                                   localport=self.localport)
     self.vccu.start()
     time.sleep(0.5)
     self.client = HMConnection(interface_id=DEFAULT_INTERFACE_CLIENT,
                                autostart=False,
                                remotes={
                                    DEFAULT_REMOTE: {
                                        "ip": DEFAULT_IP,
                                        "port": self.localport,
                                        "connect": True
                                    }
                                })
     self.client.start()
     time.sleep(STARTUP_DELAY)
Beispiel #5
0
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY

    from pyhomematic import HMConnection

    local_ip = config[DOMAIN].get("local_ip", None)
    local_port = config[DOMAIN].get("local_port", 8943)
    remote_ip = config[DOMAIN].get("remote_ip", None)
    remote_port = config[DOMAIN].get("remote_port", 2001)
    resolvenames = config[DOMAIN].get("resolvenames", False)
    username = config[DOMAIN].get("username", "Admin")
    password = config[DOMAIN].get("password", "")
    HOMEMATIC_LINK_DELAY = config[DOMAIN].get("delay", 0.5)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    hass.config.components.append(DOMAIN)

    return True
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY

    from pyhomematic import HMConnection

    local_ip = config[DOMAIN].get("local_ip", None)
    local_port = config[DOMAIN].get("local_port", 8943)
    remote_ip = config[DOMAIN].get("remote_ip", None)
    remote_port = config[DOMAIN].get("remote_port", 2001)
    resolvenames = config[DOMAIN].get("resolvenames", False)
    username = config[DOMAIN].get("username", "Admin")
    password = config[DOMAIN].get("password", "")
    HOMEMATIC_LINK_DELAY = config[DOMAIN].get("delay", 0.5)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    hass.config.components.append(DOMAIN)

    return True
    def run(self, listen: str, connect: str) -> None:
        try:
            xmlrpc_local = self._xmlrpc_listen_url(listen)
            xmlrpc_remote = self._xmlrpc_connect_url(connect)
        except ValueError as exc:
            logger.error("Invalid XML-RPC URL: %s", exc)
            sys.exit(1)

        homematic = HMConnection(
            interface_id="inventory",
            local=xmlrpc_local.hostname,
            localport=xmlrpc_local.port or 0,
            remotes={
                "default": {
                    "ip": xmlrpc_remote.hostname,
                    "port": xmlrpc_remote.port,
                    "path": xmlrpc_remote.path or "",
                    "username": xmlrpc_remote.username or "Admin",
                    "password": xmlrpc_remote.password or "",
                }
            },
            eventcallback=self._event_callback,
            systemcallback=self._system_callback,
        )

        try:
            homematic.start()
        except AttributeError:
            sys.exit(1)

        def handler(signum, frame):
            signal(signum, SIG_DFL)
            homematic.stop()

        for signum in (SIGINT, SIGTERM):
            signal(signum, handler)

        homematic._server.join()
Beispiel #8
0
 def test_0_pyhomematic_noinit(self):
     LOG.info("TestPyhomematicBase.test_0_pyhomematic_noinit")
     client = HMConnection(interface_id=DEFAULT_INTERFACE_CLIENT,
                           autostart=False,
                           remotes={
                               DEFAULT_REMOTE: {
                                   "ip": DEFAULT_IP,
                                   "port": self.localport,
                                   "connect": False
                               }
                           })
     client.start()
     time.sleep(STARTUP_DELAY)
     servicemessages = client.getServiceMessages(DEFAULT_REMOTE)
     self.assertEqual(len(servicemessages), 1)
     self.assertEqual(servicemessages[0][0], 'VCU0000001:1')
     client.stop()
    async def run(self, broker: str, listen: str, connect: str) -> None:
        p = urlparse(broker, scheme="mqtt")
        if p.scheme not in ("mqtt", "mqtts") or not p.hostname:
            raise ValueError

        tls_context = None
        if p.scheme == "mqtts":
            tls_context = ssl.create_default_context()

        will = None
        async with Client(
                p.hostname,
                port=p.port or p.scheme == "mqtt" and 1883 or 8883,
                username=p.username,
                password=p.password,
                logger=logger,
                tls_context=tls_context,
                will=will,
        ) as mqtt:
            xmlrpc_local = self._xmlrpc_listen_url(listen)
            xmlrpc_remote = self._xmlrpc_connect_url(connect)
            homematic = HMConnection(
                interface_id=HM_INTERFACE_ID,
                local=xmlrpc_local.hostname,
                localport=xmlrpc_local.port or 0,
                remotes={
                    HM_REMOTE: {
                        "ip": xmlrpc_remote.hostname,
                        "port": xmlrpc_remote.port,
                        "path": xmlrpc_remote.path or "",
                        "username": xmlrpc_remote.username or "Admin",
                        "password": xmlrpc_remote.password or "",
                    }
                },
                eventcallback=partial(self._event_callback, mqtt),
                systemcallback=partial(self._system_callback, mqtt),
            )

            try:
                homematic.start()
            except AttributeError:
                sys.exit(1)

            async with mqtt.unfiltered_messages() as messages:
                async for message in messages:
                    await self._process_packet(message, homematic)

            homematic.stop()
Beispiel #10
0
 def test_1_pyhomematic_init(self):
     LOG.info("TestPyhomematicBase.test_1_pyhomematic_init")
     client = HMConnection(interface_id=DEFAULT_INTERFACE_CLIENT,
                           autostart=False,
                           remotes={
                               DEFAULT_REMOTE: {
                                   "ip": DEFAULT_IP,
                                   "port": self.localport,
                                   "connect": True
                               }
                           })
     client.start()
     time.sleep(STARTUP_DELAY)
     servicemessages = client.getServiceMessages(DEFAULT_REMOTE)
     self.assertEqual(len(servicemessages), 1)
     self.assertEqual(servicemessages[0][0], 'VCU0000001:1')
     self.assertIsInstance(client.devices, dict)
     devices = client.devices.get(DEFAULT_REMOTE)
     self.assertIsInstance(devices, dict)
     self.assertGreater(len(devices.keys()), 0)
     client.stop()
Beispiel #11
0
DEVICE2 = 'address_of_doorcontact'  # e.g. LEQ1234567
DEVICE3 = 'address_of_thermostat'

def systemcallback(src, *args):
    print(src)
    for arg in args:
        print(arg)

try:
    # Create a server that listens on 127.0.0.1:7080 and identifies itself as myserver.
    # Connect to Homegear at 127.0.0.1:2001
    # Automatically start everything. Without autostart, pyhomematic.start() can be called.
    # We add a systemcallback so we can see what else happens besides the regular events.
    pyhomematic = HMConnection(interface_id="myserver",
                               autostart=True,
                               systemcallback=systemcallback,
                               remotes={"rf":{
                                   "ip":"127.0.0.1",
                                   "port": 2001}})
except Exception:
    sys.exit(1)

sleepcounter = 0

def eventcallback(address, interface_id, key, value):
    print("CALLBACK: %s, %s, %s, %s" % (address, interface_id, key, value))

while not pyhomematic.devices and sleepcounter < 20:
    print("Waiting for devices")
    sleepcounter += 1
    time.sleep(1)
print(pyhomematic.devices)
Beispiel #12
0
def cli(local, localport, remote, remoteport, address, channel, state, toggle,
        timer, debug, user, password, variable, data):

    # debug?
    if debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    try:
        # Connect to HM
        pyhomematic = HMConnection(interface_id="test-pyhomatic",
                                   local=local,
                                   localport=localport,
                                   remote=remote,
                                   remoteport=remoteport,
                                   autostart=True,
                                   rpcusername=user,
                                   rpcpassword=password,
                                   systemcallback=systemcallback)
    except:
        print("Can't init HMConnection!")
        sys.exit(1)

    sleepcounter = 0

    while not pyhomematic.devices and sleepcounter < 20:
        print("Waiting for devices")
        sleepcounter += 1
        time.sleep(1)
    print(pyhomematic.devices)

    # read system variables
    print("******************************")
    print("Read all: %s" % str(pyhomematic.getAllSystemVariables()))
    if variable is not None:
        pyhomematic.setSystemVariable(variable, data)
        print("Read: %s" % str(pyhomematic.getSystemVariable(variable)))
    print("******************************")

    # need test a hm object?
    if address in pyhomematic.devices:
        device = pyhomematic.devices[address]

        print("******************************")
        print("* Show metadata from %s" % address)
        print("* Elements: %s / Childs: %i" % (device.ELEMENT, len(device.CHANNELS)))
        print("* Class: %s" % str(device.__class__))
        print("* Base: %s" % str(device.__class__.__bases__))
        print("* Sensor datapoint: %s" % str(device.SENSORNODE))
        print("* Binary datapoint: %s" % str(device.BINARYNODE))
        print("* Write datapoint: %s" % str(device.WRITENODE))
        print("* Attribute datapoint: %s" % str(device.ATTRIBUTENODE))
        print("* Event datapoint: %s" % str(device.EVENTNODE))
        print("* Action datapoint: %s" % str(device.ACTIONNODE))
        print("******************************")

        # WeatherSensor
        if isinstance(device, WeatherSensor):
            print(" / Temperature: %f" % device.get_temperature())
            print(" / Humidity: %i" % device.get_humidity())
            print(" / Rain Counter: %f" % device.get_rain_counter())
            print(" / Wind Speed: %f" % device.get_wind_speed())
            print(" / Wind Direction: %i" % device.get_wind_direction())
            print(" / Wind Direction Range: %i" % device.get_wind_direction_range())
            print(" / Sunshineduration: %i" % device.get_sunshineduration())
            print(" / Brightness: %i" % device.get_brightness())
            print(" / Is Raining: %s" % str(device.is_raining()))

        # AreaThermostat
        if isinstance(device, AreaThermostat):
            print(" / Temperature: %f" % device.get_temperature())
            print(" / Humidity: %i" % device.get_humidity())

        # ShutterContact
        if isinstance(device, ShutterContact):
            print(" / Contact open: %s" % str(device.is_open()))

        # Smoke
        if isinstance(device, Smoke):
            print(" / Smoke detect: %s" % str(device.is_smoke()))

        # Motion
        if isinstance(device, Motion):
            print(" / Motion detect: %s" % str(device.is_motion()))
            print(" / Brightness: %i" % device.get_brightness())

        # Remote
        if isinstance(device, Remote):
            print(" / is a Remote")

            if toggle:
                print(" / Press short/long")
                device.press_long(channel)
                device.press_short(channel)

        # Switch
        if isinstance(device, GenericSwitch):
            print(" / Switch is on: %s" % str(device.is_on(channel)))

            if toggle:
                print(" / Changee state to: %s" % str(bool(state)))
                device.set_state(bool(state), channel)
                print(" / Switch is on: %s" % str(device.is_on(channel)))

        ########### Attribute #########
        print(" / RSSI_DEVICE: %i" % device.get_rssi())

        if isinstance(device, HelperLowBat):
            print(" / Low batter: %s" % str(device.low_batt()))

        if isinstance(device, HelperSabotage):
            print(" / Sabotage: %s" % str(device.sabotage()))

        if isinstance(device, HelperWorking):
            print(" / Working: %s" % str(device.is_working()))

        if isinstance(device, HelperValveState):
            print(" / Valve state: %i" % device.valve_state())

        if isinstance(device, HelperBatteryState):
            print(" / Bettery state: %f" % device.battery_state())

    # do nothing for show & debug events
    print("Now waiting for events/callback")
    time.sleep(timer)

    # end
    pyhomematic.stop()
Beispiel #13
0
def cli(local, localport, remote, remoteport, address, channel, state, toggle,
        timer, debug, user, password, variable, data):

    # debug?
    if debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    try:
        # Connect to HM
        pyhomematic = HMConnection(interface_id="testpyhomatic",
                                   local=local,
                                   localport=localport,
                                   remote=remote,
                                   remoteport=remoteport,
                                   autostart=True,
                                   rpcusername=user,
                                   rpcpassword=password,
                                   systemcallback=systemcallback)
    except Exception:
        print("Can't init HMConnection!")
        sys.exit(1)

    sleepcounter = 0

    while not pyhomematic.devices and sleepcounter < 20:
        print("Waiting for devices")
        sleepcounter += 1
        time.sleep(1)
    print(pyhomematic.devices)

    # read system variables
    print("******************************")
    print("Read all: %s" % str(pyhomematic.getAllSystemVariables('default')))
    if variable is not None:
        pyhomematic.setSystemVariable(variable, data)
        print("Read: %s" % str(pyhomematic.getSystemVariable(variable)))
    print("******************************")

    # need test a hm object?
    if address in pyhomematic.devices:
        device = pyhomematic.devices[address]

        print("******************************")
        print("* Show metadata from %s" % address)
        print("* Elements: %s / Childs: %i" %
              (device.ELEMENT, len(device.CHANNELS)))
        print("* Class: %s" % str(device.__class__))
        print("* Base: %s" % str(device.__class__.__bases__))
        print("* Sensor datapoint: %s" % str(device.SENSORNODE))
        print("* Binary datapoint: %s" % str(device.BINARYNODE))
        print("* Write datapoint: %s" % str(device.WRITENODE))
        print("* Attribute datapoint: %s" % str(device.ATTRIBUTENODE))
        print("* Event datapoint: %s" % str(device.EVENTNODE))
        print("* Action datapoint: %s" % str(device.ACTIONNODE))
        print("******************************")

        # WeatherSensor
        if isinstance(device, WeatherSensor):
            print(" / Temperature: %f" % device.get_temperature())
            print(" / Humidity: %i" % device.get_humidity())
            print(" / Rain Counter: %f" % device.get_rain_counter())
            print(" / Wind Speed: %f" % device.get_wind_speed())
            print(" / Wind Direction: %i" % device.get_wind_direction())
            print(" / Wind Direction Range: %i" %
                  device.get_wind_direction_range())
            print(" / Sunshineduration: %i" % device.get_sunshineduration())
            print(" / Brightness: %i" % device.get_brightness())
            print(" / Is Raining: %s" % str(device.is_raining()))

        # AreaThermostat
        if isinstance(device, AreaThermostat):
            print(" / Temperature: %f" % device.get_temperature())
            print(" / Humidity: %i" % device.get_humidity())

        # ShutterContact
        if isinstance(device, ShutterContact):
            print(" / Contact open: %s" % str(device.is_open()))

        # Smoke
        if isinstance(device, Smoke):
            print(" / Smoke detect: %s" % str(device.is_smoke()))

        # Motion
        if isinstance(device, Motion):
            print(" / Motion detect: %s" % str(device.is_motion()))
            print(" / Brightness: %i" % device.get_brightness())

        # Remote
        if isinstance(device, Remote):
            print(" / is a Remote")

            if toggle:
                print(" / Press short/long")
                device.press_long(channel)
                device.press_short(channel)

        # Switch
        if isinstance(device, GenericSwitch):
            print(" / Switch is on: %s" % str(device.is_on(channel)))

            if toggle:
                print(" / Changee state to: %s" % str(bool(state)))
                device.set_state(bool(state), channel)
                print(" / Switch is on: %s" % str(device.is_on(channel)))

        ########### Attribute #########
        print(" / RSSI_DEVICE: %i" % device.get_rssi())

        if isinstance(device, HelperLowBat):
            print(" / Low batter: %s" % str(device.low_batt()))

        if isinstance(device, HelperSabotage):
            print(" / Sabotage: %s" % str(device.sabotage()))

        if isinstance(device, HelperWorking):
            print(" / Working: %s" % str(device.is_working()))

        if isinstance(device, HelperValveState):
            print(" / Valve state: %i" % device.valve_state())

        if isinstance(device, HelperBatteryState):
            print(" / Bettery state: %f" % device.battery_state())

    # do nothing for show & debug events
    print("Now waiting for events/callback")
    time.sleep(timer)

    # end
    pyhomematic.stop()
Beispiel #14
0
DEVICE3 = 'address_of_thermostat'

def systemcallback(src, *args):
    print(src)
    for arg in args:
        print(arg)

try:
    # Create a server that listens on 127.0.0.1:7080 and identifies itself as myserver.
    # Connect to Homegear at 127.0.0.1:2001
    # Automatically start everything. Without autostart, pyhomematic.start() can be called.
    # We add a systemcallback so we can see what else happens besides the regular events.
    pyhomematic = HMConnection(interface_id="myserver",
                               local="127.0.0.1",
                               localport=7080,
                               remote="127.0.0.1",
                               remoteport=2001,
                               autostart=True,
                               systemcallback=systemcallback)
except:
    sys.exit(1)

sleepcounter = 0

def eventcallback(address, interface_id, key, value):
    print("CALLBACK: %s, %s, %s, %s" % (address, interface_id, key, value))

while not pyhomematic.devices and sleepcounter < 20:
    print("Waiting for devices")
    sleepcounter += 1
    time.sleep(1)
Beispiel #15
0
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY
    from pyhomematic import HMConnection

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    local_ip = config[DOMAIN].get(CONF_LOCAL_IP)
    local_port = config[DOMAIN].get(CONF_LOCAL_PORT)
    remote_ip = config[DOMAIN].get(CONF_REMOTE_IP)
    remote_port = config[DOMAIN].get(CONF_REMOTE_PORT)
    resolvenames = config[DOMAIN].get(CONF_RESOLVENAMES)
    username = config[DOMAIN].get(CONF_USERNAME)
    password = config[DOMAIN].get(CONF_PASSWORD)
    HOMEMATIC_LINK_DELAY = config[DOMAIN].get(CONF_DELAY)
    use_variables = config[DOMAIN].get(CONF_VARIABLES)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    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=SCHEMA_SERVICE_VIRTUALKEY)

    entities = []

    ##
    # init HM variable
    variables = HOMEMATIC.getAllSystemVariables() if use_variables else {}
    hm_var_store = {}
    if variables is not None:
        for key, value in variables.items():
            varia = HMVariable(key, value)
            hm_var_store.update({key: varia})
            entities.append(varia)

    # add homematic entites
    entities.append(HMHub(hm_var_store, use_variables))
    component.add_entities(entities)

    ##
    # register set_value service if exists variables
    if not variables:
        return True

    def _service_handle_value(service):
        """Set value on homematic variable object."""
        variable_list = component.extract_from_service(service)

        value = service.data[ATTR_VALUE]

        for hm_variable in variable_list:
            hm_variable.hm_set(value)

    hass.services.register(DOMAIN,
                           SERVICE_SET_VALUE,
                           _service_handle_value,
                           descriptions[DOMAIN][SERVICE_SET_VALUE],
                           schema=SCHEMA_SERVICE_SET_VALUE)

    return True
Beispiel #16
0
def setup(hass, config):
    """Set up the Homematic component."""
    from pyhomematic import HMConnection

    hass.data[DATA_DELAY] = config[DOMAIN].get(CONF_DELAY)
    hass.data[DATA_DEVINIT] = {}
    hass.data[DATA_STORE] = set()

    # Create hosts-dictionary for pyhomematic
    remotes = {}
    hosts = {}
    for rname, rconfig in config[DOMAIN][CONF_HOSTS].items():
        server = rconfig.get(CONF_IP)

        remotes[rname] = {}
        remotes[rname][CONF_IP] = server
        remotes[rname][CONF_PORT] = rconfig.get(CONF_PORT)
        remotes[rname][CONF_RESOLVENAMES] = rconfig.get(CONF_RESOLVENAMES)
        remotes[rname][CONF_USERNAME] = rconfig.get(CONF_USERNAME)
        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):
            hosts[server] = {
                CONF_VARIABLES: rconfig.get(CONF_VARIABLES),
                CONF_NAME: rname,
            }
        hass.data[DATA_DEVINIT][rname] = rconfig.get(CONF_DEVICES)

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    hass.data[DATA_HOMEMATIC] = HMConnection(
        local=config[DOMAIN].get(CONF_LOCAL_IP),
        localport=config[DOMAIN].get(CONF_LOCAL_PORT),
        remotes=remotes,
        systemcallback=bound_system_callback,
        interface_id='homeassistant'
    )

    # Start server thread, connect to hosts, initialize to receive events
    hass.data[DATA_HOMEMATIC].start()

    # Stops server when HASS is shutting down
    hass.bus.listen_once(
        EVENT_HOMEASSISTANT_STOP, hass.data[DATA_HOMEMATIC].stop)

    # Init homematic hubs
    entity_hubs = []
    for _, hub_data in hosts.items():
        entity_hubs.append(HMHub(
            hass, hub_data[CONF_NAME], hub_data[CONF_VARIABLES]))

    # Register HomeMatic services
    descriptions = load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    def _hm_service_virtualkey(service):
        """Service to handle virtualkey servicecalls."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found for service virtualkey!", address)
            return

        # Parameter doesn't exist for device
        if param not in hmdevice.ACTIONNODE:
            _LOGGER.error("%s not datapoint in hm device %s", param, address)
            return

        # Channel doesn't exist for device
        if channel not in hmdevice.ACTIONNODE[param]:
            _LOGGER.error("%i is not a channel in hm device %s",
                          channel, address)
            return

        # Call parameter
        hmdevice.actionNodeData(param, True, channel)

    hass.services.register(
        DOMAIN, SERVICE_VIRTUALKEY, _hm_service_virtualkey,
        descriptions[DOMAIN][SERVICE_VIRTUALKEY],
        schema=SCHEMA_SERVICE_VIRTUALKEY)

    def _service_handle_value(service):
        """Service to call setValue method for HomeMatic system variable."""
        entity_ids = service.data.get(ATTR_ENTITY_ID)
        name = service.data[ATTR_NAME]
        value = service.data[ATTR_VALUE]

        if entity_ids:
            entities = [entity for entity in entity_hubs if
                        entity.entity_id in entity_ids]
        else:
            entities = entity_hubs

        if not entities:
            _LOGGER.error("No HomeMatic hubs available")
            return

        for hub in entities:
            hub.hm_set_variable(name, value)

    hass.services.register(
        DOMAIN, SERVICE_SET_VAR_VALUE, _service_handle_value,
        descriptions[DOMAIN][SERVICE_SET_VAR_VALUE],
        schema=SCHEMA_SERVICE_SET_VAR_VALUE)

    def _service_handle_reconnect(service):
        """Service to reconnect all HomeMatic hubs."""
        hass.data[DATA_HOMEMATIC].reconnect()

    hass.services.register(
        DOMAIN, SERVICE_RECONNECT, _service_handle_reconnect,
        descriptions[DOMAIN][SERVICE_RECONNECT],
        schema=SCHEMA_SERVICE_RECONNECT)

    def _service_handle_device(service):
        """Service to call setValue method for HomeMatic devices."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)
        value = service.data.get(ATTR_VALUE)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found!", address)
            return

        hmdevice.setValue(param, value, channel)

    hass.services.register(
        DOMAIN, SERVICE_SET_DEV_VALUE, _service_handle_device,
        descriptions[DOMAIN][SERVICE_SET_DEV_VALUE],
        schema=SCHEMA_SERVICE_SET_DEV_VALUE)

    return True
Beispiel #17
0
def setup(hass, config):
    """Setup the Homematic component."""
    global HOMEMATIC, HOMEMATIC_LINK_DELAY
    from pyhomematic import HMConnection

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    local_ip = config[DOMAIN].get(CONF_LOCAL_IP)
    local_port = config[DOMAIN].get(CONF_LOCAL_PORT)
    remote_ip = config[DOMAIN].get(CONF_REMOTE_IP)
    remote_port = config[DOMAIN].get(CONF_REMOTE_PORT)
    resolvenames = config[DOMAIN].get(CONF_RESOLVENAMES)
    username = config[DOMAIN].get(CONF_USERNAME)
    password = config[DOMAIN].get(CONF_PASSWORD)
    HOMEMATIC_LINK_DELAY = config[DOMAIN].get(CONF_DELAY)

    if remote_ip is None or local_ip is None:
        _LOGGER.error("Missing remote CCU/Homegear or local address")
        return False

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    HOMEMATIC = HMConnection(local=local_ip,
                             localport=local_port,
                             remote=remote_ip,
                             remoteport=remote_port,
                             systemcallback=bound_system_callback,
                             resolvenames=resolvenames,
                             rpcusername=username,
                             rpcpassword=password,
                             interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    HOMEMATIC.start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
    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=SCHEMA_SERVICE_VIRTUALKEY)

    entities = []

    ##
    # init HM variable
    variables = HOMEMATIC.getAllSystemVariables()
    if variables is not None:
        for key, value in variables.items():
            entities.append(HMVariable(key, value))

    # add homematic entites
    entities.append(HMHub())
    component.add_entities(entities)

    ##
    # register set_value service if exists variables
    if not variables:
        return True

    def _service_handle_value(service):
        """Set value on homematic variable object."""
        variable_list = component.extract_from_service(service)

        value = service.data[ATTR_VALUE]

        for hm_variable in variable_list:
            hm_variable.hm_set(value)

    hass.services.register(DOMAIN, SERVICE_SET_VALUE,
                           _service_handle_value,
                           descriptions[DOMAIN][SERVICE_SET_VALUE],
                           schema=SCHEMA_SERVICE_SET_VALUE)

    return True
Beispiel #18
0
class Homematic(SmartPlugin):
    """
    Main class of the Plugin. Does all plugin specific stuff and provides
    the update functions for the items
    """
    
    PLUGIN_VERSION = '1.5.0'
#    ALLOW_MULTIINSTANCE = False
    
    connected = False
    

    def __init__(self, sh, *args, **kwargs):
        """
        Initalizes the plugin. The parameters descriptions for this method are pulled from the entry in plugin.yaml.

        :param sh:  **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! 
        :param *args: **Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
        :param **kwargs:**Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
        
        If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
        a reference to the sh object any more.
        
        The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are imlemented
        to support older plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values:
        use the SmartPlugin method get_parameter_value(parameter_name) instead. Anywhere within the Plugin you can get
        the configured (and checked) value for a parameter by calling self.get_parameter_value(parameter_name). It
        returns the value in the datatype that is defined in the metadata.
        """
        self.logger = logging.getLogger(__name__)

        # get the parameters for the plugin (as defined in metadata plugin.yaml):
        #   self.param1 = self.get_parameter_value('param1')
        
        # Initialization code goes here
        self.username = self.get_parameter_value('username')
        self.password = self.get_parameter_value('password')
        self.host = self.get_parameter_value('host')
#        self.port = self.get_parameter_value('port')
#        self.port_hmip = self.get_parameter_value('port_hmip')
        self.port = 2001
        self.port_hmip = 2010

        # build dict identifier for the homematic ccu of this plugin instance
        self.hm_id = 'rf'
        if self.get_instance_name() != '':
            self.hm_id += '_' + self.get_instance_name()
            self.log_instance_str = ' ('+self.get_instance_name()+')'
        else:
            self.log_instance_str = ''
        # create HomeMatic object
        try:
             self.hm = HMConnection(interface_id="myserver", autostart=False, 
                                    eventcallback=self.eventcallback, systemcallback=self.systemcallback, 
                                    remotes={self.hm_id:{"ip": self.host, "port": self.port}})
#                                    remotes={self.hm_id:{"ip": self.host, "port": self.port}, self.hmip_id:{"ip": self.host, "port": self.port_hmip}})
        except:
            self.logger.error("{}: Unable to create HomeMatic object".format(self.get_fullname()))
            self._init_complete = False
            return


        # build dict identifier for the homematicIP ccu of this plugin instance
        if self.port_hmip != 0:
            self.hmip_id = 'ip'
            if self.get_instance_name() != '':
                self.hmip_id += '_' + self.get_instance_name()
            # create HomeMaticIP object
            try:
                 self.hmip = HMConnection(interface_id="myserver_ip", autostart=False, 
                                          eventcallback=self.eventcallback, systemcallback=self.systemcallback, 
                                          remotes={self.hmip_id:{"ip": self.host, "port": self.port_hmip}})
            except:
                self.logger.error("{}: Unable to create HomeMaticIP object".format(self.get_fullname()))
#                self._init_complete = False
#                return


        # set the name of the thread that got created by pyhomematic to something meaningfull 
        self.hm._server.name = self.get_fullname()

        # start communication with HomeMatic ccu
        try:
            self.hm.start()
            self.connected = True
        except:
            self.logger.error("{}: Unable to start HomeMatic object - SmartHomeNG will be unable to terminate the thread vor this plugin (instance)".format(self.get_fullname()))
            self.connected = False
#            self._init_complete = False
            # stop the thread that got created by initializing pyhomematic 
#            self.hm.stop()
#            return

        # start communication with HomeMatic ccu
        try:
            self.hmip.start()
        except:
            self.logger.error("{}: Unable to start HomeMaticIP object".format(self.get_fullname()))

        if self.connected:
            # TO DO: sleep besser lösen!
            sleep(20)
#            self.logger.warning("Plugin '{}': self.hm.devices".format(self.hm.devices))
            if self.hm.devices.get(self.hm_id,{}) == {}:
                self.logger.error("{}: Connection to ccu failed".format(self.get_fullname()))
#                self._init_complete = False
                # stop the thread that got created by initializing pyhomematic 
#                self.hm.stop()
#                return
        
        self.hm_items = []           

        if not self.init_webinterface():
#            self._init_complete = False
            pass

        return


    def run(self):
        """
        Run method for the plugin
        """        
        self.logger.debug("Plugin '{}': run method called".format(self.get_fullname()))
        self.alive = True
        # if you want to create child threads, do not make them daemon = True!
        # They will not shutdown properly. (It's a python bug)


    def stop(self):
        """
        Stop method for the plugin
        """
        self.logger.debug("Plugin '{}': stop method called".format(self.get_fullname()))
        self.alive = False
        self.hm.stop()
        self.hmip.stop()


    def parse_item(self, item):
        """
        Default plugin parse_item method. Is called when the plugin is initialized.
        The plugin can, corresponding to its attribute keywords, decide what to do with
        the item in future, like adding it to an internal array for future reference
        :param item:    The item to process.
        :return:        If the plugin needs to be informed of an items change you should return a call back function
                        like the function update_item down below. An example when this is needed is the knx plugin
                        where parse_item returns the update_item function when the attribute knx_send is found.
                        This means that when the items value is about to be updated, the call back function is called
                        with the item, caller, source and dest as arguments and in case of the knx plugin the value
                        can be sent to the knx with a knx write function within the knx plugin.
        """
        if self.has_iattr(item.conf, 'hm_address'):
            init_error = False
#            self.logger.debug("parse_item{}: {}".format(self.log_instance_str, item))
            dev_id = self.get_iattr_value(item.conf, 'hm_address')


            dev_type = self.get_iattr_value(item.conf, 'hm_type')

            dev_type = '?'
            dev = self.hm.devices[self.hm_id].get(dev_id)
            if dev is None:
                dev = self.hmip.devices[self.hmip_id].get(dev_id)
                if dev is not None:
                    dev_type = 'hmIP'
            else:
                dev_type = 'hm'

            hm_address = self.get_iattr_value(item.conf, 'hm_address')
            hm_channel = self.get_iattr_value(item.conf, 'hm_channel')
            hm_function = self.get_iattr_value(item.conf, 'hm_function')
            hm_node = ''
            if dev is None:
                self.logger.error("parse_item{}: No HomeMatic device found with address '{}' for {}".format(self.log_instance_str, dev_id, item))
#                return

            else:
                hm_devicetype = self.get_hmdevicetype( dev_id )

#                self.logger.warning("{}, parse_item {}: type='{}', hm_address='{}', hm_channel='{}', hm_function='{}', hm_devicetype='{}'".format(self.get_fullname(), item, item.type(), hm_address, hm_channel, hm_function, hm_devicetype))

                # Lookup hm_node and hm_channel for the configured hm_function
                if hm_function is None:
                    hm_function = 'STATE'
                hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.ACTIONNODE, 'AC', item)
                if hm_node == '':
                    hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.ATTRIBUTENODE, 'AT', item)
                if hm_node == '':
                    hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.BINARYNODE, 'BI', item)
                if hm_node == '':
                    hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.EVENTNODE, 'EV', item)
                if hm_node == '':
                    hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.SENSORNODE, 'SE', item)
                if hm_node == '':
                    hm_channel, hm_node = self.get_hmchannelforfunction(hm_function, hm_channel, dev.WRITENODE, 'WR', item)
                        
#                self.logger.warning("{}, parse_item {}: dev.ELEMENT='{}'".format(self.get_fullname(), item, dev.ELEMENT))
            
                self.logger.debug("parse_item{}: {}, type='{}', address={}:{}, function='{}', devicetype='{}'".format(self.log_instance_str, item, item.type(), hm_address, hm_channel, hm_function, hm_devicetype))
                
            if hm_node == '':
                hm_node = None
                
            # store item and device information for plugin instance
            self.hm_items.append( [str(item), item, hm_address, hm_channel, hm_function, hm_node, dev_type] )
            
            # Initialize item from HomeMatic
            if dev is not None:
                value = None
                if hm_node == 'AC':
                    pass     # actionNodeData can not be read for initialization
                    init_error = True
                elif hm_node == 'AT':
                    value = dev.getAttributeData(hm_function)
                elif hm_node == 'BI':
                    value = dev.getBinaryData(hm_function)
                elif hm_node == 'EV':
                    value = dev.event(hm_function)
                elif hm_node == 'SE':
                    value = dev.getSensorData(hm_function)
                elif hm_node == 'WR':
                    value = dev.getWriteData(hm_function)
                else:
                    init_error = True
                    self.logger.error("parse_item{}: Not initializing {}: Unknown hm_node='{}' for address={}:{}, function={}".format(self.log_instance_str, item, hm_node, hm_address, hm_channel, hm_function))

                if value is not None:
                    self.logger.info("parse_item{}: Initializing {} with '{}' from address={}:{}, function={}".format(self.log_instance_str, item, value, hm_address, hm_channel, hm_function))
                    item(value, 'HomeMatic', 'Init')
                else:
                    if not init_error:
                        self.logger.error("parse_item{}: Not initializing {} from address={}:{}, function='{}'".format(self.log_instance_str, item, hm_node, hm_address, hm_channel, hm_function))
                
            return self.update_item


    def parse_logic(self, logic):
        """
        Default plugin parse_logic method
        """
        if 'xxx' in logic.conf:
            # self.function(logic['name'])
            pass


    def update_item(self, item, caller=None, source=None, dest=None):
        """
        Write items values
        :param item: item to be updated towards the plugin
        :param caller: if given it represents the callers name
        :param source: if given it represents the source
        :param dest: if given it represents the dest
        """
        if caller != 'HomeMatic':
            if self.has_iattr(item.conf, 'hm_address'):
#               self.hm_items[] = [str(item), item, hm_address, hm_channel, hm_function, hm_node]
                myitem = None
                for i in self.hm_items:
                    if item == i[1]:
                        myitem = i
                        self.logger.warning("update_item{}: Test: item='{}', caller='{}', hm_function={}, itemvalue='{}'".format(self.log_instance_str, item, caller, i[4], item()))
                
                self.logger.warning("update_item{}: Todo: Called with value '{}' for item '{}' from caller '{}', source '{}' and dest '{}'".format(self.log_instance_str, item(), item, caller, source, dest))

                dev_id = self.get_iattr_value(item.conf, 'hm_address')
                dev = self.hm.devices[self.hm_id].get(dev_id)

                # Write item value to HomeMatic device
                if dev is not None:
                    hm_node = myitem[5]
                    hm_channel = myitem[3]
                    hm_function = myitem[4]
                    dev.CHANNELS[int(hm_channel)].setValue(hm_function, item())
                    self.logger.warning("{}, update_item (hm): Called with value '{}' for item '{}' from caller '{}', source '{}' and dest '{}'".format(self.get_fullname(), item(), item, caller, source, dest))
                else:
                    dev = self.hmip.devices[self.hmip_id].get(dev_id)
                    # Write item value to HomeMaticIP device
                    if dev is not None:
                        hm_node = myitem[5]
                        hm_channel = myitem[3]
                        hm_function = myitem[4]
                        dev.CHANNELS[int(hm_channel)].setValue(hm_function, item())
                        self.logger.warning("{}, update_item (hmIP): Called with value '{}' for item '{}' from caller '{}', source '{}' and dest '{}'".format(self.get_fullname(), item(), item, caller, source, dest))

                # ACTIONNODE: PRESS_LONG (action), PRESS_SHORT (action), [LEVEL (float 0.0-1.0)]
                # LEVEL (float: 0.0-1.0), STOP (action), INHIBIT (bool), INSTALL_TEST (action), 
                #   OLD_LEVEL (action), RAMP_TIME (float 0.0-85825945.6 s), RAMP_STOP (action) 
                #
                # Heizkörperthermostat (HM-CC-RT-DN):
                # SET_TEMPERATURE (float -10.0-50.0), AUTO_MODE (action), MANU_MODE (float 4.5-30.5), BOOST_MODE (action), COMFORT_MODE (action), LOWERING_MODE (action),
                # PARTY_MODE_SUBMIT (string), PARTY_TEMPERATURE (float 5.0-30.0), PARTY_START_TIME (int 0-1410), PARTY_START_DAY (int 0-31), PARTY_START_MONTH (int 1-12), PARTY_START_YEAR (int 0-99),
                # PARTY_STOP_TIME (int), PARTY_STOP_DAY (int), PARTY_STOP_MONTH (int), PARTY_STOP_YEAR (int)
                #
                # Heizkörperthermostat (HM-CC-RT-DN-BoM): 
                # CLEAR_WINDOW_OPEN_SYMBOL (int 0-1), SET_SYMBOL_FOR_HEATING_PHASE (int 0-1), ...
                #
                # Funk- Wandthermostat ab V2.0 (CLIMATECONTROL_REGULATOR)
                # SETPOINT (float 6.0-30.0)
                #
                # KeyMatic:
                # RELOCK_DELAY (float 0.0-65535.0)
                #
                # Statusanzeige 16Kanal LED
                # LED_STATUS (option 0=OFF, 1=RED, 2=GREEN, 3=ORANGE), ALL_LEDS (string), LED_SLEEP_MODE (option 0=OFF, 1=ON)
                #
                # Funk- Fernbedienung 19 Tasten mit Display
                # TEXT (string), BULB (action), SWITCH (action), WINDOW (action), DOOR (action), BLIND (action), SCENE (action), PHONE (action),
                # BELL (action), CLOCK (action), ARROW_UP (action), ARROW_DOWN (action), UNIT (option 0=NONE, 1=PERCENT, 2=WATT, 3=CELSIUS, 4=FAHRENHEIT),
                # BEEP (option 0=NONE, 1-3=TONE1-3), BACKLIGHT (option 0=OFF, 1=ON, 2=BLINK_SLOW, 3=BLINK_FAST), 
                # SUBMIT (action), ALARM_COUNT (int 0-255), SERVICE_COUNT (int 0-255)
                #
                # ON_TIME (float 0.0-85825945.6 s), SUBMIT (string)
                    
                # STATE, LEVEL, STOP (action)


    def init_webinterface(self):
        """"
        Initialize the web interface for this plugin

        This method is only needed if the plugin is implementing a web interface
        """
        try:
            self.mod_http = Modules.get_instance().get_module('http')   # try/except to handle running in a core version that does not support modules
        except:
             self.mod_http = None
        if self.mod_http == None:
            self.logger.error("Plugin '{}': Not initializing the web interface".format(self.get_shortname()))
            return False
        
        import sys
        if not "SmartPluginWebIf" in list(sys.modules['lib.model.smartplugin'].__dict__):
            self.logger.warning("Plugin '{}': Web interface needs SmartHomeNG v1.5 and up. Not initializing the web interface".format(self.get_shortname()))
            return False

        # set application configuration for cherrypy
        webif_dir = self.path_join(self.get_plugin_dir(), 'webif')
        config = {
            '/': {
                'tools.staticdir.root': webif_dir,
            },
            '/static': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': 'static'
            }
        }
        
        # Register the web interface as a cherrypy app
        self.mod_http.register_webif(WebInterface(webif_dir, self), 
                                     self.get_shortname(), 
                                     config, 
                                     self.get_classname(), self.get_instance_name(),
                                     description='')
        return True



# ---------------------------------------------------------
#    Methods of the plugin class for the external device
# ---------------------------------------------------------

    def get_hmdevicetype(self, dev_id):
        """
        get the devicetype for the given device id
        
        :param dev_id: HomeMatic device id
        :param type: str
        
        :return: device type
        :rtype: str
        """
        dev = self.hm.devices[self.hm_id].get(dev_id)
        if dev is not None:
            d_type = str(dev.__class__).replace("<class '"+dev.__module__+'.', '').replace("'>",'')
            return d_type

        dev = self.hmip.devices[self.hmip_id].get(dev_id)
        if dev is not None:
            d_type = str(dev.__class__).replace("<class '"+dev.__module__+'.', '').replace("'>",'')
            return d_type

        return ''


    def get_hmchannelforfunction(self, hm_function, hm_channel, node, hm_node, item):
        """
        Returns the HomeMatic Channel of the deivce for the wanted function
        
        :param hm_function: Configured function (or STATE)
        :param hm_channel: Preconfigured channel or None
        :param node: the node attribute of the Homematic device (e.g. dev.BINARYNODE)
        :param hm_node: short string for the nodename (AT, AC, BI, EV, SE, WR)
        """
        if hm_function in node.keys():
            if hm_channel is None:
                hm_channel = node[hm_function][0]
            else:
                if not int(hm_channel) in node[hm_function]:

                    hm_node = ''
                    self.logger.error("get_hmchannelforfunction{}: Invalid channel '{}' specified for {}".format(self.log_instance_str, hm_channel, item))
        else:
            hm_node = ''
        return hm_channel, hm_node
        

    def systemcallback(self, src, *args):
        self.logger.info("systemcallback{}: src = '{}', args = '{}'".format(self.log_instance_str, src, args))


    def eventcallback(self, interface_id, address, value_key, value):
        """
        Callback method for HomeMatic events

        This method is called whenever the HomeMatic ccu processs an event 
        """
        defined = False
        for i in self.hm_items:
            if address == i[2]+':'+str(i[3]):
                if value_key == i[4]:
                    self.logger.info("eventcallback{}: address={}, {}='{}' -> {}".format(self.log_instance_str, address, value_key, value, i[0]))
#                    i[1](value, 'HomeMatic', address)
                    i[1](value, 'HomeMatic')
                    defined = True

        if not defined:
            self.logger.debug("eventcallback{}: Ohne item Zuordnung: interface_id = '{}', address = '{}', {} = '{}'".format(self.log_instance_str, interface_id, address, value_key, value))
Beispiel #19
0
    def __init__(self, sh, *args, **kwargs):
        """
        Initalizes the plugin.

        If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
        a reference to the sh object any more.

        Plugins have to use the new way of getting parameter values:
        use the SmartPlugin method get_parameter_value(parameter_name). Anywhere within the Plugin you can get
        the configured (and checked) value for a parameter by calling self.get_parameter_value(parameter_name). It
        returns the value in the datatype that is defined in the metadata.
        """

        # Call init code of parent class (SmartPlugin)
        super().__init__()

        # get the parameters for the plugin (as defined in metadata plugin.yaml):
        #   self.param1 = self.get_parameter_value('param1')

        # Initialization code goes here
        self.username = self.get_parameter_value('username')
        self.password = self.get_parameter_value('password')
        self.host = self.get_parameter_value('host')
        #        self.port = self.get_parameter_value('port')
        #        self.port_hmip = self.get_parameter_value('port_hmip')
        self.port = 2001
        self.port_hmip = 2010

        # build dict identifier for the homematic ccu of this plugin instance
        self.hm_id = 'rf'
        if self.get_instance_name() != '':
            self.hm_id += '_' + self.get_instance_name()
        # create HomeMatic object
        try:
            self.hm = HMConnection(
                interface_id="myserver",
                autostart=False,
                eventcallback=self.eventcallback,
                systemcallback=self.systemcallback,
                remotes={self.hm_id: {
                    "ip": self.host,
                    "port": self.port
                }})
#                                    remotes={self.hm_id:{"ip": self.host, "port": self.port}, self.hmip_id:{"ip": self.host, "port": self.port_hmip}})
        except:
            self.logger.error("Unable to create HomeMatic object")
            self._init_complete = False
            return

        # build dict identifier for the homematicIP ccu of this plugin instance
        if self.port_hmip != 0:
            self.hmip_id = 'ip'
            if self.get_instance_name() != '':
                self.hmip_id += '_' + self.get_instance_name()
            # create HomeMaticIP object
            try:
                self.hmip = HMConnection(interface_id="myserver_ip",
                                         autostart=False,
                                         eventcallback=self.eventcallback,
                                         systemcallback=self.systemcallback,
                                         remotes={
                                             self.hmip_id: {
                                                 "ip": self.host,
                                                 "port": self.port_hmip
                                             }
                                         })
            except:
                self.logger.error("Unable to create HomeMaticIP object")
#                self._init_complete = False
#                return

# set the name of the thread that got created by pyhomematic to something meaningfull
        self.hm._server.name = 'plugins.' + self.get_fullname() + '.server'

        # start communication with HomeMatic ccu
        try:
            self.hm.start()
            self.connected = True
        except:
            self.logger.error(
                "Unable to start HomeMatic object - SmartHomeNG will be unable to terminate the thread vor this plugin (instance)"
            )
            self.connected = False
        #            self._init_complete = False
        # stop the thread that got created by initializing pyhomematic
        #            self.hm.stop()
        #            return

        # start communication with HomeMatic ccu
        try:
            self.hmip.start()
        except:
            self.logger.error("{}: Unable to start HomeMaticIP object".format(
                self.get_fullname()))

        if self.connected:
            # TO DO: sleep besser lösen!
            sleep(20)
            #            self.logger.warning("Plugin '{}': self.hm.devices".format(self.hm.devices))
            if self.hm.devices.get(self.hm_id, {}) == {}:
                self.logger.error("Connection to ccu failed")
        #                self._init_complete = False
        # stop the thread that got created by initializing pyhomematic
        #                self.hm.stop()
        #                return

        self.hm_items = []

        self.init_webinterface(WebInterface)

        return
def setup(hass, config):
    """Setup the Homematic component."""
    from pyhomematic import HMConnection

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    hass.data[DATA_DELAY] = config[DOMAIN].get(CONF_DELAY)
    hass.data[DATA_DEVINIT] = {}
    hass.data[DATA_STORE] = []

    # create hosts list for pyhomematic
    remotes = {}
    hosts = {}
    for rname, rconfig in config[DOMAIN][CONF_HOSTS].items():
        server = rconfig.get(CONF_IP)

        remotes[rname] = {}
        remotes[rname][CONF_IP] = server
        remotes[rname][CONF_PORT] = rconfig.get(CONF_PORT)
        remotes[rname][CONF_RESOLVENAMES] = rconfig.get(CONF_RESOLVENAMES)
        remotes[rname][CONF_USERNAME] = rconfig.get(CONF_USERNAME)
        remotes[rname][CONF_PASSWORD] = rconfig.get(CONF_PASSWORD)

        if server not in hosts or rconfig.get(CONF_PRIMARY):
            hosts[server] = {
                CONF_VARIABLES: rconfig.get(CONF_VARIABLES),
                CONF_NAME: rname,
            }
        hass.data[DATA_DEVINIT][rname] = rconfig.get(CONF_DEVICES)

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    hass.data[DATA_HOMEMATIC] = HMConnection(
        local=config[DOMAIN].get(CONF_LOCAL_IP),
        localport=config[DOMAIN].get(CONF_LOCAL_PORT),
        remotes=remotes,
        systemcallback=bound_system_callback,
        interface_id="homeassistant")

    # Start server thread, connect to peer, initialize to receive events
    hass.data[DATA_HOMEMATIC].start()

    # Stops server when Homeassistant is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
                         hass.data[DATA_HOMEMATIC].stop)
    hass.config.components.append(DOMAIN)

    # init homematic hubs
    hub_entities = []
    for _, hub_data in hosts.items():
        hub_entities.append(
            HMHub(hass, component, hub_data[CONF_NAME],
                  hub_data[CONF_VARIABLES]))
    component.add_entities(hub_entities)

    # regeister homematic services
    descriptions = load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    def _hm_service_virtualkey(service):
        """Service handle virtualkey services."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)

        # device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found for service virtualkey!", address)
            return

        # 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 not in hmdevice.ACTIONNODE[param]:
            _LOGGER.error("%i is not a channel in hm device %s", channel,
                          address)
            return

        # call key
        hmdevice.actionNodeData(param, True, channel)

    hass.services.register(DOMAIN,
                           SERVICE_VIRTUALKEY,
                           _hm_service_virtualkey,
                           descriptions[DOMAIN][SERVICE_VIRTUALKEY],
                           schema=SCHEMA_SERVICE_VIRTUALKEY)

    def _service_handle_value(service):
        """Set value on homematic variable object."""
        variable_list = component.extract_from_service(service)

        value = service.data[ATTR_VALUE]

        for hm_variable in variable_list:
            if isinstance(hm_variable, HMVariable):
                hm_variable.hm_set(value)

    hass.services.register(DOMAIN,
                           SERVICE_SET_VAR_VALUE,
                           _service_handle_value,
                           descriptions[DOMAIN][SERVICE_SET_VAR_VALUE],
                           schema=SCHEMA_SERVICE_SET_VAR_VALUE)

    def _service_handle_reconnect(service):
        """Reconnect to all homematic hubs."""
        hass.data[DATA_HOMEMATIC].reconnect()

    hass.services.register(DOMAIN,
                           SERVICE_RECONNECT,
                           _service_handle_reconnect,
                           descriptions[DOMAIN][SERVICE_RECONNECT],
                           schema=SCHEMA_SERVICE_RECONNECT)

    def _service_handle_device(service):
        """Service handle set_dev_value services."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)
        value = service.data.get(ATTR_VALUE)

        # device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found!", address)
            return

        # call key
        hmdevice.setValue(param, value, channel)

    hass.services.register(DOMAIN,
                           SERVICE_SET_DEV_VALUE,
                           _service_handle_device,
                           descriptions[DOMAIN][SERVICE_SET_DEV_VALUE],
                           schema=SCHEMA_SERVICE_SET_DEV_VALUE)

    return True
Beispiel #21
0
    def __init__(self, sh, *args, **kwargs):
        """
        Initalizes the plugin. The parameters descriptions for this method are pulled from the entry in plugin.yaml.

        :param sh:  **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! 
        :param *args: **Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
        :param **kwargs:**Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
        
        If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
        a reference to the sh object any more.
        
        The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are imlemented
        to support older plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values:
        use the SmartPlugin method get_parameter_value(parameter_name) instead. Anywhere within the Plugin you can get
        the configured (and checked) value for a parameter by calling self.get_parameter_value(parameter_name). It
        returns the value in the datatype that is defined in the metadata.
        """
        self.logger = logging.getLogger(__name__)

        # get the parameters for the plugin (as defined in metadata plugin.yaml):
        #   self.param1 = self.get_parameter_value('param1')
        
        # Initialization code goes here
        self.username = self.get_parameter_value('username')
        self.password = self.get_parameter_value('password')
        self.host = self.get_parameter_value('host')
#        self.port = self.get_parameter_value('port')
#        self.port_hmip = self.get_parameter_value('port_hmip')
        self.port = 2001
        self.port_hmip = 2010

        # build dict identifier for the homematic ccu of this plugin instance
        self.hm_id = 'rf'
        if self.get_instance_name() != '':
            self.hm_id += '_' + self.get_instance_name()
            self.log_instance_str = ' ('+self.get_instance_name()+')'
        else:
            self.log_instance_str = ''
        # create HomeMatic object
        try:
             self.hm = HMConnection(interface_id="myserver", autostart=False, 
                                    eventcallback=self.eventcallback, systemcallback=self.systemcallback, 
                                    remotes={self.hm_id:{"ip": self.host, "port": self.port}})
#                                    remotes={self.hm_id:{"ip": self.host, "port": self.port}, self.hmip_id:{"ip": self.host, "port": self.port_hmip}})
        except:
            self.logger.error("{}: Unable to create HomeMatic object".format(self.get_fullname()))
            self._init_complete = False
            return


        # build dict identifier for the homematicIP ccu of this plugin instance
        if self.port_hmip != 0:
            self.hmip_id = 'ip'
            if self.get_instance_name() != '':
                self.hmip_id += '_' + self.get_instance_name()
            # create HomeMaticIP object
            try:
                 self.hmip = HMConnection(interface_id="myserver_ip", autostart=False, 
                                          eventcallback=self.eventcallback, systemcallback=self.systemcallback, 
                                          remotes={self.hmip_id:{"ip": self.host, "port": self.port_hmip}})
            except:
                self.logger.error("{}: Unable to create HomeMaticIP object".format(self.get_fullname()))
#                self._init_complete = False
#                return


        # set the name of the thread that got created by pyhomematic to something meaningfull 
        self.hm._server.name = self.get_fullname()

        # start communication with HomeMatic ccu
        try:
            self.hm.start()
            self.connected = True
        except:
            self.logger.error("{}: Unable to start HomeMatic object - SmartHomeNG will be unable to terminate the thread vor this plugin (instance)".format(self.get_fullname()))
            self.connected = False
#            self._init_complete = False
            # stop the thread that got created by initializing pyhomematic 
#            self.hm.stop()
#            return

        # start communication with HomeMatic ccu
        try:
            self.hmip.start()
        except:
            self.logger.error("{}: Unable to start HomeMaticIP object".format(self.get_fullname()))

        if self.connected:
            # TO DO: sleep besser lösen!
            sleep(20)
#            self.logger.warning("Plugin '{}': self.hm.devices".format(self.hm.devices))
            if self.hm.devices.get(self.hm_id,{}) == {}:
                self.logger.error("{}: Connection to ccu failed".format(self.get_fullname()))
#                self._init_complete = False
                # stop the thread that got created by initializing pyhomematic 
#                self.hm.stop()
#                return
        
        self.hm_items = []           

        if not self.init_webinterface():
#            self._init_complete = False
            pass

        return
Beispiel #22
0
def setup(hass, config):
    """Set up the Homematic component."""
    from pyhomematic import HMConnection

    conf = config[DOMAIN]
    hass.data[DATA_CONF] = remotes = {}
    hass.data[DATA_STORE] = set()

    # Create hosts-dictionary for pyhomematic
    for rname, rconfig in conf[CONF_INTERFACES].items():
        remotes[rname] = {
            'ip': socket.gethostbyname(rconfig.get(CONF_HOST)),
            'port': rconfig.get(CONF_PORT),
            'path': rconfig.get(CONF_PATH),
            'resolvenames': rconfig.get(CONF_RESOLVENAMES),
            'username': rconfig.get(CONF_USERNAME),
            'password': rconfig.get(CONF_PASSWORD),
            'callbackip': rconfig.get(CONF_CALLBACK_IP),
            'callbackport': rconfig.get(CONF_CALLBACK_PORT),
            'connect': True,
        }

    for sname, sconfig in conf[CONF_HOSTS].items():
        remotes[sname] = {
            'ip': socket.gethostbyname(sconfig.get(CONF_HOST)),
            'port': DEFAULT_PORT,
            'username': sconfig.get(CONF_USERNAME),
            'password': sconfig.get(CONF_PASSWORD),
            'connect': False,
        }

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    hass.data[DATA_HOMEMATIC] = homematic = HMConnection(
        local=config[DOMAIN].get(CONF_LOCAL_IP),
        localport=config[DOMAIN].get(CONF_LOCAL_PORT),
        remotes=remotes,
        systemcallback=bound_system_callback,
        interface_id='homeassistant'
    )

    # Start server thread, connect to hosts, initialize to receive events
    homematic.start()

    # Stops server when HASS is shutting down
    hass.bus.listen_once(
        EVENT_HOMEASSISTANT_STOP, hass.data[DATA_HOMEMATIC].stop)

    # Init homematic hubs
    entity_hubs = []
    for hub_name in conf[CONF_HOSTS].keys():
        entity_hubs.append(HMHub(hass, homematic, hub_name))

    def _hm_service_virtualkey(service):
        """Service to handle virtualkey servicecalls."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found for service virtualkey!", address)
            return

        # Parameter doesn't exist for device
        if param not in hmdevice.ACTIONNODE:
            _LOGGER.error("%s not datapoint in hm device %s", param, address)
            return

        # Channel doesn't exist for device
        if channel not in hmdevice.ACTIONNODE[param]:
            _LOGGER.error("%i is not a channel in hm device %s",
                          channel, address)
            return

        # Call parameter
        hmdevice.actionNodeData(param, True, channel)

    hass.services.register(
        DOMAIN, SERVICE_VIRTUALKEY, _hm_service_virtualkey,
        schema=SCHEMA_SERVICE_VIRTUALKEY)

    def _service_handle_value(service):
        """Service to call setValue method for HomeMatic system variable."""
        entity_ids = service.data.get(ATTR_ENTITY_ID)
        name = service.data[ATTR_NAME]
        value = service.data[ATTR_VALUE]

        if entity_ids:
            entities = [entity for entity in entity_hubs if
                        entity.entity_id in entity_ids]
        else:
            entities = entity_hubs

        if not entities:
            _LOGGER.error("No HomeMatic hubs available")
            return

        for hub in entities:
            hub.hm_set_variable(name, value)

    hass.services.register(
        DOMAIN, SERVICE_SET_VARIABLE_VALUE, _service_handle_value,
        schema=SCHEMA_SERVICE_SET_VARIABLE_VALUE)

    def _service_handle_reconnect(service):
        """Service to reconnect all HomeMatic hubs."""
        homematic.reconnect()

    hass.services.register(
        DOMAIN, SERVICE_RECONNECT, _service_handle_reconnect,
        schema=SCHEMA_SERVICE_RECONNECT)

    def _service_handle_device(service):
        """Service to call setValue method for HomeMatic devices."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)
        value = service.data.get(ATTR_VALUE)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found!", address)
            return

        hmdevice.setValue(param, value, channel)

    hass.services.register(
        DOMAIN, SERVICE_SET_DEVICE_VALUE, _service_handle_device,
        schema=SCHEMA_SERVICE_SET_DEVICE_VALUE)

    def _service_handle_install_mode(service):
        """Service to set interface into install mode."""
        interface = service.data.get(ATTR_INTERFACE)
        mode = service.data.get(ATTR_MODE)
        time = service.data.get(ATTR_TIME)
        address = service.data.get(ATTR_ADDRESS)

        homematic.setInstallMode(interface, t=time, mode=mode, address=address)

    hass.services.register(
        DOMAIN, SERVICE_SET_INSTALL_MODE, _service_handle_install_mode,
        schema=SCHEMA_SERVICE_SET_INSTALL_MODE)

    return True
Beispiel #23
0
def setup(hass, config):
    """Set up the Homematic component."""

    conf = config[DOMAIN]
    hass.data[DATA_CONF] = remotes = {}
    hass.data[DATA_STORE] = set()

    # Create hosts-dictionary for pyhomematic
    for rname, rconfig in conf[CONF_INTERFACES].items():
        remotes[rname] = {
            "ip": rconfig.get(CONF_HOST),
            "port": rconfig.get(CONF_PORT),
            "path": rconfig.get(CONF_PATH),
            "resolvenames": rconfig.get(CONF_RESOLVENAMES),
            "jsonport": rconfig.get(CONF_JSONPORT),
            "username": rconfig.get(CONF_USERNAME),
            "password": rconfig.get(CONF_PASSWORD),
            "callbackip": rconfig.get(CONF_CALLBACK_IP),
            "callbackport": rconfig.get(CONF_CALLBACK_PORT),
            "ssl": rconfig.get(CONF_SSL),
            "verify_ssl": rconfig.get(CONF_VERIFY_SSL),
            "connect": True,
        }

    for sname, sconfig in conf[CONF_HOSTS].items():
        remotes[sname] = {
            "ip": sconfig.get(CONF_HOST),
            "port": DEFAULT_PORT,
            "username": sconfig.get(CONF_USERNAME),
            "password": sconfig.get(CONF_PASSWORD),
            "connect": False,
        }

    # Create server thread
    bound_system_callback = partial(_system_callback_handler, hass, config)
    hass.data[DATA_HOMEMATIC] = homematic = HMConnection(
        local=config[DOMAIN].get(CONF_LOCAL_IP),
        localport=config[DOMAIN].get(CONF_LOCAL_PORT, DEFAULT_LOCAL_PORT),
        remotes=remotes,
        systemcallback=bound_system_callback,
        interface_id="homeassistant",
    )

    # Start server thread, connect to hosts, initialize to receive events
    homematic.start()

    # Stops server when HASS is shutting down
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, hass.data[DATA_HOMEMATIC].stop)

    # Init homematic hubs
    entity_hubs = []
    for hub_name in conf[CONF_HOSTS].keys():
        entity_hubs.append(HMHub(hass, homematic, hub_name))

    def _hm_service_virtualkey(service):
        """Service to handle virtualkey servicecalls."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found for service virtualkey!", address)
            return

        # Parameter doesn't exist for device
        if param not in hmdevice.ACTIONNODE:
            _LOGGER.error("%s not datapoint in hm device %s", param, address)
            return

        # Channel doesn't exist for device
        if channel not in hmdevice.ACTIONNODE[param]:
            _LOGGER.error("%i is not a channel in hm device %s", channel, address)
            return

        # Call parameter
        hmdevice.actionNodeData(param, True, channel)

    hass.services.register(
        DOMAIN,
        SERVICE_VIRTUALKEY,
        _hm_service_virtualkey,
        schema=SCHEMA_SERVICE_VIRTUALKEY,
    )

    def _service_handle_value(service):
        """Service to call setValue method for HomeMatic system variable."""
        entity_ids = service.data.get(ATTR_ENTITY_ID)
        name = service.data[ATTR_NAME]
        value = service.data[ATTR_VALUE]

        if entity_ids:
            entities = [
                entity for entity in entity_hubs if entity.entity_id in entity_ids
            ]
        else:
            entities = entity_hubs

        if not entities:
            _LOGGER.error("No HomeMatic hubs available")
            return

        for hub in entities:
            hub.hm_set_variable(name, value)

    hass.services.register(
        DOMAIN,
        SERVICE_SET_VARIABLE_VALUE,
        _service_handle_value,
        schema=SCHEMA_SERVICE_SET_VARIABLE_VALUE,
    )

    def _service_handle_reconnect(service):
        """Service to reconnect all HomeMatic hubs."""
        homematic.reconnect()

    hass.services.register(
        DOMAIN,
        SERVICE_RECONNECT,
        _service_handle_reconnect,
        schema=SCHEMA_SERVICE_RECONNECT,
    )

    def _service_handle_device(service):
        """Service to call setValue method for HomeMatic devices."""
        address = service.data.get(ATTR_ADDRESS)
        channel = service.data.get(ATTR_CHANNEL)
        param = service.data.get(ATTR_PARAM)
        value = service.data.get(ATTR_VALUE)
        value_type = service.data.get(ATTR_VALUE_TYPE)

        # Convert value into correct XML-RPC Type.
        # https://docs.python.org/3/library/xmlrpc.client.html#xmlrpc.client.ServerProxy
        if value_type:
            if value_type == "int":
                value = int(value)
            elif value_type == "double":
                value = float(value)
            elif value_type == "boolean":
                value = bool(value)
            elif value_type == "dateTime.iso8601":
                value = datetime.strptime(value, "%Y%m%dT%H:%M:%S")
            else:
                # Default is 'string'
                value = str(value)

        # Device not found
        hmdevice = _device_from_servicecall(hass, service)
        if hmdevice is None:
            _LOGGER.error("%s not found!", address)
            return

        hmdevice.setValue(param, value, channel)

    hass.services.register(
        DOMAIN,
        SERVICE_SET_DEVICE_VALUE,
        _service_handle_device,
        schema=SCHEMA_SERVICE_SET_DEVICE_VALUE,
    )

    def _service_handle_install_mode(service):
        """Service to set interface into install mode."""
        interface = service.data.get(ATTR_INTERFACE)
        mode = service.data.get(ATTR_MODE)
        time = service.data.get(ATTR_TIME)
        address = service.data.get(ATTR_ADDRESS)

        homematic.setInstallMode(interface, t=time, mode=mode, address=address)

    hass.services.register(
        DOMAIN,
        SERVICE_SET_INSTALL_MODE,
        _service_handle_install_mode,
        schema=SCHEMA_SERVICE_SET_INSTALL_MODE,
    )

    def _service_put_paramset(service):
        """Service to call the putParamset method on a HomeMatic connection."""
        interface = service.data.get(ATTR_INTERFACE)
        address = service.data.get(ATTR_ADDRESS)
        paramset_key = service.data.get(ATTR_PARAMSET_KEY)
        # When passing in the paramset from a YAML file we get an OrderedDict
        # here instead of a dict, so add this explicit cast.
        # The service schema makes sure that this cast works.
        paramset = dict(service.data.get(ATTR_PARAMSET))

        _LOGGER.debug(
            "Calling putParamset: %s, %s, %s, %s",
            interface,
            address,
            paramset_key,
            paramset,
        )
        homematic.putParamset(interface, address, paramset_key, paramset)

    hass.services.register(
        DOMAIN,
        SERVICE_PUT_PARAMSET,
        _service_put_paramset,
        schema=SCHEMA_SERVICE_PUT_PARAMSET,
    )

    return True