Beispiel #1
0
    def test_expand_entity_ids_expands_nested_groups(self):
        group.Group(self.hass, 'light', ['light.test_1', 'light.test_2'])
        group.Group(self.hass, 'switch', ['switch.test_1', 'switch.test_2'])
        group.Group(self.hass, 'group_of_groups',
                    ['group.light', 'group.switch'])

        self.assertEqual(
            ['light.test_1', 'light.test_2', 'switch.test_1', 'switch.test_2'],
            sorted(
                group.expand_entity_ids(self.hass, ['group.group_of_groups'])))
Beispiel #2
0
    def add_entities(self, new_entities):
        """
        Takes in a list of new entities. For each entity will see if it already
        exists. If not, will add it, set it up and push the first state.
        """
        for entity in new_entities:
            if entity is not None and entity not in self.entities.values():
                entity.hass = self.hass

                if getattr(entity, 'entity_id', None) is None:
                    entity.entity_id = generate_entity_id(
                        self.entity_id_format, entity.name,
                        self.entities.keys())

                self.entities[entity.entity_id] = entity

                entity.update_ha_state()

        if self.group is None and self.group_name is not None:
            self.group = group.Group(self.hass,
                                     self.group_name,
                                     user_defined=False)

        if self.group is not None:
            self.group.update_tracked_entity_ids(self.entities.keys())

        self._start_polling()
Beispiel #3
0
    def test_setup_group_with_a_non_existing_state(self):
        """Try to setup a group with a non existing state."""
        self.hass.states.set('light.Bowl', STATE_ON)

        grp = group.Group(self.hass, 'light_and_nothing',
                          ['light.Bowl', 'non.existing'])

        self.assertEqual(STATE_ON, grp.state)
Beispiel #4
0
    def test_setup_group_with_non_groupable_states(self):
        self.hass.states.set('cast.living_room', "Plex")
        self.hass.states.set('cast.bedroom', "Netflix")

        grp = group.Group(self.hass, 'chromecasts',
                          ['cast.living_room', 'cast.bedroom'])

        self.assertEqual(STATE_UNKNOWN, grp.state)
Beispiel #5
0
    def update_group(self):
        """Set up and/or update component group."""
        if self.group is None and self.group_name is not None:
            self.group = group.Group(self.hass,
                                     self.group_name,
                                     user_defined=False)

        if self.group is not None:
            self.group.update_tracked_entity_ids(self.entities.keys())
Beispiel #6
0
    def setUp(self):  # pylint: disable=invalid-name
        """ Init needed objects. """
        self.hass = ha.HomeAssistant()

        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(
            self.hass, 'init_group', ['light.Bowl', 'light.Ceiling'], False)

        self.group_entity_id = test_group.entity_id
Beispiel #7
0
    def test_setup_group_with_mixed_groupable_states(self):
        """ Try to setup a group with mixed groupable states """
        self.hass.states.set('device_tracker.Paulus', STATE_HOME)
        group.Group(self.hass, 'person_and_light',
                    ['light.Bowl', 'device_tracker.Paulus'])

        self.assertEqual(
            STATE_ON,
            self.hass.states.get(
                group.ENTITY_ID_FORMAT.format('person_and_light')).state)
