Beispiel #1
0
def setup(hass, config):
    """Set up the Route53 component."""
    domain = config[DOMAIN][CONF_DOMAIN]
    records = config[DOMAIN][CONF_RECORDS]
    zone = config[DOMAIN][CONF_ZONE]
    aws_access_key_id = config[DOMAIN][CONF_ACCESS_KEY_ID]
    aws_secret_access_key = config[DOMAIN][CONF_SECRET_ACCESS_KEY]
    ttl = config[DOMAIN][CONF_TTL]

    def update_records_interval(now):
        """Set up recurring update."""
        _update_route53(
            aws_access_key_id,
            aws_secret_access_key,
            zone,
            domain,
            records,
            ttl
        )

    def update_records_service(now):
        """Set up service for manual trigger."""
        _update_route53(
            aws_access_key_id,
            aws_secret_access_key,
            zone,
            domain,
            records,
            ttl
        )

    track_time_interval(hass, update_records_interval, INTERVAL)

    hass.services.register(DOMAIN, 'update_records', update_records_service)
    return True
Beispiel #2
0
def setup(hass, config):
    """Set up the UpCloud component."""
    import upcloud_api

    conf = config[DOMAIN]
    username = conf.get(CONF_USERNAME)
    password = conf.get(CONF_PASSWORD)
    scan_interval = conf.get(CONF_SCAN_INTERVAL)

    manager = upcloud_api.CloudManager(username, password)

    try:
        manager.authenticate()
        hass.data[DATA_UPCLOUD] = UpCloud(manager)
    except upcloud_api.UpCloudAPIError:
        _LOGGER.error("Authentication failed.")
        return False

    def upcloud_update(event_time):
        """Call UpCloud to update information."""
        _LOGGER.debug("Updating UpCloud component")
        hass.data[DATA_UPCLOUD].update()
        dispatcher_send(hass, SIGNAL_UPDATE_UPCLOUD)

    # Call the UpCloud API to refresh data
    track_time_interval(hass, upcloud_update, scan_interval)

    return True