Beispiel #8
0
    def test_expand_entity_ids(self):
        """Test expand_entity_ids method."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        self.assertEqual(
            sorted(['light.ceiling', 'light.bowl']),
            sorted(group.expand_entity_ids(self.hass, [test_group.entity_id])))
Beispiel #9
0
    def test_get_entity_ids_with_domain_filter(self):
        """Test if get_entity_ids works with a domain_filter."""
        self.hass.states.set('switch.AC', STATE_OFF)

        mixed_group = group.Group(self.hass, 'mixed_group',
                                  ['light.Bowl', 'switch.AC'], False)

        self.assertEqual(['switch.ac'],
                         group.get_entity_ids(self.hass,
                                              mixed_group.entity_id,
                                              domain_filter="switch"))
Beispiel #10
0
    def test_group_turns_off_if_all_off(self):
        """Test if turn off if the last device that was on turns off."""
        self.hass.states.set('light.Bowl', STATE_OFF)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        self.hass.pool.block_till_done()

        group_state = self.hass.states.get(test_group.entity_id)
        self.assertEqual(STATE_OFF, group_state.state)
Beispiel #11
0
    def test_group_being_init_before_first_tracked_state_is_set_to_off(self):
        """ Test if the group turns off if no states existed and now a state it is
            tracking is being added as OFF. """
        test_group = group.Group(
            self.hass, 'test group', ['light.not_there_1'])

        self.hass.states.set('light.not_there_1', STATE_OFF)

        self.hass.pool.block_till_done()

        group_state = self.hass.states.get(test_group.entity_id)
        self.assertEqual(STATE_OFF, group_state.state)
Beispiel #12
0
 def test_group_updated_after_device_tracker_zone_change(self):
     """Test group state when device tracker in group changes zone."""
     self.hass.states.set('device_tracker.Adam', STATE_HOME)
     self.hass.states.set('device_tracker.Eve', STATE_NOT_HOME)
     self.hass.pool.block_till_done()
     group.Group(self.hass, 'peeps',
                 ['device_tracker.Adam', 'device_tracker.Eve'])
     self.hass.states.set('device_tracker.Adam', 'cool_state_not_home')
     self.hass.pool.block_till_done()
     self.assertEqual(
         STATE_NOT_HOME,
         self.hass.states.get(group.ENTITY_ID_FORMAT.format('peeps')).state)
Beispiel #13
0
    def test_monitor_group(self):
        """Test if the group keeps track of states."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        # Test if group setup in our init mode is ok
        self.assertIn(test_group.entity_id, self.hass.states.entity_ids())

        group_state = self.hass.states.get(test_group.entity_id)
        self.assertEqual(STATE_ON, group_state.state)
        self.assertTrue(group_state.attributes.get(group.ATTR_AUTO))
Beispiel #14
0
    def test_group_turns_on_if_all_are_off_and_one_turns_on(self):
        """Test if turn on if all devices were turned off and one turns on."""
        self.hass.states.set('light.Bowl', STATE_OFF)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        # Turn one on
        self.hass.states.set('light.Ceiling', STATE_ON)
        self.hass.pool.block_till_done()

        group_state = self.hass.states.get(test_group.entity_id)
        self.assertEqual(STATE_ON, group_state.state)
Beispiel #15
0
    def test_is_on(self):
        """Test is_on method."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        self.assertTrue(group.is_on(self.hass, test_group.entity_id))
        self.hass.states.set('light.Bowl', STATE_OFF)
        self.hass.pool.block_till_done()
        self.assertFalse(group.is_on(self.hass, test_group.entity_id))

        # Try on non existing state
        self.assertFalse(group.is_on(self.hass, 'non.existing'))
Beispiel #16
0
    def test_expand_entity_ids_does_not_return_duplicates(self):
        """Test that expand_entity_ids does not return duplicates."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(
            self.hass, 'init_group', ['light.Bowl', 'light.Ceiling'], False)

        self.assertEqual(
            ['light.bowl', 'light.ceiling'],
            sorted(group.expand_entity_ids(
                self.hass, [test_group.entity_id, 'light.Ceiling'])))

        self.assertEqual(
            ['light.bowl', 'light.ceiling'],
            sorted(group.expand_entity_ids(
                self.hass, ['light.bowl', test_group.entity_id])))
Beispiel #17
0
def setup(hass, config):
    """ Track states and offer events for sensors. """
    logger = logging.getLogger(__name__)

    sensors = platform_devices_from_config(config, DOMAIN, hass,
                                           ENTITY_ID_FORMAT, logger)

    @util.Throttle(MIN_TIME_BETWEEN_SCANS)
    def update_sensor_states(now):
        """ Update states of all sensors. """
        if sensors:
            logger.info("Updating sensor states")

            for sensor in sensors.values():
                sensor.update_ha_state(hass, True)

    update_sensor_states(None)

    # Track all sensors in a group
    sensor_group = group.Group(hass, GROUP_NAME_ALL_SENSORS, sensors.keys(),
                               False)

    def sensor_discovered(service, info):
        """ Called when a sensor is discovered. """
        platform = get_component("{}.{}".format(DOMAIN,
                                                DISCOVERY_PLATFORMS[service]))

        discovered = platform.devices_discovered(hass, config, info)

        for sensor in discovered:
            if sensor is not None and sensor not in sensors.values():
                sensor.entity_id = util.ensure_unique_string(
                    ENTITY_ID_FORMAT.format(util.slugify(sensor.name)),
                    sensors.keys())

                sensors[sensor.entity_id] = sensor

                sensor.update_ha_state(hass)

        sensor_group.update_tracked_entity_ids(sensors.keys())

    discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered)

    # Fire every 3 seconds
    hass.track_time_change(update_sensor_states, seconds=range(0, 60, 3))

    return True