Beispiel #3
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the Gearbest sensor."""
    from gearbest_parser import CurrencyConverter
    currency = config.get(CONF_CURRENCY)

    sensors = []
    items = config.get(CONF_ITEMS)

    converter = CurrencyConverter()
    converter.update()

    for item in items:
        try:
            sensors.append(GearbestSensor(converter, item, currency))
        except ValueError as exc:
            _LOGGER.error(exc)

    def currency_update(event_time):
        """Update currency list."""
        converter.update()

    track_time_interval(hass,
                        currency_update,
                        MIN_TIME_BETWEEN_CURRENCY_UPDATES)

    add_devices(sensors, True)
def setup(hass, config):
    """Set up the Hunter Hydrawise component."""
    conf = config[DOMAIN]
    access_token = conf[CONF_ACCESS_TOKEN]
    scan_interval = conf.get(CONF_SCAN_INTERVAL)

    try:
        from hydrawiser.core import Hydrawiser

        hydrawise = Hydrawiser(user_token=access_token)
        hass.data[DATA_HYDRAWISE] = HydrawiseHub(hydrawise)
    except (ConnectTimeout, HTTPError) as ex:
        _LOGGER.error(
            "Unable to connect to Hydrawise cloud service: %s", str(ex))
        hass.components.persistent_notification.create(
            'Error: {}<br />'
            'You will need to restart hass after fixing.'
            ''.format(ex),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    def hub_refresh(event_time):
        """Call Hydrawise hub to refresh information."""
        _LOGGER.debug("Updating Hydrawise Hub component")
        hass.data[DATA_HYDRAWISE].data.update_controller_info()
        dispatcher_send(hass, SIGNAL_UPDATE_HYDRAWISE)

    # Call the Hydrawise API to refresh updates
    track_time_interval(hass, hub_refresh, scan_interval)

    return True
Beispiel #5
0
def setup(hass, config):
    """Set up the Melnor RainCloud component."""
    conf = config[DOMAIN]
    username = conf.get(CONF_USERNAME)
    password = conf.get(CONF_PASSWORD)
    scan_interval = conf.get(CONF_SCAN_INTERVAL)

    try:
        from raincloudy.core import RainCloudy

        raincloud = RainCloudy(username=username, password=password)
        if not raincloud.is_connected:
            raise HTTPError
        hass.data[DATA_RAINCLOUD] = RainCloudHub(raincloud)
    except (ConnectTimeout, HTTPError) as ex:
        _LOGGER.error("Unable to connect to Rain Cloud service: %s", str(ex))
        hass.components.persistent_notification.create(
            'Error: {}<br />'
            'You will need to restart hass after fixing.'
            ''.format(ex),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    def hub_refresh(event_time):
        """Call Raincloud hub to refresh information."""
        _LOGGER.debug("Updating RainCloud Hub component.")
        hass.data[DATA_RAINCLOUD].data.update()
        dispatcher_send(hass, SIGNAL_UPDATE_RAINCLOUD)

    # Call the Raincloud API to refresh updates
    track_time_interval(hass, hub_refresh, scan_interval)

    return True
Beispiel #6
0
    def __init__(self, hass, config, see, data):
        """Initialize the Mercedes ME device tracker."""
        self.see = see
        self.data = data
        self.update_info()

        track_time_interval(
            hass, self.update_info, MIN_TIME_BETWEEN_SCANS)
Beispiel #7
0
def setup(hass, config):
    """Set up the component."""
    hass.data[DOMAIN] = {}
    hass.data[DOMAIN_DATA] = {}
    _LOGGER.info('Starting setup')
    _LOGGER.warning(' %s is starting, report any issues to %s', __version__, COMPONENT_REPO)
    host = config[DOMAIN][CONF_HOST]
    api = config[DOMAIN][CONF_API_KEY]
    hass.data[DOMAIN][CONF_HOST] = host
    hass.data[DOMAIN][CONF_API_KEY] = api

    def restart_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'sb.restart')

    def update_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'sb.update')

    def shutdown_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'sb.shutdown')

    def clearlogs_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'clear.logs')

    def clearhistory_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'clear.history')

    def forcepropersearch_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'sb.propersearch')

    def forcedailysearch_sickrage_service(call):
        """Set up recuring update."""
        generic_command(host, api, 'sb.dailysearch')

    def sensor_update(call):
        """Update sensor values"""
        result = generic_command(host, api, 'shows.stats')
        for attr in ATTRIBUTES:
            _LOGGER.debug('Updating value for %s', attr)
            hass.data[DOMAIN_DATA][attr] = result['data'][attr]
        hass.states.set('sensor.' + DOMAIN, result['result'], hass.data[DOMAIN_DATA])
        _LOGGER.debug('Update done...')

    hass.services.register(DOMAIN, 'restart', restart_sickrage_service)
    hass.services.register(DOMAIN, 'update', update_sickrage_service)
    hass.services.register(DOMAIN, 'shutdown', shutdown_sickrage_service)
    hass.services.register(DOMAIN, 'clearlogs', clearlogs_sickrage_service)
    hass.services.register(DOMAIN, 'clearhistory', clearhistory_sickrage_service)
    hass.services.register(DOMAIN, 'forcepropersearch', forcepropersearch_sickrage_service)
    hass.services.register(DOMAIN, 'forcedailysearch', forcedailysearch_sickrage_service)
    track_time_interval(hass, sensor_update, INTERVAL)
    sensor_update(None)
    return True
Beispiel #8
0
def setup(hass, config):
    """Set up MercedesMe System."""
    from mercedesmejsonpy.controller import Controller
    from mercedesmejsonpy import Exceptions

    conf = config[DOMAIN]
    username = conf.get(CONF_USERNAME)
    password = conf.get(CONF_PASSWORD)
    scan_interval = conf.get(CONF_SCAN_INTERVAL)

    try:
        mercedesme_api = Controller(username, password, scan_interval)
        if not mercedesme_api.is_valid_session:
            raise Exceptions.MercedesMeException(500)
        hass.data[DATA_MME] = MercedesMeHub(mercedesme_api)
    except Exceptions.MercedesMeException as ex:
        if ex.code == 401:
            hass.components.persistent_notification.create(
                "Error:<br />Please check username and password."
                "You will need to restart Home Assistant after fixing.",
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)
        else:
            hass.components.persistent_notification.create(
                "Error:<br />Can't communicate with Mercedes me API.<br />"
                "Error code: {} Reason: {}"
                "You will need to restart Home Assistant after fixing."
                "".format(ex.code, ex.message),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)

        _LOGGER.error("Unable to communicate with Mercedes me API: %s",
                      ex.message)
        return False

    discovery.load_platform(hass, 'sensor', DOMAIN, {}, config)
    discovery.load_platform(hass, 'device_tracker', DOMAIN, {}, config)
    discovery.load_platform(hass, 'binary_sensor', DOMAIN, {}, config)

    def hub_refresh(event_time):
        """Call Mercedes me API to refresh information."""
        _LOGGER.info("Updating Mercedes me component.")
        hass.data[DATA_MME].data.update()
        dispatcher_send(hass, SIGNAL_UPDATE_MERCEDESME)

    track_time_interval(
        hass,
        hub_refresh,
        timedelta(seconds=scan_interval))

    return True
def setup(hass, config):
    """Set up an Arlo component."""
    conf = config[DOMAIN]
    username = conf.get(CONF_USERNAME)
    password = conf.get(CONF_PASSWORD)
    scan_interval = conf.get(CONF_SCAN_INTERVAL)

    try:
        from pyarlo import PyArlo

        arlo = PyArlo(username, password, preload=False)
        if not arlo.is_connected:
            return False

        # assign refresh period to base station thread
        arlo_base_station = next((
            station for station in arlo.base_stations), None)

        if arlo_base_station is not None:
            arlo_base_station.refresh_rate = scan_interval.total_seconds()
        elif not arlo.cameras:
            _LOGGER.error("No Arlo camera or base station available.")
            return False

        hass.data[DATA_ARLO] = arlo

    except (ConnectTimeout, HTTPError) as ex:
        _LOGGER.error("Unable to connect to Netgear Arlo: %s", str(ex))
        hass.components.persistent_notification.create(
            'Error: {}<br />'
            'You will need to restart hass after fixing.'
            ''.format(ex),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    def hub_refresh(event_time):
        """Call ArloHub to refresh information."""
        _LOGGER.debug("Updating Arlo Hub component")
        hass.data[DATA_ARLO].update(update_cameras=True,
                                    update_base_station=True)
        dispatcher_send(hass, SIGNAL_UPDATE_ARLO)

    # register service
    hass.services.register(DOMAIN, 'update', hub_refresh)

    # register scan interval for ArloHub
    track_time_interval(hass, hub_refresh, scan_interval)
    return True
Beispiel #10
0
    def test_track_time_interval(self):
        """Test tracking time interval."""
        specific_runs = []

        utc_now = dt_util.utcnow()
        unsub = track_time_interval(
            self.hass, lambda x: specific_runs.append(1),
            timedelta(seconds=10)
        )

        self._send_time_changed(utc_now + timedelta(seconds=5))
        self.hass.block_till_done()
        self.assertEqual(0, len(specific_runs))

        self._send_time_changed(utc_now + timedelta(seconds=13))
        self.hass.block_till_done()
        self.assertEqual(1, len(specific_runs))

        self._send_time_changed(utc_now + timedelta(minutes=20))
        self.hass.block_till_done()
        self.assertEqual(2, len(specific_runs))

        unsub()

        self._send_time_changed(utc_now + timedelta(seconds=30))
        self.hass.block_till_done()
        self.assertEqual(2, len(specific_runs))
Beispiel #11
0
    def __init__(self, hass, name, use_variables):
        """Initialize HomeMatic hub."""
        self.hass = hass
        self.entity_id = "{}.{}".format(DOMAIN, name.lower())
        self._homematic = hass.data[DATA_HOMEMATIC]
        self._variables = {}
        self._name = name
        self._state = STATE_UNKNOWN
        self._use_variables = use_variables

        # Load data
        track_time_interval(hass, self._update_hub, SCAN_INTERVAL_HUB)
        self._update_hub(None)

        if self._use_variables:
            track_time_interval(
                hass, self._update_variables, SCAN_INTERVAL_VARIABLES)
            self._update_variables(None)
Beispiel #12
0
def setup(hass, config):
    """Set up the Transmission Component."""
    host = config[DOMAIN][CONF_HOST]
    username = config[DOMAIN].get(CONF_USERNAME)
    password = config[DOMAIN].get(CONF_PASSWORD)
    port = config[DOMAIN][CONF_PORT]
    scan_interval = config[DOMAIN][CONF_SCAN_INTERVAL]

    import transmissionrpc
    from transmissionrpc.error import TransmissionError
    try:
        api = transmissionrpc.Client(
            host, port=port, user=username, password=password)
        api.session_stats()
    except TransmissionError as error:
        if str(error).find("401: Unauthorized"):
            _LOGGER.error("Credentials for"
                          " Transmission client are not valid")
        return False

    tm_data = hass.data[DATA_TRANSMISSION] = TransmissionData(
        hass, config, api)

    tm_data.update()
    tm_data.init_torrent_list()

    def refresh(event_time):
        """Get the latest data from Transmission."""
        tm_data.update()

    track_time_interval(hass, refresh, scan_interval)

    sensorconfig = {
        'sensors': config[DOMAIN][CONF_MONITORED_CONDITIONS],
        'client_name': config[DOMAIN][CONF_NAME]}

    discovery.load_platform(hass, 'sensor', DOMAIN, sensorconfig, config)

    if config[DOMAIN][TURTLE_MODE]:
        discovery.load_platform(hass, 'switch', DOMAIN, sensorconfig, config)

    return True
def setup(hass, config):
    """Set up the Mopar component."""
    import motorparts

    conf = config[DOMAIN]
    cookie = hass.config.path(COOKIE_FILE)
    try:
        session = motorparts.get_session(
            conf[CONF_USERNAME],
            conf[CONF_PASSWORD],
            conf[CONF_PIN],
            cookie_path=cookie
        )
    except motorparts.MoparError:
        _LOGGER.error("Failed to login")
        return False

    data = hass.data[DOMAIN] = MoparData(hass, session)
    data.update(now=None)

    track_time_interval(
        hass, data.update, conf[CONF_SCAN_INTERVAL]
    )

    def handle_horn(call):
        """Enable the horn on the Mopar vehicle."""
        data.actuate('horn', call.data[ATTR_VEHICLE_INDEX])

    hass.services.register(
        DOMAIN,
        SERVICE_HORN,
        handle_horn,
        schema=SERVICE_HORN_SCHEMA
    )

    for platform in SUPPORTED_PLATFORMS:
        load_platform(hass, platform, DOMAIN, {}, config)

    return True
Beispiel #14
0
    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(
                hass, self._update_info, MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error('You have specified invalid login credentials')
            self.success_init = False
Beispiel #15
0
def setup(hass, config):
    """Set up the Cloudflare component."""
    from pycfdns import CloudflareUpdater

    cfupdate = CloudflareUpdater()
    email = config[DOMAIN][CONF_EMAIL]
    key = config[DOMAIN][CONF_API_KEY]
    zone = config[DOMAIN][CONF_ZONE]
    records = config[DOMAIN][CONF_RECORDS]

    def update_records_interval(now):
        """Set up recurring update."""
        _update_cloudflare(cfupdate, email, key, zone, records)

    def update_records_service(now):
        """Set up service for manual trigger."""
        _update_cloudflare(cfupdate, email, key, zone, records)

    track_time_interval(hass, update_records_interval, INTERVAL)
    hass.services.register(
        DOMAIN, 'update_records', update_records_service)
    return True
Beispiel #16
0
    def turn_on(self, **kwargs):
        """Turn on flux."""
        if self.is_on:
            return

        # Make initial update
        self.flux_update()

        self.unsub_tracker = track_time_interval(
            self.hass,
            self.flux_update,
            datetime.timedelta(seconds=self._interval))

        self.schedule_update_ha_state()
    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]

        try:
            credfile = "{}.{}".format(hass.config.path(CREDENTIALS_FILE),
                                      slugify(self.username))
            self.service = Service(self.username, self.password, credfile)
            self._update_info()

            track_time_interval(
                hass, self._update_info, MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error("You have specified invalid login credentials")
            self.success_init = False
Beispiel #18
0
def setup(hass, config):
    """Set up the Yeelight bulbs."""
    conf = config.get(DOMAIN, {})
    yeelight_data = hass.data[DATA_YEELIGHT] = {}

    def device_discovered(service, info):
        _LOGGER.debug("Adding autodetected %s", info['hostname'])

        device_type = info['device_type']

        name = "yeelight_%s_%s" % (device_type,
                                   info['properties']['mac'])
        ipaddr = info[CONF_HOST]
        device_config = DEVICE_SCHEMA({
            CONF_NAME: name,
            CONF_MODEL: device_type
        })

        _setup_device(hass, config, ipaddr, device_config)

    discovery.listen(hass, SERVICE_YEELIGHT, device_discovered)

    def update(event):
        for device in yeelight_data.values():
            device.update()

    track_time_interval(
        hass, update, conf.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL)
    )

    if DOMAIN in config:
        for ipaddr, device_config in conf[CONF_DEVICES].items():
            _LOGGER.debug("Adding configured %s", device_config[CONF_NAME])
            _setup_device(hass, config, ipaddr, device_config)

    return True
Beispiel #19
0
 def _init_regular_updates(self):
     """Schedule regular updates based on configured time interval."""
     track_time_interval(self._hass, lambda now: self._update(),
                         DEFAULT_UPDATE_INTERVAL)
def setup(hass, config):
    """Set up this component."""
    conf_track = config[DOMAIN][CONF_TRACK]
    conf_hide_sensor = config[DOMAIN][CONF_HIDE_SENSOR]
    config_show_installabe = config[DOMAIN][CONF_SHOW_INSTALLABLE]
    conf_card_urls = [DEFAULT_REMOTE_CARD_CONFIG_URL
                      ] + config[DOMAIN][CONF_CARD_CONFIG_URLS]
    conf_component_urls = [DEFAULT_REMOTE_COMPONENT_CONFIG_URL
                           ] + config[DOMAIN][CONF_COMPONENT_CONFIG_URLS]

    _LOGGER.info(
        'version %s is starting, if you have ANY issues with this, please report'
        ' them here: https://github.com/custom-components/custom_updater',
        __version__)

    ha_conf_dir = str(hass.config.path())
    if 'cards' in conf_track:
        card_controller = CustomCards(hass, ha_conf_dir, conf_hide_sensor,
                                      conf_card_urls, config_show_installabe)
        track_time_interval(hass, card_controller.cache_versions, INTERVAL)
    if 'components' in conf_track:
        components_controller = CustomComponents(hass, ha_conf_dir,
                                                 conf_hide_sensor,
                                                 conf_component_urls,
                                                 config_show_installabe)
        track_time_interval(hass, components_controller.cache_versions,
                            INTERVAL)

    def check_all_service(call):
        """Set up service for manual trigger."""
        if not conf_track or 'cards' in conf_track:
            card_controller.cache_versions()
        if not conf_track or 'components' in conf_track:
            components_controller.cache_versions()

    def update_all_service(call):
        """Set up service for manual trigger."""
        if not conf_track or 'cards' in conf_track:
            card_controller.update_all()
        if not conf_track or 'components' in conf_track:
            components_controller.update_all()

    def install_service(call):
        """install single component/card"""
        element = call.data.get(ATTR_ELEMENT)
        _LOGGER.debug('Installing %s', element)
        card_controller.install(element)
        components_controller.install(element)

    if not conf_track or 'cards' in conf_track:

        def upgrade_card_service(call):
            """Set up service for manual trigger."""
            card_controller.upgrade_single(call.data.get(ATTR_CARD), 'auto')

        hass.services.register(DOMAIN, 'upgrade_single_card',
                               upgrade_card_service)

    if not conf_track or 'components' in conf_track:

        def upgrade_component_service(call):
            """Set up service for manual trigger."""
            components_controller.upgrade_single(call.data.get(ATTR_COMPONENT))

        hass.services.register(DOMAIN, 'upgrade_single_component',
                               upgrade_component_service)

    hass.services.register(DOMAIN, 'check_all', check_all_service)
    hass.services.register(DOMAIN, 'update_all', update_all_service)
    hass.services.register(DOMAIN, 'install', install_service)
    return True
def setup(hass, config):
    """Setting up Unified Remote Integration"""
    # Fetching configuration entries.
    hosts = config[DOMAIN].get(CONF_HOSTS)
    retry_delay = config[DOMAIN].get(CONF_RETRY)
    if retry_delay > 120:
        retry_delay = 120

    if not init_computers(hosts):
        return False

    def keep_alive(call):
        """Keep host listening our requests"""
        for computer in COMPUTERS:
            try:
                response = computer.connection.exe_remote("", "")
                _LOGGER.debug("Keep alive packet sent")
                _LOGGER.debug(
                    f"Keep alive packet response: {response.content.decode('ascii')}"
                )
                validate_response(response)
            # If there's an connection error, try to reconnect.
            except ConnectionError:
                try:
                    _LOGGER.debug(f"Trying to reconnect with {computer.host}")
                    computer.reconnect()
                except Exception as error:
                    computer.set_unavailable()
                    _LOGGER.debug(
                        f"Unable to connect with {computer.host}. Headers: {computer.connection.get_headers()}"
                    )
                    _LOGGER.debug(f"Error: {error}")
                    pass

    def handle_call(call):
        """Handle the service call."""
        # Fetch service data.
        target = remote_name = call.data.get("target")
        if target is None or target.strip() == "":
            computer = COMPUTERS[0]
        else:
            computer = find_computer(target)

        if computer is None:
            _LOGGER.error(f"No such computer called {target}")
            return None

        remote_name = call.data.get("remote", DEFAULT_NAME)
        remote_id = call.data.get("remote_id", DEFAULT_NAME)
        action = call.data.get("action", DEFAULT_NAME)
        extras = call.data.get("extras")

        # Allows user to pass remote id without declaring it on remotes.yml
        if remote_id is not None:
            if not (remote_id == "" or action == ""):
                computer.call_remote(remote_id, action, extras)
                return None

        # Check if none or empty service data was parsed.
        if not (remote_name == "" or action == ""):
            remote = REMOTES.get_remote(remote_name)
            # Check if remote was declared on remotes.yml.
            if remote is None:
                _LOGGER.warning(
                    f"Remote {remote_name} not found Please check your remotes.yml"
                )
                return None
            # Fetch remote id.
            remote_id = remote["id"]
            # Check if given action exists in remote control list.
            if action in remote["controls"]:
                computer.call_remote(remote_id, action, extras)
            else:
                # Log if called remote doens't exists on remotes.yml.
                _LOGGER.warning(
                    f'Action "{action}" doesn\'t exists for remote {remote_name} Please check your remotes.yml'
                )

    # Register remote call service.
    hass.services.register(DOMAIN, "call", handle_call)
    # Set "keep_alive()" function to be called every 2 minutes (120 seconds).
    # 2 minutes (120 seconds) are the max interval to keep connection alive.
    # So you can just decrease this delay, otherwise, the connection will not
    # be persistent.
    track_time_interval(hass, keep_alive, timedelta(seconds=retry_delay))

    return True
Beispiel #22
0
def setup(hass, config):
    """Set up the Wink component."""
    import pywink
    from pubnubsubhandler import PubNubSubscriptionHandler

    if hass.data.get(DOMAIN) is None:
        hass.data[DOMAIN] = {
            'unique_ids': [],
            'entities': {},
            'oauth': {},
            'configuring': {},
            'pubnub': None,
            'configurator': False
        }

    if config.get(DOMAIN) is not None:
        client_id = config[DOMAIN].get(ATTR_CLIENT_ID)
        client_secret = config[DOMAIN].get(ATTR_CLIENT_SECRET)
        email = config[DOMAIN].get(CONF_EMAIL)
        password = config[DOMAIN].get(CONF_PASSWORD)
        local_control = config[DOMAIN].get(CONF_LOCAL_CONTROL)
    else:
        client_id = None
        client_secret = None
        email = None
        password = None
        local_control = None
        hass.data[DOMAIN]['configurator'] = True
    if None not in [client_id, client_secret]:
        _LOGGER.info("Using legacy OAuth authentication")
        if not local_control:
            pywink.disable_local_control()
        hass.data[DOMAIN]["oauth"]["client_id"] = client_id
        hass.data[DOMAIN]["oauth"]["client_secret"] = client_secret
        hass.data[DOMAIN]["oauth"]["email"] = email
        hass.data[DOMAIN]["oauth"]["password"] = password
        pywink.legacy_set_wink_credentials(email, password,
                                           client_id, client_secret)
    else:
        _LOGGER.info("Using OAuth authentication")
        if not local_control:
            pywink.disable_local_control()
        config_path = hass.config.path(WINK_CONFIG_FILE)
        if os.path.isfile(config_path):
            config_file = load_json(config_path)
            if config_file == DEFAULT_CONFIG:
                _request_app_setup(hass, config)
                return True
            # else move on because the user modified the file
        else:
            save_json(config_path, DEFAULT_CONFIG)
            _request_app_setup(hass, config)
            return True

        if DOMAIN in hass.data[DOMAIN]['configuring']:
            _configurator = hass.data[DOMAIN]['configuring']
            hass.components.configurator.request_done(_configurator.pop(
                DOMAIN))

        # Using oauth
        access_token = config_file.get(ATTR_ACCESS_TOKEN)
        refresh_token = config_file.get(ATTR_REFRESH_TOKEN)

        # This will be called after authorizing Home-Assistant
        if None not in (access_token, refresh_token):
            pywink.set_wink_credentials(config_file.get(ATTR_CLIENT_ID),
                                        config_file.get(ATTR_CLIENT_SECRET),
                                        access_token=access_token,
                                        refresh_token=refresh_token)
        # This is called to create the redirect so the user can Authorize
        # Home .
        else:

            redirect_uri = '{}{}'.format(
                hass.config.api.base_url, WINK_AUTH_CALLBACK_PATH)

            wink_auth_start_url = pywink.get_authorization_url(
                config_file.get(ATTR_CLIENT_ID), redirect_uri)
            hass.http.register_redirect(WINK_AUTH_START, wink_auth_start_url)
            hass.http.register_view(WinkAuthCallbackView(
                config, config_file, pywink.request_token))
            _request_oauth_completion(hass, config)
            return True

    pywink.set_user_agent(USER_AGENT)
    hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler(
        pywink.get_subscription_key())

    def _subscribe():
        hass.data[DOMAIN]['pubnub'].subscribe()

    # Call subscribe after the user sets up wink via the configurator
    # All other methods will complete setup before
    # EVENT_HOMEASSISTANT_START is called meaning they
    # will call subscribe via the method below. (start_subscription)
    if hass.data[DOMAIN]['configurator']:
        _subscribe()

    def keep_alive_call(event_time):
        """Call the Wink API endpoints to keep PubNub working."""
        _LOGGER.info("Polling the Wink API to keep PubNub updates flowing")
        pywink.set_user_agent(str(int(time.time())))
        _temp_response = pywink.get_user()
        _LOGGER.debug(str(json.dumps(_temp_response)))
        time.sleep(1)
        pywink.set_user_agent(USER_AGENT)
        _temp_response = pywink.wink_api_fetch()
        _LOGGER.debug(str(json.dumps(_temp_response)))

    # Call the Wink API every hour to keep PubNub updates flowing
    track_time_interval(hass, keep_alive_call, timedelta(minutes=60))

    def start_subscription(event):
        """Start the PubNub subscription."""
        _subscribe()

    hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)

    def stop_subscription(event):
        """Stop the PubNub subscription."""
        hass.data[DOMAIN]['pubnub'].unsubscribe()
        hass.data[DOMAIN]['pubnub'] = None

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)

    def save_credentials(event):
        """Save currently set OAuth credentials."""
        if hass.data[DOMAIN]["oauth"].get("email") is None:
            config_path = hass.config.path(WINK_CONFIG_FILE)
            _config = pywink.get_current_oauth_credentials()
            save_json(config_path, _config)

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, save_credentials)

    # Save the users potentially updated oauth credentials at a regular
    # interval to prevent them from being expired after a HA reboot.
    track_time_interval(hass, save_credentials, timedelta(minutes=60))

    def force_update(call):
        """Force all devices to poll the Wink API."""
        _LOGGER.info("Refreshing Wink states from API")
        for entity_list in hass.data[DOMAIN]['entities'].values():
            # Throttle the calls to Wink API
            for entity in entity_list:
                time.sleep(1)
                entity.schedule_update_ha_state(True)

    hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update)

    def pull_new_devices(call):
        """Pull new devices added to users Wink account since startup."""
        _LOGGER.info("Getting new devices from Wink API")
        for _component in WINK_COMPONENTS:
            discovery.load_platform(hass, _component, DOMAIN, {}, config)

    hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices)

    def set_pairing_mode(call):
        """Put the hub in provided pairing mode."""
        hub_name = call.data.get('hub_name')
        pairing_mode = call.data.get('pairing_mode')
        kidde_code = call.data.get('kidde_radio_code')
        for hub in WINK_HUBS:
            if hub.name() == hub_name:
                hub.pair_new_device(pairing_mode, kidde_radio_code=kidde_code)

    def rename_device(call):
        """Set specified device's name."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            name = call.data.get('name')
            found_device.wink.set_name(name)

    hass.services.register(DOMAIN, SERVICE_RENAME_DEVICE, rename_device,
                           schema=RENAME_DEVICE_SCHEMA)

    def delete_device(call):
        """Delete specified device."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            found_device.wink.remove_device()

    hass.services.register(DOMAIN, SERVICE_DELETE_DEVICE, delete_device,
                           schema=DELETE_DEVICE_SCHEMA)

    hubs = pywink.get_hubs()
    for hub in hubs:
        if hub.device_manufacturer() == 'wink':
            WINK_HUBS.append(hub)

    if WINK_HUBS:
        hass.services.register(
            DOMAIN, SERVICE_SET_PAIRING_MODE, set_pairing_mode,
            schema=SET_PAIRING_MODE_SCHEMA)

    def service_handle(service):
        """Handle services."""
        entity_ids = service.data.get('entity_id')
        all_sirens = []
        for switch in hass.data[DOMAIN]['entities']['switch']:
            if isinstance(switch, WinkSirenDevice):
                all_sirens.append(switch)
        sirens_to_set = []
        if entity_ids is None:
            sirens_to_set = all_sirens
        else:
            for siren in all_sirens:
                if siren.entity_id in entity_ids:
                    sirens_to_set.append(siren)

        for siren in sirens_to_set:
            _man = siren.wink.device_manufacturer()
            if (service.service != SERVICE_SET_AUTO_SHUTOFF and
                    service.service != SERVICE_ENABLE_SIREN and
                    _man not in ('dome', 'wink')):
                _LOGGER.error("Service only valid for Dome or Wink sirens")
                return

            if service.service == SERVICE_ENABLE_SIREN:
                siren.wink.set_state(service.data.get(ATTR_ENABLED))
            elif service.service == SERVICE_SET_AUTO_SHUTOFF:
                siren.wink.set_auto_shutoff(
                    service.data.get(ATTR_AUTO_SHUTOFF))
            elif service.service == SERVICE_SET_CHIME_VOLUME:
                siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME))
            elif service.service == SERVICE_SET_SIREN_VOLUME:
                siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME))
            elif service.service == SERVICE_SET_SIREN_TONE:
                siren.wink.set_siren_sound(service.data.get(ATTR_TONE))
            elif service.service == SERVICE_ENABLE_CHIME:
                siren.wink.set_chime(service.data.get(ATTR_TONE))
            elif service.service == SERVICE_SIREN_STROBE_ENABLED:
                siren.wink.set_siren_strobe_enabled(
                    service.data.get(ATTR_ENABLED))
            elif service.service == SERVICE_CHIME_STROBE_ENABLED:
                siren.wink.set_chime_strobe_enabled(
                    service.data.get(ATTR_ENABLED))

    # Load components for the devices in Wink that we support
    for wink_component in WINK_COMPONENTS:
        hass.data[DOMAIN]['entities'][wink_component] = []
        discovery.load_platform(hass, wink_component, DOMAIN, {}, config)

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    sirens = []
    has_dome_or_wink_siren = False
    for siren in pywink.get_sirens():
        _man = siren.device_manufacturer()
        if _man in ("dome", "wink"):
            has_dome_or_wink_siren = True
        _id = siren.object_id() + siren.name()
        if _id not in hass.data[DOMAIN]['unique_ids']:
            sirens.append(WinkSirenDevice(siren, hass))

    if sirens:

        hass.services.register(DOMAIN, SERVICE_SET_AUTO_SHUTOFF,
                               service_handle,
                               schema=SET_AUTO_SHUTOFF_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_ENABLE_SIREN,
                               service_handle,
                               schema=ENABLED_SIREN_SCHEMA)

    if has_dome_or_wink_siren:

        hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE,
                               service_handle,
                               schema=SET_SIREN_TONE_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME,
                               service_handle,
                               schema=SET_CHIME_MODE_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME,
                               service_handle,
                               schema=SET_VOLUME_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME,
                               service_handle,
                               schema=SET_VOLUME_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_SIREN_STROBE_ENABLED,
                               service_handle,
                               schema=SET_STROBE_ENABLED_SCHEMA)

        hass.services.register(DOMAIN, SERVICE_CHIME_STROBE_ENABLED,
                               service_handle,
                               schema=SET_STROBE_ENABLED_SCHEMA)

    component.add_entities(sirens)

    return True
Beispiel #23
0
def setup(hass, config):
    """Set up the Wink component."""
    import pywink
    import requests
    from pubnubsubhandler import PubNubSubscriptionHandler

    hass.data[DOMAIN] = {}
    hass.data[DOMAIN]['entities'] = []
    hass.data[DOMAIN]['unique_ids'] = []
    hass.data[DOMAIN]['entities'] = {}

    user_agent = config[DOMAIN].get(CONF_USER_AGENT)

    if user_agent:
        pywink.set_user_agent(user_agent)

    access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN)
    client_id = config[DOMAIN].get('client_id')

    def _get_wink_token_from_web():
        email = hass.data[DOMAIN]["oath"]["email"]
        password = hass.data[DOMAIN]["oath"]["password"]

        payload = {'username': email, 'password': password}
        token_response = requests.post(CONF_TOKEN_URL, data=payload)
        try:
            token = token_response.text.split(':')[1].split()[0].rstrip('<br')
        except IndexError:
            _LOGGER.error("Error getting token. Please check email/password.")
            return False
        pywink.set_bearer_token(token)

    if access_token:
        pywink.set_bearer_token(access_token)
    elif client_id:
        email = config[DOMAIN][CONF_EMAIL]
        password = config[DOMAIN][CONF_PASSWORD]
        client_id = config[DOMAIN]['client_id']
        client_secret = config[DOMAIN]['client_secret']
        pywink.set_wink_credentials(email, password, client_id, client_secret)
        hass.data[DOMAIN]['oath'] = {"email": email,
                                     "password": password,
                                     "client_id": client_id,
                                     "client_secret": client_secret}
    else:
        email = config[DOMAIN][CONF_EMAIL]
        password = config[DOMAIN][CONF_PASSWORD]
        hass.data[DOMAIN]['oath'] = {"email": email, "password": password}
        _get_wink_token_from_web()

    hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler(
        pywink.get_subscription_key())

    def keep_alive_call(event_time):
        """Call the Wink API endpoints to keep PubNub working."""
        _LOGGER.info("Getting a new Wink token.")
        if hass.data[DOMAIN]["oath"].get("client_id") is not None:
            _email = hass.data[DOMAIN]["oath"]["email"]
            _password = hass.data[DOMAIN]["oath"]["password"]
            _client_id = hass.data[DOMAIN]["oath"]["client_id"]
            _client_secret = hass.data[DOMAIN]["oath"]["client_secret"]
            pywink.set_wink_credentials(_email, _password, _client_id,
                                        _client_secret)
        else:
            _LOGGER.info("Getting a new Wink token.")
            _get_wink_token_from_web()
        time.sleep(1)
        _LOGGER.info("Polling the Wink API to keep PubNub updates flowing.")
        _LOGGER.debug(str(json.dumps(pywink.wink_api_fetch())))
        time.sleep(1)
        _LOGGER.debug(str(json.dumps(pywink.get_user())))

    # Call the Wink API every hour to keep PubNub updates flowing
    if access_token is None:
        track_time_interval(hass, keep_alive_call, timedelta(minutes=120))

    def start_subscription(event):
        """Start the pubnub subscription."""
        hass.data[DOMAIN]['pubnub'].subscribe()
    hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)

    def stop_subscription(event):
        """Stop the pubnub subscription."""
        hass.data[DOMAIN]['pubnub'].unsubscribe()
    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)

    def force_update(call):
        """Force all devices to poll the Wink API."""
        _LOGGER.info("Refreshing Wink states from API")
        for entity_list in hass.data[DOMAIN]['entities'].values():
            # Throttle the calls to Wink API
            for entity in entity_list:
                time.sleep(1)
                entity.schedule_update_ha_state(True)
    hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update)

    def pull_new_devices(call):
        """Pull new devices added to users Wink account since startup."""
        _LOGGER.info("Getting new devices from Wink API")
        for component in WINK_COMPONENTS:
            discovery.load_platform(hass, component, DOMAIN, {}, config)
    hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices)

    # Load components for the devices in Wink that we support
    for component in WINK_COMPONENTS:
        hass.data[DOMAIN]['entities'][component] = []
        discovery.load_platform(hass, component, DOMAIN, {}, config)

    return True
Beispiel #24
0
 def _init_regular_updates(self, hass):
     """Schedule regular updates at the top of the clock."""
     track_time_interval(hass, lambda now: self._update(),
                         self._scan_interval)
Beispiel #25
0
 def update_and_restart(event_time):
     update_forced(event_time)
     self._update_task = track_time_interval(
         self.hass, update_forced,
         timedelta(seconds=DEFAULT_SCAN_INTERVAL))
Beispiel #26
0
def setup(hass, config):
    """Set up the NZBGet sensors."""

    host = config[DOMAIN][CONF_HOST]
    port = config[DOMAIN][CONF_PORT]
    ssl = "s" if config[DOMAIN][CONF_SSL] else ""
    name = config[DOMAIN][CONF_NAME]
    username = config[DOMAIN].get(CONF_USERNAME)
    password = config[DOMAIN].get(CONF_PASSWORD)
    scan_interval = config[DOMAIN][CONF_SCAN_INTERVAL]

    try:
        nzbget_api = pynzbgetapi.NZBGetAPI(host, username, password, ssl, ssl,
                                           port)
        nzbget_api.version()
    except pynzbgetapi.NZBGetAPIException as conn_err:
        _LOGGER.error("Error setting up NZBGet API: %s", conn_err)
        return False

    _LOGGER.debug("Successfully validated NZBGet API connection")

    nzbget_data = hass.data[DATA_NZBGET] = NZBGetData(hass, nzbget_api)
    nzbget_data.init_download_list()
    nzbget_data.update()

    def service_handler(service):
        """Handle service calls."""
        if service.service == SERVICE_PAUSE:
            nzbget_data.pause_download()
        elif service.service == SERVICE_RESUME:
            nzbget_data.resume_download()
        elif service.service == SERVICE_SET_SPEED:
            limit = service.data[ATTR_SPEED]
            nzbget_data.rate(limit)

    hass.services.register(DOMAIN,
                           SERVICE_PAUSE,
                           service_handler,
                           schema=vol.Schema({}))

    hass.services.register(DOMAIN,
                           SERVICE_RESUME,
                           service_handler,
                           schema=vol.Schema({}))

    hass.services.register(DOMAIN,
                           SERVICE_SET_SPEED,
                           service_handler,
                           schema=SPEED_LIMIT_SCHEMA)

    def refresh(event_time):
        """Get the latest data from NZBGet."""
        nzbget_data.update()

    track_time_interval(hass, refresh, scan_interval)

    sensorconfig = {"client_name": name}

    hass.helpers.discovery.load_platform("sensor", DOMAIN, sensorconfig,
                                         config)

    return True
Beispiel #27
0
def setup(hass, config):
    """Set up the Wink component."""
    import pywink
    from pubnubsubhandler import PubNubSubscriptionHandler

    descriptions = load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml')).get(DOMAIN)

    if hass.data.get(DOMAIN) is None:
        hass.data[DOMAIN] = {
            'unique_ids': [],
            'entities': {},
            'oauth': {},
            'configuring': {},
            'pubnub': None,
            'configurator': False
        }

    def _get_wink_token_from_web():
        _email = hass.data[DOMAIN]["oauth"]["email"]
        _password = hass.data[DOMAIN]["oauth"]["password"]

        payload = {'username': _email, 'password': _password}
        token_response = requests.post(CONF_TOKEN_URL, data=payload)
        try:
            token = token_response.text.split(':')[1].split()[0].rstrip('<br')
        except IndexError:
            _LOGGER.error("Error getting token. Please check email/password.")
            return False
        pywink.set_bearer_token(token)

    if config.get(DOMAIN) is not None:
        client_id = config[DOMAIN].get(ATTR_CLIENT_ID)
        client_secret = config[DOMAIN].get(ATTR_CLIENT_SECRET)
        email = config[DOMAIN].get(CONF_EMAIL)
        password = config[DOMAIN].get(CONF_PASSWORD)
        local_control = config[DOMAIN].get(CONF_LOCAL_CONTROL)
    else:
        client_id = None
        client_secret = None
        email = None
        password = None
        local_control = None
        hass.data[DOMAIN]['configurator'] = True
    if None not in [client_id, client_secret]:
        _LOGGER.info("Using legacy oauth authentication")
        if not local_control:
            pywink.disable_local_control()
        hass.data[DOMAIN]["oauth"]["client_id"] = client_id
        hass.data[DOMAIN]["oauth"]["client_secret"] = client_secret
        hass.data[DOMAIN]["oauth"]["email"] = email
        hass.data[DOMAIN]["oauth"]["password"] = password
        pywink.legacy_set_wink_credentials(email, password,
                                           client_id, client_secret)
    elif None not in [email, password]:
        _LOGGER.info("Using web form authentication")
        pywink.disable_local_control()
        hass.data[DOMAIN]["oauth"]["email"] = email
        hass.data[DOMAIN]["oauth"]["password"] = password
        _get_wink_token_from_web()
    else:
        _LOGGER.info("Using new oauth authentication")
        if not local_control:
            pywink.disable_local_control()
        config_path = hass.config.path(WINK_CONFIG_FILE)
        if os.path.isfile(config_path):
            config_file = _read_config_file(config_path)
            if config_file == DEFAULT_CONFIG:
                _request_app_setup(hass, config)
                return True
            # else move on because the user modified the file
        else:
            _write_config_file(config_path, DEFAULT_CONFIG)
            _request_app_setup(hass, config)
            return True

        if DOMAIN in hass.data[DOMAIN]['configuring']:
            _configurator = hass.data[DOMAIN]['configuring']
            hass.components.configurator.request_done(_configurator.pop(
                DOMAIN))

        # Using oauth
        access_token = config_file.get(ATTR_ACCESS_TOKEN)
        refresh_token = config_file.get(ATTR_REFRESH_TOKEN)

        # This will be called after authorizing Home-Assistant
        if None not in (access_token, refresh_token):
            pywink.set_wink_credentials(config_file.get(ATTR_CLIENT_ID),
                                        config_file.get(ATTR_CLIENT_SECRET),
                                        access_token=access_token,
                                        refresh_token=refresh_token)
        # This is called to create the redirect so the user can Authorize
        # Home-Assistant
        else:

            redirect_uri = '{}{}'.format(hass.config.api.base_url,
                                         WINK_AUTH_CALLBACK_PATH)

            wink_auth_start_url = pywink.get_authorization_url(
                config_file.get(ATTR_CLIENT_ID), redirect_uri)
            hass.http.register_redirect(WINK_AUTH_START, wink_auth_start_url)
            hass.http.register_view(WinkAuthCallbackView(config,
                                                         config_file,
                                                         pywink.request_token))
            _request_oauth_completion(hass, config)
            return True

    pywink.set_user_agent(USER_AGENT)
    hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler(
        pywink.get_subscription_key())

    def _subscribe():
        hass.data[DOMAIN]['pubnub'].subscribe()

    # Call subscribe after the user sets up wink via the configurator
    # All other methods will complete setup before
    # EVENT_HOMEASSISTANT_START is called meaning they
    # will call subscribe via the method below. (start_subscription)
    if hass.data[DOMAIN]['configurator']:
        _subscribe()

    def keep_alive_call(event_time):
        """Call the Wink API endpoints to keep PubNub working."""
        _LOGGER.info("Polling the Wink API to keep PubNub updates flowing.")
        pywink.set_user_agent(str(int(time.time())))
        _temp_response = pywink.get_user()
        _LOGGER.debug(str(json.dumps(_temp_response)))
        time.sleep(1)
        pywink.set_user_agent(USER_AGENT)
        _temp_response = pywink.wink_api_fetch()
        _LOGGER.debug(str(json.dumps(_temp_response)))

    # Call the Wink API every hour to keep PubNub updates flowing
    track_time_interval(hass, keep_alive_call, timedelta(minutes=60))

    def start_subscription(event):
        """Start the pubnub subscription."""
        _subscribe()

    hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)

    def stop_subscription(event):
        """Stop the pubnub subscription."""
        hass.data[DOMAIN]['pubnub'].unsubscribe()
        hass.data[DOMAIN]['pubnub'] = None

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)

    def save_credentials(event):
        """Save currently set oauth credentials."""
        if hass.data[DOMAIN]["oauth"].get("email") is None:
            config_path = hass.config.path(WINK_CONFIG_FILE)
            _config = pywink.get_current_oauth_credentials()
            _write_config_file(config_path, _config)

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, save_credentials)

    def force_update(call):
        """Force all devices to poll the Wink API."""
        _LOGGER.info("Refreshing Wink states from API")
        for entity_list in hass.data[DOMAIN]['entities'].values():
            # Throttle the calls to Wink API
            for entity in entity_list:
                time.sleep(1)
                entity.schedule_update_ha_state(True)

    hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update,
                           descriptions.get(SERVICE_REFRESH_STATES))

    def pull_new_devices(call):
        """Pull new devices added to users Wink account since startup."""
        _LOGGER.info("Getting new devices from Wink API")
        for _component in WINK_COMPONENTS:
            discovery.load_platform(hass, _component, DOMAIN, {}, config)

    hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices,
                           descriptions.get(SERVICE_ADD_NEW_DEVICES))

    def set_pairing_mode(call):
        """Put the hub in provided pairing mode."""
        hub_name = call.data.get('hub_name')
        pairing_mode = call.data.get('pairing_mode')
        kidde_code = call.data.get('kidde_radio_code')
        for hub in WINK_HUBS:
            if hub.name() == hub_name:
                hub.pair_new_device(pairing_mode,
                                    kidde_radio_code=kidde_code)

    def rename_device(call):
        """Set specified device's name."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            name = call.data.get('name')
            found_device.wink.set_name(name)

    hass.services.register(DOMAIN, SERVICE_RENAME_DEVICE, rename_device,
                           descriptions.get(SERVICE_RENAME_DEVICE),
                           schema=RENAME_DEVICE_SCHEMA)

    def delete_device(call):
        """Delete specified device."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            found_device.wink.remove_device()

    hass.services.register(DOMAIN, SERVICE_DELETE_DEVICE, delete_device,
                           descriptions.get(SERVICE_DELETE_DEVICE),
                           schema=DELETE_DEVICE_SCHEMA)

    hubs = pywink.get_hubs()
    for hub in hubs:
        if hub.device_manufacturer() == 'wink':
            WINK_HUBS.append(hub)

    if WINK_HUBS:
        hass.services.register(
            DOMAIN, SERVICE_SET_PAIRING_MODE, set_pairing_mode,
            descriptions.get(SERVICE_SET_PAIRING_MODE),
            schema=SET_PAIRING_MODE_SCHEMA)

    # Load components for the devices in Wink that we support
    for wink_component in WINK_COMPONENTS:
        hass.data[DOMAIN]['entities'][wink_component] = []
        discovery.load_platform(hass, wink_component, DOMAIN, {}, config)

    return True
Beispiel #28
0
def setup(hass, config):
    """Set up Temper2 MQTT component"""
    topic = config[DOMAIN].get(TOPIC)
    scan_interval = timedelta(seconds=config[DOMAIN].get(CONF_SCAN_INTERVAL))
    mqtt = hass.components.mqtt

    #Need to get the device id of the Tempre@ device: 0001:0004:01
    result = subprocess.run([HID_QUERY_SCRIPT, '-e'], stdout=subprocess.PIPE)
    #_LOGGER.warn("-e result {}".format(result.stdout.decode('utf-8')))
    deviceId = ""
    deviceIds = re.search(r"(.*?01) : 413d:2107.*",
                          result.stdout.decode('utf-8'), re.M | re.I)
    if deviceIds:
        deviceId = deviceIds.group(1)
        _LOGGER.warn("Temper2 - Found DeviceId {}".format(deviceId))
    else:
        _LOGGER.warn("NO MATCH")
        raise Exception("No 413d:2107 device found.")

    _LOGGER.info("Custom component {} is setup.".format(DOMAIN))

    def set_state_service(call):
        """Service to send a message."""
        msg = '{{"temperature":{}}}'.format(call.data.get('new_state'))
        _LOGGER.warn("Publish " + msg)
        mqtt.publish(topic, msg)

    def refresh(event_time):
        """Refresh"""
        temp_parts = get_Temper2Reading()
        current_temperature = calc_Temperature(temp_parts)
        if current_temperature < MAX_TEMP:
            msg = '{{"temperature":{}}}'.format(current_temperature)
            mqtt.publish(topic, msg)
            _LOGGER.info("Published " + msg)
        else:
            # Sometimes the unit returns crazy values 328 deg celcius, for now we just log
            _LOGGER.warn(
                "Wrong Temperature reading [{}]".format(current_temperature))

    def get_Temper2Reading():
        result = subprocess.run([
            HID_QUERY_SCRIPT, deviceId, '0x01', '0x80', '0x33', '0x01', '0x00',
            '0x00', '0x00', '0x00'
        ],
                                stdout=subprocess.PIPE)
        # _LOGGER.warn("Publish " + result.stdout.decode('utf-8')) '0001:0004:01'
        parts = result.stdout.decode('utf-8').split('\n')
        while '' in parts:
            parts.remove('')
        return parts

    def calc_Temperature(parts):
        temperature_line = parts[len(parts) - 1].split(' ')
        # list looks like ['\t', '80', '01', '0a', '73', '', '', '4e', '20', '00', '00']
        # we want item 3 & 4 ('0a', '73')

        temp = ((int(temperature_line[3], 16) << 8) +
                int(temperature_line[4], 16)) / 100
        return temp

    track_time_interval(hass, refresh, scan_interval)

    # Register our service with Home Assistant.
    hass.services.register(DOMAIN, 'set_state', set_state_service)

    # Initialization was successfull
    return True
Beispiel #29
0
def setup(hass, config):
    """Set up Tuya Component."""
    from tuyapy import TuyaApi

    tuya = TuyaApi()
    username = config[DOMAIN][CONF_USERNAME]
    password = config[DOMAIN][CONF_PASSWORD]
    country_code = config[DOMAIN][CONF_COUNTRYCODE]

    hass.data[DATA_TUYA] = tuya
    tuya.init(username, password, country_code)
    hass.data[DOMAIN] = {
        'entities': {}
    }

    def load_devices(device_list):
        """Load new devices by device_list."""
        device_type_list = {}
        for device in device_list:
            dev_type = device.device_type()
            if (dev_type in TUYA_TYPE_TO_HA and
                    device.object_id() not in hass.data[DOMAIN]['entities']):
                ha_type = TUYA_TYPE_TO_HA[dev_type]
                if ha_type not in device_type_list:
                    device_type_list[ha_type] = []
                device_type_list[ha_type].append(device.object_id())
                hass.data[DOMAIN]['entities'][device.object_id()] = None
        for ha_type, dev_ids in device_type_list.items():
            discovery.load_platform(
                hass, ha_type, DOMAIN, {'dev_ids': dev_ids}, config)

    device_list = tuya.get_all_devices()
    load_devices(device_list)

    def poll_devices_update(event_time):
        """Check if accesstoken is expired and pull device list from server."""
        _LOGGER.debug("Pull devices from Tuya.")
        tuya.poll_devices_update()
        # Add new discover device.
        device_list = tuya.get_all_devices()
        load_devices(device_list)
        # Delete not exist device.
        newlist_ids = []
        for device in device_list:
            newlist_ids.append(device.object_id())
        for dev_id in list(hass.data[DOMAIN]['entities']):
            if dev_id not in newlist_ids:
                dispatcher_send(hass, SIGNAL_DELETE_ENTITY, dev_id)
                hass.data[DOMAIN]['entities'].pop(dev_id)

    track_time_interval(hass, poll_devices_update, timedelta(minutes=5))

    hass.services.register(DOMAIN, SERVICE_PULL_DEVICES, poll_devices_update)

    def force_update(call):
        """Force all devices to pull data."""
        dispatcher_send(hass, SIGNAL_UPDATE_ENTITY)

    hass.services.register(DOMAIN, SERVICE_FORCE_UPDATE, force_update)

    return True
 def _start_recovery(self):
     self._wrap_event_flag.clear()
     dispatcher_send(self._hass, service_signal(SERVICE_UPDATE, self._wrap_name))
     self._unsub_recheck = track_time_interval(
         self._hass, self._wrap_test_online, RECHECK_INTERVAL
     )
Beispiel #31
0
 def _init_regular_updates(self):
     """Schedule regular updates at the specified interval."""
     track_time_interval(
         self._hass, lambda now: self._feed_manager.update(),
         self._scan_interval)
Beispiel #32
0
def setup(hass, config):
    """Set up the Overseerr component platform."""

    overseerr = pyoverseerr.Overseerr(
        ssl=config[DOMAIN][CONF_SSL],
        host=config[DOMAIN][CONF_HOST],
        port=config[DOMAIN][CONF_PORT],
        urlbase=config[DOMAIN][CONF_URLBASE],
        username=config[DOMAIN].get(CONF_USERNAME),
        password=config[DOMAIN].get(CONF_PASSWORD),
        api_key=config[DOMAIN].get(CONF_API_KEY),
    )

    scan_interval=config[DOMAIN][CONF_SCAN_INTERVAL]

    try:
        overseerr.authenticate()
        overseerr.test_connection()
    except pyoverseerr.OverseerrError as err:
        _LOGGER.warning("Unable to setup Overseerr: %s", err)
        return False

    hass.data[DOMAIN] = {"instance": overseerr}

    def submit_movie_request(call):
        """Submit request for movie."""
        name = call.data[ATTR_NAME]
        movies = overseerr.search_movie(name)
        if movies:
            movie = movies[0]
            overseerr.request_movie(movie["theMovieDbId"])
        else:
            raise Warning("No movie found.")

    def submit_tv_request(call):
        """Submit request for TV show."""
        name = call.data[ATTR_NAME]
        tv_shows = overseerr.search_tv(name)

        if tv_shows:
            season = call.data[ATTR_SEASON]
            show = tv_shows[0]["id"]
            if season == "first":
                overseerr.request_tv(show, request_first=True)
            elif season == "latest":
                overseerr.request_tv(show, request_latest=True)
            elif season == "all":
                overseerr.request_tv(show, request_all=True)
        else:
            raise Warning("No TV show found.")

    def submit_music_request(call):
        """Submit request for music album."""
        name = call.data[ATTR_NAME]
        music = overseerr.search_music_album(name)
        if music:
            overseerr.request_music(music[0]["foreignAlbumId"])
        else:
            raise Warning("No music album found.")

    def update_request(call):
        """Update status of specified request."""
        request_id = call.data[ATTR_ID]
        status = call.data[ATTR_STATUS]
        overseerr.update_request(request_id, status)

    async def update_sensors(event_time):
        """Call to update sensors."""
        _LOGGER.debug("Updating sensors")
        # asyncio.run_coroutine_threadsafe( hass.data[DOMAIN].update(), hass.loop)
        await hass.services.async_call("homeassistant", "update_entity", {ATTR_ENTITY_ID: ["sensor.overseerr_pending_requests"]}, blocking=True)
        await hass.services.async_call("homeassistant", "update_entity", {ATTR_ENTITY_ID: ["sensor.overseerr_movie_requests"]}, blocking=True)
        await hass.services.async_call("homeassistant", "update_entity", {ATTR_ENTITY_ID: ["sensor.overseerr_tv_show_requests"]}, blocking=True)
        await hass.services.async_call("homeassistant", "update_entity", {ATTR_ENTITY_ID: ["sensor.overseerr_total_requests"]}, blocking=False)


    hass.services.register(
        DOMAIN,
        SERVICE_MOVIE_REQUEST,
        submit_movie_request,
        schema=SUBMIT_MOVIE_REQUEST_SERVICE_SCHEMA,
    )
    hass.services.register(
        DOMAIN,
        SERVICE_MUSIC_REQUEST,
        submit_music_request,
        schema=SUBMIT_MUSIC_REQUEST_SERVICE_SCHEMA,
    )
    hass.services.register(
        DOMAIN,
        SERVICE_TV_REQUEST,
        submit_tv_request,
        schema=SUBMIT_TV_REQUEST_SERVICE_SCHEMA,
    )
    hass.services.register(
        DOMAIN,
        SERVICE_UPDATE_REQUEST,
        update_request,
        schema=SERVICE_UPDATE_REQUEST_SCHEMA,
    )
    
    hass.helpers.discovery.load_platform("sensor", DOMAIN, {}, config)
 
    webhook_id = config[DOMAIN].get(CONF_API_KEY)
    _LOGGER.debug("webhook_id: %s", webhook_id)

    _LOGGER.info("Overseerr Installing Webhook")

    hass.components.webhook.async_register(DOMAIN, "Overseerr", webhook_id, handle_webhook)

    url = hass.components.webhook.async_generate_url(webhook_id)
    _LOGGER.debug("webhook data: %s", url)

    # register scan interval
    track_time_interval(hass, update_sensors, scan_interval)

    return True
def setup(hass, config):
    """Set up the Wink component."""
    import pywink
    from pubnubsubhandler import PubNubSubscriptionHandler

    if hass.data.get(DOMAIN) is None:
        hass.data[DOMAIN] = {
            'unique_ids': [],
            'entities': {},
            'oauth': {},
            'configuring': {},
            'pubnub': None,
            'configurator': False
        }

    if config.get(DOMAIN) is not None:
        client_id = config[DOMAIN].get(ATTR_CLIENT_ID)
        client_secret = config[DOMAIN].get(ATTR_CLIENT_SECRET)
        email = config[DOMAIN].get(CONF_EMAIL)
        password = config[DOMAIN].get(CONF_PASSWORD)
        local_control = config[DOMAIN].get(CONF_LOCAL_CONTROL)
    else:
        client_id = None
        client_secret = None
        email = None
        password = None
        local_control = None
        hass.data[DOMAIN]['configurator'] = True
    if None not in [client_id, client_secret]:
        _LOGGER.info("Using legacy OAuth authentication")
        if not local_control:
            pywink.disable_local_control()
        hass.data[DOMAIN]["oauth"]["client_id"] = client_id
        hass.data[DOMAIN]["oauth"]["client_secret"] = client_secret
        hass.data[DOMAIN]["oauth"]["email"] = email
        hass.data[DOMAIN]["oauth"]["password"] = password
        pywink.legacy_set_wink_credentials(email, password, client_id,
                                           client_secret)
    else:
        _LOGGER.info("Using OAuth authentication")
        if not local_control:
            pywink.disable_local_control()
        config_path = hass.config.path(WINK_CONFIG_FILE)
        if os.path.isfile(config_path):
            config_file = load_json(config_path)
            if config_file == DEFAULT_CONFIG:
                _request_app_setup(hass, config)
                return True
            # else move on because the user modified the file
        else:
            save_json(config_path, DEFAULT_CONFIG)
            _request_app_setup(hass, config)
            return True

        if DOMAIN in hass.data[DOMAIN]['configuring']:
            _configurator = hass.data[DOMAIN]['configuring']
            hass.components.configurator.request_done(
                _configurator.pop(DOMAIN))

        # Using oauth
        access_token = config_file.get(ATTR_ACCESS_TOKEN)
        refresh_token = config_file.get(ATTR_REFRESH_TOKEN)

        # This will be called after authorizing Home-Assistant
        if None not in (access_token, refresh_token):
            pywink.set_wink_credentials(config_file.get(ATTR_CLIENT_ID),
                                        config_file.get(ATTR_CLIENT_SECRET),
                                        access_token=access_token,
                                        refresh_token=refresh_token)
        # This is called to create the redirect so the user can Authorize
        # Home .
        else:

            redirect_uri = '{}{}'.format(hass.config.api.base_url,
                                         WINK_AUTH_CALLBACK_PATH)

            wink_auth_start_url = pywink.get_authorization_url(
                config_file.get(ATTR_CLIENT_ID), redirect_uri)
            hass.http.register_redirect(WINK_AUTH_START, wink_auth_start_url)
            hass.http.register_view(
                WinkAuthCallbackView(config, config_file,
                                     pywink.request_token))
            _request_oauth_completion(hass, config)
            return True

    pywink.set_user_agent(USER_AGENT)
    hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler(
        pywink.get_subscription_key())

    def _subscribe():
        hass.data[DOMAIN]['pubnub'].subscribe()

    # Call subscribe after the user sets up wink via the configurator
    # All other methods will complete setup before
    # EVENT_HOMEASSISTANT_START is called meaning they
    # will call subscribe via the method below. (start_subscription)
    if hass.data[DOMAIN]['configurator']:
        _subscribe()

    def keep_alive_call(event_time):
        """Call the Wink API endpoints to keep PubNub working."""
        _LOGGER.info("Polling the Wink API to keep PubNub updates flowing")
        pywink.set_user_agent(str(int(time.time())))
        _temp_response = pywink.get_user()
        _LOGGER.debug(str(json.dumps(_temp_response)))
        time.sleep(1)
        pywink.set_user_agent(USER_AGENT)
        _temp_response = pywink.wink_api_fetch()
        _LOGGER.debug(str(json.dumps(_temp_response)))

    # Call the Wink API every hour to keep PubNub updates flowing
    track_time_interval(hass, keep_alive_call, timedelta(minutes=60))

    def start_subscription(event):
        """Start the PubNub subscription."""
        _subscribe()

    hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)

    def stop_subscription(event):
        """Stop the PubNub subscription."""
        hass.data[DOMAIN]['pubnub'].unsubscribe()
        hass.data[DOMAIN]['pubnub'] = None

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)

    def save_credentials(event):
        """Save currently set OAuth credentials."""
        if hass.data[DOMAIN]["oauth"].get("email") is None:
            config_path = hass.config.path(WINK_CONFIG_FILE)
            _config = pywink.get_current_oauth_credentials()
            save_json(config_path, _config)

    hass.bus.listen(EVENT_HOMEASSISTANT_STOP, save_credentials)

    # Save the users potentially updated oauth credentials at a regular
    # interval to prevent them from being expired after a HA reboot.
    track_time_interval(hass, save_credentials, timedelta(minutes=60))

    def force_update(call):
        """Force all devices to poll the Wink API."""
        _LOGGER.info("Refreshing Wink states from API")
        for entity_list in hass.data[DOMAIN]['entities'].values():
            # Throttle the calls to Wink API
            for entity in entity_list:
                time.sleep(1)
                entity.schedule_update_ha_state(True)

    hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update)

    def pull_new_devices(call):
        """Pull new devices added to users Wink account since startup."""
        _LOGGER.info("Getting new devices from Wink API")
        for _component in WINK_COMPONENTS:
            discovery.load_platform(hass, _component, DOMAIN, {}, config)

    hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices)

    def set_pairing_mode(call):
        """Put the hub in provided pairing mode."""
        hub_name = call.data.get('hub_name')
        pairing_mode = call.data.get('pairing_mode')
        kidde_code = call.data.get('kidde_radio_code')
        for hub in WINK_HUBS:
            if hub.name() == hub_name:
                hub.pair_new_device(pairing_mode, kidde_radio_code=kidde_code)

    def rename_device(call):
        """Set specified device's name."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            name = call.data.get('name')
            found_device.wink.set_name(name)

    hass.services.register(DOMAIN,
                           SERVICE_RENAME_DEVICE,
                           rename_device,
                           schema=RENAME_DEVICE_SCHEMA)

    def delete_device(call):
        """Delete specified device."""
        # This should only be called on one device at a time.
        found_device = None
        entity_id = call.data.get('entity_id')[0]
        all_devices = []
        for list_of_devices in hass.data[DOMAIN]['entities'].values():
            all_devices += list_of_devices
        for device in all_devices:
            if device.entity_id == entity_id:
                found_device = device
        if found_device is not None:
            found_device.wink.remove_device()

    hass.services.register(DOMAIN,
                           SERVICE_DELETE_DEVICE,
                           delete_device,
                           schema=DELETE_DEVICE_SCHEMA)

    hubs = pywink.get_hubs()
    for hub in hubs:
        if hub.device_manufacturer() == 'wink':
            WINK_HUBS.append(hub)

    if WINK_HUBS:
        hass.services.register(DOMAIN,
                               SERVICE_SET_PAIRING_MODE,
                               set_pairing_mode,
                               schema=SET_PAIRING_MODE_SCHEMA)

    def service_handle(service):
        """Handle services."""
        entity_ids = service.data.get('entity_id')
        all_sirens = []
        for switch in hass.data[DOMAIN]['entities']['switch']:
            if isinstance(switch, WinkSirenDevice):
                all_sirens.append(switch)
        sirens_to_set = []
        if entity_ids is None:
            sirens_to_set = all_sirens
        else:
            for siren in all_sirens:
                if siren.entity_id in entity_ids:
                    sirens_to_set.append(siren)

        for siren in sirens_to_set:
            _man = siren.wink.device_manufacturer()
            if (service.service != SERVICE_SET_AUTO_SHUTOFF
                    and service.service != SERVICE_ENABLE_SIREN
                    and (_man != 'dome' and _man != 'wink')):
                _LOGGER.error("Service only valid for Dome or Wink sirens")
                return

            if service.service == SERVICE_ENABLE_SIREN:
                siren.wink.set_state(service.data.get(ATTR_ENABLED))
            elif service.service == SERVICE_SET_AUTO_SHUTOFF:
                siren.wink.set_auto_shutoff(
                    service.data.get(ATTR_AUTO_SHUTOFF))
            elif service.service == SERVICE_SET_CHIME_VOLUME:
                siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME))
            elif service.service == SERVICE_SET_SIREN_VOLUME:
                siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME))
            elif service.service == SERVICE_SET_SIREN_TONE:
                siren.wink.set_siren_sound(service.data.get(ATTR_TONE))
            elif service.service == SERVICE_ENABLE_CHIME:
                siren.wink.set_chime(service.data.get(ATTR_TONE))
            elif service.service == SERVICE_SIREN_STROBE_ENABLED:
                siren.wink.set_siren_strobe_enabled(
                    service.data.get(ATTR_ENABLED))
            elif service.service == SERVICE_CHIME_STROBE_ENABLED:
                siren.wink.set_chime_strobe_enabled(
                    service.data.get(ATTR_ENABLED))

    # Load components for the devices in Wink that we support
    for wink_component in WINK_COMPONENTS:
        hass.data[DOMAIN]['entities'][wink_component] = []
        discovery.load_platform(hass, wink_component, DOMAIN, {}, config)

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    sirens = []
    has_dome_or_wink_siren = False
    for siren in pywink.get_sirens():
        _man = siren.device_manufacturer()
        if _man == "dome" or _man == "wink":
            has_dome_or_wink_siren = True
        _id = siren.object_id() + siren.name()
        if _id not in hass.data[DOMAIN]['unique_ids']:
            sirens.append(WinkSirenDevice(siren, hass))

    if sirens:

        hass.services.register(DOMAIN,
                               SERVICE_SET_AUTO_SHUTOFF,
                               service_handle,
                               schema=SET_AUTO_SHUTOFF_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_ENABLE_SIREN,
                               service_handle,
                               schema=ENABLED_SIREN_SCHEMA)

    if has_dome_or_wink_siren:

        hass.services.register(DOMAIN,
                               SERVICE_SET_SIREN_TONE,
                               service_handle,
                               schema=SET_SIREN_TONE_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_ENABLE_CHIME,
                               service_handle,
                               schema=SET_CHIME_MODE_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_SET_SIREN_VOLUME,
                               service_handle,
                               schema=SET_VOLUME_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_SET_CHIME_VOLUME,
                               service_handle,
                               schema=SET_VOLUME_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_SIREN_STROBE_ENABLED,
                               service_handle,
                               schema=SET_STROBE_ENABLED_SCHEMA)

        hass.services.register(DOMAIN,
                               SERVICE_CHIME_STROBE_ENABLED,
                               service_handle,
                               schema=SET_STROBE_ENABLED_SCHEMA)

    component.add_entities(sirens)

    return True
Beispiel #34
0
def setup_plexserver(host, token, has_ssl, verify_ssl, hass, config,
                     add_entities_callback):
    """Set up a plexserver based on host parameter."""
    import plexapi.server
    import plexapi.exceptions

    cert_session = None
    http_prefix = 'https' if has_ssl else 'http'
    if has_ssl and (verify_ssl is False):
        _LOGGER.info("Ignoring SSL verification")
        cert_session = requests.Session()
        cert_session.verify = False
    try:
        plexserver = plexapi.server.PlexServer('%s://%s' % (http_prefix, host),
                                               token, cert_session)
        _LOGGER.info("Discovery configuration done (no token needed)")
    except (plexapi.exceptions.BadRequest, plexapi.exceptions.Unauthorized,
            plexapi.exceptions.NotFound) as error:
        _LOGGER.info(error)
        # No token or wrong token
        request_configuration(host, hass, config, add_entities_callback)
        return

    # If we came here and configuring this host, mark as done
    if host in _CONFIGURING:
        request_id = _CONFIGURING.pop(host)
        configurator = hass.components.configurator
        configurator.request_done(request_id)
        _LOGGER.info("Discovery configuration done")

    # Save config
    save_json(hass.config.path(PLEX_CONFIG_FILE),
              {host: {
                  'token': token,
                  'ssl': has_ssl,
                  'verify': verify_ssl,
              }})

    _LOGGER.info('Connected to: %s://%s', http_prefix, host)

    plex_clients = hass.data[PLEX_DATA]
    plex_sessions = {}
    track_time_interval(hass, lambda now: update_devices(),
                        timedelta(seconds=10))

    def update_devices():
        """Update the devices objects."""
        try:
            devices = plexserver.clients()
        except plexapi.exceptions.BadRequest:
            _LOGGER.exception("Error listing plex devices")
            return
        except requests.exceptions.RequestException as ex:
            _LOGGER.warning(
                "Could not connect to plex server at http://%s (%s)", host, ex)
            return

        new_plex_clients = []
        available_client_ids = []
        for device in devices:
            # For now, let's allow all deviceClass types
            if device.deviceClass in ['badClient']:
                continue

            available_client_ids.append(device.machineIdentifier)

            if device.machineIdentifier not in plex_clients:
                new_client = PlexClient(config, device, None, plex_sessions,
                                        update_devices)
                plex_clients[device.machineIdentifier] = new_client
                _LOGGER.debug("New device: %s", device.machineIdentifier)
                new_plex_clients.append(new_client)
            else:
                _LOGGER.debug("Refreshing device: %s",
                              device.machineIdentifier)
                plex_clients[device.machineIdentifier].refresh(device, None)

        # add devices with a session and no client (ex. PlexConnect Apple TV's)
        try:
            sessions = plexserver.sessions()
        except plexapi.exceptions.BadRequest:
            _LOGGER.exception("Error listing plex sessions")
            return
        except requests.exceptions.RequestException as ex:
            _LOGGER.warning(
                "Could not connect to plex server at http://%s (%s)", host, ex)
            return

        plex_sessions.clear()
        for session in sessions:
            for player in session.players:
                plex_sessions[player.machineIdentifier] = session, player

        for machine_identifier, (session, player) in plex_sessions.items():
            if machine_identifier in available_client_ids:
                # Avoid using session if already added as a device.
                _LOGGER.debug("Skipping session, device exists: %s",
                              machine_identifier)
                continue

            if (machine_identifier not in plex_clients
                    and machine_identifier is not None):
                new_client = PlexClient(config, player, session, plex_sessions,
                                        update_devices)
                plex_clients[machine_identifier] = new_client
                _LOGGER.debug("New session: %s", machine_identifier)
                new_plex_clients.append(new_client)
            else:
                _LOGGER.debug("Refreshing session: %s", machine_identifier)
                plex_clients[machine_identifier].refresh(None, session)

        clients_to_remove = []
        for client in plex_clients.values():
            # force devices to idle that do not have a valid session
            if client.session is None:
                client.force_idle()

            client.set_availability(
                client.machine_identifier in available_client_ids
                or client.machine_identifier in plex_sessions)

            if client not in new_plex_clients:
                client.schedule_update_ha_state()

            if not config.get(CONF_REMOVE_UNAVAILABLE_CLIENTS) \
                    or client.available:
                continue

            if (dt_util.utcnow() - client.marked_unavailable) >= \
                    (config.get(CONF_CLIENT_REMOVE_INTERVAL)):
                hass.add_job(client.async_remove())
                clients_to_remove.append(client.machine_identifier)

        while clients_to_remove:
            del plex_clients[clients_to_remove.pop()]

        if new_plex_clients:
            add_entities_callback(new_plex_clients)
 def _init_regular_updates(self, hass):
     """Schedule regular updates at the top of the clock."""
     track_time_interval(hass, lambda now: self._update(),
                         self._scan_interval)