Beispiel #18
0
    def __init__(self, hass, device_scanner, seconds, track_new_devices):
        self.hass = hass

        self.device_scanner = device_scanner

        self.lock = threading.Lock()

        # Do we track new devices by default?
        self.track_new_devices = track_new_devices

        # Dictionary to keep track of known devices and devices we track
        self.tracked = {}
        self.untracked_devices = set()

        # Did we encounter an invalid known devices file
        self.invalid_known_devices_file = False

        # Wrap it in a func instead of lambda so it can be identified in
        # the bus by its __name__ attribute.
        def update_device_state(now):
            """ Triggers update of the device states. """
            self.update_devices(now)

        dev_group = group.Group(
            hass, GROUP_NAME_ALL_DEVICES, user_defined=False)

        def reload_known_devices_service(service):
            """ Reload known devices file. """
            self._read_known_devices_file()

            self.update_devices(dt_util.utcnow())

            dev_group.update_tracked_entity_ids(self.device_entity_ids)

        reload_known_devices_service(None)

        if self.invalid_known_devices_file:
            return

        seconds = range(0, 60, seconds)

        _LOGGER.info("Device tracker interval second=%s", seconds)
        track_utc_time_change(hass, update_device_state, second=seconds)

        hass.services.register(DOMAIN,
                               SERVICE_DEVICE_TRACKER_RELOAD,
                               reload_known_devices_service)
Beispiel #19
0
    def test_closest_function_home_vs_group_entity_id(self):
        self.hass.states.set('test_domain.object', 'happy', {
            'latitude': self.hass.config.latitude + 0.1,
            'longitude': self.hass.config.longitude + 0.1,
        })

        self.hass.states.set('not_in_group.but_closer', 'happy', {
            'latitude': self.hass.config.latitude,
            'longitude': self.hass.config.longitude,
        })

        group.Group(self.hass, 'location group', ['test_domain.object'])

        self.assertEqual(
            'test_domain.object',
            template.render(self.hass,
                            '{{ closest("group.location_group").entity_id }}'))
Beispiel #20
0
def setup(hass, config):
    """Setup example component."""
    target_entity =  config[DOMAIN].get('target')
    name =  config[DOMAIN].get('name', DOMAIN + ' ' + target_entity)

    object_id_enable = DOMAIN + '_' + target_entity + '_enable'
    object_id_hour = DOMAIN + '_' + target_entity + '_hour'
    object_id_temp = DOMAIN + '_' + target_entity + '_temp'

    def activate(now):
        if hass.states.get('input_boolean.' + object_id_enable).state == 'off':
            return
        if not str(now.hour) == str(int(float(hass.states.get('input_slider.' + object_id_hour).state))):
            return

        climate.set_temperature(hass, hass.states.get('input_slider.' + object_id_temp).state, entity_id='climate.'+target_entity)
        hass.states.set('input_boolean.' + object_id_enable, 'off')
        
    _config = config['input_boolean']
    _config[object_id_enable] = {'name': 'Enable', 'initial': False}
    config['input_boolean'] = _config
    input_boolean.setup(hass, config)

    _config = config['input_slider']
    _config[object_id_hour] = {'name': 'Hour', 'initial': 15, 'min': 7, 'max': 23, 'step': 1}
    _config[object_id_temp] = {'name': 'Temp', 'initial': 20, 'min': 17, 'max': 22, 'step': 0.5}
    config['input_slider'] = _config
    input_slider.setup(hass, config)

    #_config = {'platform': 'template', 'sensors': { object_id_hour: {'value_template': '{{ states("input_slider.' + object_id_hour + '") | round(0) }}'}}}
    #config['sensor'] = _config
    #sensor.setup(hass, config)

    group.Group(hass,name, ['input_boolean.' + object_id_enable, 'input_slider.' + object_id_hour, 'input_slider.' + object_id_temp])

    track_time_change(hass, activate, minute=0, second=2)

    def enable(entity_id, old_state, new_state):
        hass.states.set('input_boolean.' + object_id_enable, 'on')

    track_state_change(hass, ['input_slider.' + object_id_hour, 'input_slider.' + object_id_temp], enable)

    return True