def setup(hass, config):
    """Set up this component."""
    conf_track = config[DOMAIN][CONF_TRACK]
    conf_hide_sensor = config[DOMAIN][CONF_HIDE_SENSOR]
    config_show_installabe = config[DOMAIN][CONF_SHOW_INSTALLABLE]
    conf_card_urls = config[DOMAIN][CONF_CARD_CONFIG_URLS]
    conf_component_urls = config[DOMAIN][CONF_COMPONENT_CONFIG_URLS]
    conf_py_script_urls = config[DOMAIN][CONF_PYTHON_SCRIPT_CONFIG_URLS]

    _LOGGER.info('if you have ANY issues with this, please report them here:'
                 ' https://github.com/custom-components/custom_updater')

    if 'cards' in conf_track:
        card_controller = CustomCards(hass, conf_hide_sensor, conf_card_urls,
                                      config_show_installabe)
        track_time_interval(hass, card_controller.cache_versions, INTERVAL)
    if 'components' in conf_track:
        components_controller = CustomComponents(hass, conf_hide_sensor,
                                                 conf_component_urls,
                                                 config_show_installabe)
        track_time_interval(hass, components_controller.cache_versions,
                            INTERVAL)
    if 'python_scripts' in conf_track:
        python_scripts_controller = CustomPythonScripts(
            hass, conf_hide_sensor, conf_py_script_urls,
            config_show_installabe)
        track_time_interval(hass, python_scripts_controller.cache_versions,
                            INTERVAL)

    def check_all_service(call):
        """Set up service for manual trigger."""
        if 'cards' in conf_track:
            card_controller.cache_versions()
        if 'components' in conf_track:
            components_controller.cache_versions()
        if 'python_scripts' in conf_track:
            python_scripts_controller.cache_versions()

    def update_all_service(call):
        """Set up service for manual trigger."""
        if 'cards' in conf_track:
            card_controller.update_all()
        if 'components' in conf_track:
            components_controller.update_all()
        if 'python_scripts' in conf_track:
            python_scripts_controller.update_all()

    def install_service(call):
        """Install single component/card."""
        element = call.data.get(ATTR_ELEMENT)
        _LOGGER.debug('Installing %s', element)
        if 'cards' in conf_track:
            card_controller.install(element)
        if 'components' in conf_track:
            components_controller.install(element)
        if 'python_scripts' in conf_track:
            python_scripts_controller.install(element)

    hass.services.register(DOMAIN, 'check_all', check_all_service)
    hass.services.register(DOMAIN, 'update_all', update_all_service)
    hass.services.register(DOMAIN, 'install', install_service)
    return True
 def _init_regular_updates(self):
     """Schedule regular updates at the specified interval."""
     track_time_interval(
         self._hass, lambda now: self._update(), self._scan_interval)
Beispiel #38
0
def setup(hass, config):
    """Set up the platform from config."""
    from miio import Device, DeviceException

    if DOMAIN not in hass.data:
        hass.data[DOMAIN] = {}

    host = config[DOMAIN][CONF_HOST]
    token = config[DOMAIN][CONF_TOKEN]
    name = config[DOMAIN][CONF_NAME]
    model = config[DOMAIN].get(CONF_MODEL)
    scan_interval = config[DOMAIN][CONF_SCAN_INTERVAL]

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}
        hass.data[DATA_KEY][host] = {}

    _LOGGER.info("Initializing with host %s (token %s...)", host, token[:5])

    if model is None:
        try:
            miio_device = Device(host, token)
            device_info = miio_device.info()
            model = device_info.model
            _LOGGER.info(
                "%s %s %s detected",
                model,
                device_info.firmware_version,
                device_info.hardware_version,
            )
        except DeviceException:
            raise PlatformNotReady

    if model in SUPPORTED_MODELS:
        from miio import Cooker

        cooker = Cooker(host, token)

        hass.data[DOMAIN][host] = cooker

        for component in ["sensor"]:
            discovery.load_platform(hass, component, DOMAIN, {}, config)

    else:
        _LOGGER.error(
            "Unsupported device found! Please create an issue at "
            "https://github.com/syssi/xiaomi_cooker/issues "
            "and provide the following data: %s",
            model,
        )
        return False

    def update(event_time):
        """Update device status."""
        from miio.cooker import OperationMode

        try:
            state = cooker.status()
            _LOGGER.debug("Got new state: %s", state)
            hass.data[DATA_KEY][host][DATA_STATE] = state

            if state.mode in [OperationMode.Running, OperationMode.AutoKeepWarm]:
                hass.data[DATA_KEY][host][
                    DATA_TEMPERATURE_HISTORY
                ] = cooker.get_temperature_history()

            dispatcher_send(hass, "{}_updated".format(DOMAIN), host)

        except DeviceException as ex:
            dispatcher_send(hass, "{}_unavailable".format(DOMAIN), host)
            _LOGGER.error("Got exception while fetching the state: %s", ex)

    update(utcnow())
    track_time_interval(hass, update, scan_interval)

    def start_service(call):
        """Service to start cooking."""
        profile = call.data.get(ATTR_PROFILE)
        cooker.start(profile)

    def stop_service(call):
        """Service to stop cooking."""
        cooker.stop()

    hass.services.register(
        DOMAIN, SERVICE_START, start_service, schema=SERVICE_SCHEMA_START
    )

    hass.services.register(DOMAIN, SERVICE_STOP, stop_service, schema=SERVICE_SCHEMA)

    return True