Beispiel #21
0
    def test_setup(self):
        """Test setup method."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(self.hass, 'init_group',
                                 ['light.Bowl', 'light.Ceiling'], False)

        _setup_component(
            self.hass, 'group', {
                'group': {
                    'second_group': {
                        'entities': 'light.Bowl, ' + test_group.entity_id,
                        'icon': 'mdi:work',
                        'view': True,
                    },
                    'test_group': 'hello.world,sensor.happy',
                    'empty_group': {
                        'name': 'Empty Group',
                        'entities': None
                    },
                }
            })

        group_state = self.hass.states.get(
            group.ENTITY_ID_FORMAT.format('second_group'))
        self.assertEqual(STATE_ON, group_state.state)
        self.assertEqual(set((test_group.entity_id, 'light.bowl')),
                         set(group_state.attributes['entity_id']))
        self.assertIsNone(group_state.attributes.get(group.ATTR_AUTO))
        self.assertEqual('mdi:work', group_state.attributes.get(ATTR_ICON))
        self.assertTrue(group_state.attributes.get(group.ATTR_VIEW))
        self.assertTrue(group_state.attributes.get(ATTR_HIDDEN))

        group_state = self.hass.states.get(
            group.ENTITY_ID_FORMAT.format('test_group'))
        self.assertEqual(STATE_UNKNOWN, group_state.state)
        self.assertEqual(set(('sensor.happy', 'hello.world')),
                         set(group_state.attributes['entity_id']))
        self.assertIsNone(group_state.attributes.get(group.ATTR_AUTO))
        self.assertIsNone(group_state.attributes.get(ATTR_ICON))
        self.assertIsNone(group_state.attributes.get(group.ATTR_VIEW))
        self.assertIsNone(group_state.attributes.get(ATTR_HIDDEN))
    def test_closest_function_home_vs_group_state(self):
        """Test closest function home vs group state."""
        self.hass.states.set(
            'test_domain.object', 'happy', {
                'latitude': self.hass.config.latitude + 0.1,
                'longitude': self.hass.config.longitude + 0.1,
            })

        self.hass.states.set(
            'not_in_group.but_closer', 'happy', {
                'latitude': self.hass.config.latitude,
                'longitude': self.hass.config.longitude,
            })

        group.Group(self.hass, 'location group', ['test_domain.object'])

        self.assertEqual(
            'test_domain.object',
            template.Template(
                '{{ closest(states.group.location_group).entity_id }}',
                self.hass).render())
Beispiel #23
0
    def add_entities(self, new_entities):
        """
        Takes in a list of new entities. For each entity will see if it already
        exists. If not, will add it, set it up and push the first state.
        """
        with self.lock:
            for entity in new_entities:
                if entity is None or entity in self.entities.values():
                    continue

                entity.hass = self.hass

                if getattr(entity, 'entity_id', None) is None:
                    entity.entity_id = generate_entity_id(
                        self.entity_id_format, entity.name,
                        self.entities.keys())

                self.entities[entity.entity_id] = entity

                entity.update_ha_state()

            if self.group is None and self.group_name is not None:
                self.group = group.Group(self.hass,
                                         self.group_name,
                                         user_defined=False)

            if self.group is not None:
                self.group.update_tracked_entity_ids(self.entities.keys())

            if self.is_polling or \
               not any(entity.should_poll for entity
                       in self.entities.values()):
                return

            self.is_polling = True

            track_utc_time_change(self.hass,
                                  self._update_entity_states,
                                  second=range(0, 60, self.scan_interval))
Beispiel #24
0
    def test_set_assumed_state_based_on_tracked(self):
        """Test assumed state."""
        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.states.set('light.Ceiling', STATE_OFF)
        test_group = group.Group(
            self.hass, 'init_group',
            ['light.Bowl', 'light.Ceiling', 'sensor.no_exist'])

        state = self.hass.states.get(test_group.entity_id)
        self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))

        self.hass.states.set('light.Bowl', STATE_ON,
                             {ATTR_ASSUMED_STATE: True})
        self.hass.pool.block_till_done()

        state = self.hass.states.get(test_group.entity_id)
        self.assertTrue(state.attributes.get(ATTR_ASSUMED_STATE))

        self.hass.states.set('light.Bowl', STATE_ON)
        self.hass.pool.block_till_done()

        state = self.hass.states.get(test_group.entity_id)
        self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
    def setup(self, config):
        """
        Sets up a full device component:
         - Loads the platforms from the config
         - Will update devices on an interval
         - Will listen for supported discovered platforms
        """

        # only setup group if name is given
        if self.group_name is None:
            self.group = None
        else:
            self.group = group.Group(self.hass, self.group_name,
                                     user_defined=False)

        # Look in config for Domain, Domain 2, Domain 3 etc and load them
        for p_type, p_config in \
                config_per_platform(config, self.domain, self.logger):

            self._setup_platform(p_type, p_config)

        if self.discovery_platforms:
            discovery.listen(self.hass, self.discovery_platforms.keys(),
                             self._device_discovered)
Beispiel #26
0
 def setup_group(self):
     """Initialize group for all tracked devices."""
     entity_ids = (dev.entity_id for dev in self.devices.values()
                   if dev.track)
     self.group = group.Group(self.hass, GROUP_NAME_ALL_DEVICES, entity_ids,
                              False)
Beispiel #27
0
def setup(hass, config):
    """ Exposes light control via statemachine and services. """

    # Load built-in profiles and custom profiles
    profile_paths = [
        os.path.join(os.path.dirname(__file__), LIGHT_PROFILES_FILE),
        hass.get_config_path(LIGHT_PROFILES_FILE)
    ]
    profiles = {}

    for profile_path in profile_paths:

        if os.path.isfile(profile_path):
            with open(profile_path) as inp:
                reader = csv.reader(inp)

                # Skip the header
                next(reader, None)

                try:
                    for profile_id, color_x, color_y, brightness in reader:
                        profiles[profile_id] = (float(color_x), float(color_y),
                                                int(brightness))

                except ValueError:
                    # ValueError if not 4 values per row
                    # ValueError if convert to float/int failed
                    _LOGGER.error("Error parsing light profiles from %s",
                                  profile_path)

                    return False

    # Dict to track entity_id -> lights
    lights = {}

    # Track all lights in a group
    light_group = group.Group(hass, GROUP_NAME_ALL_LIGHTS, user_defined=False)

    def add_lights(new_lights):
        """ Add lights to the component to track. """
        for light in new_lights:
            if light is not None and light not in lights.values():
                light.entity_id = generate_entity_id(ENTITY_ID_FORMAT,
                                                     light.name, lights.keys())

                lights[light.entity_id] = light

                light.update_ha_state(hass)

        light_group.update_tracked_entity_ids(lights.keys())

    for p_type, p_config in config_per_platform(config, DOMAIN, _LOGGER):
        platform = get_component(ENTITY_ID_FORMAT.format(p_type))

        if platform is None:
            _LOGGER.error("Unknown type specified: %s", p_type)

        platform.setup_platform(hass, p_config, add_lights)

    def update_lights_state(now):
        """ Update the states of all the lights. """
        if lights:
            _LOGGER.info("Updating light states")

            for light in lights.values():
                light.update_ha_state(hass, True)

    update_lights_state(None)

    def light_discovered(service, info):
        """ Called when a light is discovered. """
        platform = get_component(
            ENTITY_ID_FORMAT.format(DISCOVERY_PLATFORMS[service]))

        platform.setup_platform(hass, {}, add_lights, info)

    discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), light_discovered)

    def handle_light_service(service):
        """ Hande a turn light on or off service call. """
        # Get and validate data
        dat = service.data

        # Convert the entity ids to valid light ids
        target_lights = [
            lights[entity_id]
            for entity_id in extract_entity_ids(hass, service)
            if entity_id in lights
        ]

        if not target_lights:
            target_lights = lights.values()

        params = {}

        transition = util.convert(dat.get(ATTR_TRANSITION), int)

        if transition is not None:
            params[ATTR_TRANSITION] = transition

        if service.service == SERVICE_TURN_OFF:
            for light in target_lights:
                # pylint: disable=star-args
                light.turn_off(**params)

        else:
            # Processing extra data for turn light on request

            # We process the profile first so that we get the desired
            # behavior that extra service data attributes overwrite
            # profile values
            profile = profiles.get(dat.get(ATTR_PROFILE))

            if profile:
                *params[ATTR_XY_COLOR], params[ATTR_BRIGHTNESS] = profile

            if ATTR_BRIGHTNESS in dat:
                # We pass in the old value as the default parameter if parsing
                # of the new one goes wrong.
                params[ATTR_BRIGHTNESS] = util.convert(
                    dat.get(ATTR_BRIGHTNESS), int, params.get(ATTR_BRIGHTNESS))

            if ATTR_XY_COLOR in dat:
                try:
                    # xy_color should be a list containing 2 floats
                    xycolor = dat.get(ATTR_XY_COLOR)

                    # Without this check, a xycolor with value '99' would work
                    if not isinstance(xycolor, str):
                        params[ATTR_XY_COLOR] = [float(val) for val in xycolor]

                except (TypeError, ValueError):
                    # TypeError if xy_color is not iterable
                    # ValueError if value could not be converted to float
                    pass

            if ATTR_RGB_COLOR in dat:
                try:
                    # rgb_color should be a list containing 3 ints
                    rgb_color = dat.get(ATTR_RGB_COLOR)

                    if len(rgb_color) == 3:
                        params[ATTR_XY_COLOR] = \
                            util.color_RGB_to_xy(int(rgb_color[0]),
                                                 int(rgb_color[1]),
                                                 int(rgb_color[2]))

                except (TypeError, ValueError):
                    # TypeError if rgb_color is not iterable
                    # ValueError if not all values can be converted to int
                    pass

            if ATTR_FLASH in dat:
                if dat[ATTR_FLASH] == FLASH_SHORT:
                    params[ATTR_FLASH] = FLASH_SHORT

                elif dat[ATTR_FLASH] == FLASH_LONG:
                    params[ATTR_FLASH] = FLASH_LONG

            for light in target_lights:
                # pylint: disable=star-args
                light.turn_on(**params)

        for light in target_lights:
            light.update_ha_state(hass, True)

    # Update light state every 30 seconds
    hass.track_time_change(update_lights_state, second=[0, 30])

    # Listen for light on and light off service calls
    hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_light_service)

    hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_light_service)

    return True
Beispiel #28
0
    def test_setup_empty_group(self):
        """Try to setup an empty group."""
        grp = group.Group(self.hass, 'nothing', [])

        self.assertEqual(STATE_UNKNOWN, grp.state)
Beispiel #29
0
    def test_groups_get_unique_names(self):
        """Two groups with same name should both have a unique entity id."""
        grp1 = group.Group(self.hass, 'Je suis Charlie')
        grp2 = group.Group(self.hass, 'Je suis Charlie')

        self.assertNotEqual(grp1.entity_id, grp2.entity_id)
Beispiel #30
0
def setup(hass, config):
    """ Track states and offer events for switches. """
    logger = logging.getLogger(__name__)

    switches = platform_devices_from_config(
        config, DOMAIN, hass, ENTITY_ID_FORMAT, logger)

    @util.Throttle(MIN_TIME_BETWEEN_SCANS)
    def update_states(now):
        """ Update states of all switches. """
        if switches:
            logger.info("Updating switch states")

            for switch in switches.values():
                switch.update_ha_state(hass, True)

    update_states(None)

    # Track all switches in a group
    switch_group = group.Group(
        hass, GROUP_NAME_ALL_SWITCHES, switches.keys(), False)

    def switch_discovered(service, info):
        """ Called when a switch is discovered. """
        platform = get_component("{}.{}".format(
            DOMAIN, DISCOVERY_PLATFORMS[service]))

        discovered = platform.devices_discovered(hass, config, info)

        for switch in discovered:
            if switch is not None and switch not in switches.values():
                switch.entity_id = generate_entity_id(
                    ENTITY_ID_FORMAT, switch.name, switches.keys())

                switches[switch.entity_id] = switch

                switch.update_ha_state(hass)

        switch_group.update_tracked_entity_ids(switches.keys())

    discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), switch_discovered)

    def handle_switch_service(service):
        """ Handles calls to the switch services. """
        target_switches = [switches[entity_id] for entity_id
                           in extract_entity_ids(hass, service)
                           if entity_id in switches]

        if not target_switches:
            target_switches = switches.values()

        for switch in target_switches:
            if service.service == SERVICE_TURN_ON:
                switch.turn_on()
            else:
                switch.turn_off()

            switch.update_ha_state(hass)

    # Update state every 30 seconds
    hass.track_time_change(update_states, second=[0, 30])

    hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service)

    hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service)

    return True