Beispiel #39
0
def setup(hass, config):
    """Set up the RainMachine component."""
    from regenmaschine import Authenticator, Client
    from regenmaschine.exceptions import RainMachineError

    conf = config[DOMAIN]
    ip_address = conf[CONF_IP_ADDRESS]
    password = conf[CONF_PASSWORD]
    port = conf[CONF_PORT]
    ssl = conf[CONF_SSL]

    try:
        auth = Authenticator.create_local(
            ip_address, password, port=port, https=ssl)
        rainmachine = RainMachine(hass, Client(auth))
        rainmachine.update()
        hass.data[DATA_RAINMACHINE] = rainmachine
    except RainMachineError as exc:
        _LOGGER.error('An error occurred: %s', str(exc))
        hass.components.persistent_notification.create(
            'Error: {0}<br />'
            'You will need to restart hass after fixing.'
            ''.format(exc),
            title=NOTIFICATION_TITLE,
            notification_id=NOTIFICATION_ID)
        return False

    for component, schema in [
            ('binary_sensor', conf[CONF_BINARY_SENSORS]),
            ('sensor', conf[CONF_SENSORS]),
            ('switch', conf[CONF_SWITCHES]),
    ]:
        discovery.load_platform(hass, component, DOMAIN, schema, config)

    def refresh(event_time):
        """Refresh RainMachine data."""
        _LOGGER.debug('Updating RainMachine data')
        hass.data[DATA_RAINMACHINE].update()
        dispatcher_send(hass, DATA_UPDATE_TOPIC)

    track_time_interval(hass, refresh, DEFAULT_SCAN_INTERVAL)

    def start_program(service):
        """Start a particular program."""
        rainmachine.client.programs.start(service.data[CONF_PROGRAM_ID])

    def start_zone(service):
        """Start a particular zone for a certain amount of time."""
        rainmachine.client.zones.start(service.data[CONF_ZONE_ID],
                                       service.data[CONF_ZONE_RUN_TIME])

    def stop_all(service):
        """Stop all watering."""
        rainmachine.client.watering.stop_all()

    def stop_program(service):
        """Stop a program."""
        rainmachine.client.programs.stop(service.data[CONF_PROGRAM_ID])

    def stop_zone(service):
        """Stop a zone."""
        rainmachine.client.zones.stop(service.data[CONF_ZONE_ID])

    for service, method, schema in [
            ('start_program', start_program, SERVICE_START_PROGRAM_SCHEMA),
            ('start_zone', start_zone, SERVICE_START_ZONE_SCHEMA),
            ('stop_all', stop_all, {}),
            ('stop_program', stop_program, SERVICE_STOP_PROGRAM_SCHEMA),
            ('stop_zone', stop_zone, SERVICE_STOP_ZONE_SCHEMA)
    ]:
        hass.services.register(DOMAIN, service, method, schema=schema)

    return True