def test_expand_entity_ids_does_not_return_duplicates(self): """ Test that expand_entity_ids does not return duplicates. """ self.assertEqual( ['light.bowl', 'light.ceiling'], sorted(group.expand_entity_ids( self.hass, [self.group_entity_id, 'light.Ceiling']))) self.assertEqual( ['light.bowl', 'light.ceiling'], sorted(group.expand_entity_ids( self.hass, ['light.bowl', self.group_entity_id])))
def test_expand_entity_ids(self): """ Test expand_entity_ids method. """ self.assertEqual(sorted(['light.Ceiling', 'light.Bowl']), sorted(group.expand_entity_ids( self.hass, [self.group_name]))) # Make sure that no duplicates are returned self.assertEqual( sorted(['light.Ceiling', 'light.Bowl']), sorted(group.expand_entity_ids( self.hass, [self.group_name, 'light.Ceiling']))) # Test that non strings are ignored self.assertEqual([], group.expand_entity_ids(self.hass, [5, True]))
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.create_group( self.hass, 'init_group', ['light.Bowl', 'light.Ceiling'], False) assert ['light.bowl', 'light.ceiling'] == \ sorted(group.expand_entity_ids( self.hass, [test_group.entity_id, 'light.Ceiling'])) assert ['light.bowl', 'light.ceiling'] == \ sorted(group.expand_entity_ids( self.hass, ['light.bowl', test_group.entity_id]))
async def test_expand_entity_ids_does_not_return_duplicates(hass): """Test that expand_entity_ids does not return duplicates.""" hass.states.async_set("light.Bowl", STATE_ON) hass.states.async_set("light.Ceiling", STATE_OFF) assert await async_setup_component(hass, "group", {}) test_group = await group.Group.async_create_group( hass, "init_group", ["light.Bowl", "light.Ceiling"], False) assert ["light.bowl", "light.ceiling"] == sorted( group.expand_entity_ids(hass, [test_group.entity_id, "light.Ceiling"])) assert ["light.bowl", "light.ceiling"] == sorted( group.expand_entity_ids(hass, ["light.bowl", test_group.entity_id]))
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.create_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])), )
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.create_group(self.hass, "init_group", ["light.Bowl", "light.Ceiling"], False) assert ["light.bowl", "light.ceiling"] == sorted( group.expand_entity_ids(self.hass, [test_group.entity_id, "light.Ceiling"])) assert ["light.bowl", "light.ceiling"] == sorted( group.expand_entity_ids(self.hass, ["light.bowl", test_group.entity_id]))
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.create_group(self.hass, 'init_group', ['light.Bowl', 'light.Ceiling'], False) assert ['light.bowl', 'light.ceiling'] == \ sorted(group.expand_entity_ids( self.hass, [test_group.entity_id, 'light.Ceiling'])) assert ['light.bowl', 'light.ceiling'] == \ sorted(group.expand_entity_ids( self.hass, ['light.bowl', test_group.entity_id]))
def async_get_nodes_from_targets( hass: HomeAssistant, val: dict[str, Any], ent_reg: er.EntityRegistry | None = None, dev_reg: dr.DeviceRegistry | None = None, logger: logging.Logger = LOGGER, ) -> set[ZwaveNode]: """ Get nodes for all targets. Supports entity_id with group expansion, area_id, and device_id. """ nodes: set[ZwaveNode] = set() # Convert all entity IDs to nodes for entity_id in expand_entity_ids(hass, val.get(ATTR_ENTITY_ID, [])): try: nodes.add( async_get_node_from_entity_id(hass, entity_id, ent_reg, dev_reg)) except ValueError as err: logger.warning(err.args[0]) # Convert all area IDs to nodes for area_id in val.get(ATTR_AREA_ID, []): nodes.update( async_get_nodes_from_area_id(hass, area_id, ent_reg, dev_reg)) # Convert all device IDs to nodes for device_id in val.get(ATTR_DEVICE_ID, []): try: nodes.add(async_get_node_from_device_id(hass, device_id, dev_reg)) except ValueError as err: logger.warning(err.args[0]) return nodes
def __init__( self, hass, name: str, start, end, duration, entity_ids: list, precision: int, undef, ): """Initialize the sensor.""" self._hass = hass self._name = name self._start_template = start self._end_template = end self._duration = duration self._period = self.start = self.end = None self._precision = precision self._undef = undef self._state = None self._unit_of_measurement = None self._icon = None self._temperature_mode = None self.sources = expand_entity_ids(hass, entity_ids) self.count_sources = len(self.sources) self.available_sources = 0 self.count = 0 self.min_value = self.max_value = None
def get_nodes_from_service_data(val: dict[str, Any]) -> dict[str, Any]: """Get nodes set from service data.""" nodes: set[ZwaveNode] = set() # Convert all entity IDs to nodes for entity_id in expand_entity_ids(self._hass, val.pop(ATTR_ENTITY_ID, [])): try: nodes.add( async_get_node_from_entity_id(self._hass, entity_id, self._ent_reg, self._dev_reg)) except ValueError as err: const.LOGGER.warning(err.args[0]) # Convert all area IDs to nodes for area_id in val.pop(ATTR_AREA_ID, []): nodes.update( async_get_nodes_from_area_id(self._hass, area_id, self._ent_reg, self._dev_reg)) # Convert all device IDs to nodes for device_id in val.pop(ATTR_DEVICE_ID, []): try: nodes.add( async_get_node_from_device_id(self._hass, device_id, self._dev_reg)) except ValueError as err: const.LOGGER.warning(err.args[0]) val[const.ATTR_NODES] = nodes return val
def closest(self, *args): """Find closest entity. Closest to home: closest(states) closest(states.device_tracker) closest('group.children') closest(states.group.children) Closest to a point: closest(23.456, 23.456, 'group.children') closest('zone.school', 'group.children') closest(states.zone.school, 'group.children') """ if len(args) == 1: latitude = self._hass.config.latitude longitude = self._hass.config.longitude entities = args[0] elif len(args) == 2: point_state = self._resolve_state(args[0]) if point_state is None: _LOGGER.warning('Closest:Unable to find state %s', args[0]) return None elif not loc_helper.has_location(point_state): _LOGGER.warning( 'Closest:State does not contain valid location: %s', point_state) return None latitude = point_state.attributes.get(ATTR_LATITUDE) longitude = point_state.attributes.get(ATTR_LONGITUDE) entities = args[1] else: latitude = convert(args[0], float) longitude = convert(args[1], float) if latitude is None or longitude is None: _LOGGER.warning( 'Closest:Received invalid coordinates: %s, %s', args[0], args[1]) return None entities = args[2] if isinstance(entities, (AllStates, DomainStates)): states = list(entities) else: if isinstance(entities, State): gr_entity_id = entities.entity_id else: gr_entity_id = str(entities) states = [self._hass.states.get(entity_id) for entity_id in group.expand_entity_ids(self._hass, [gr_entity_id])] return loc_helper.closest(latitude, longitude, states)
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.create_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])) )
def test_expand_entity_ids_expands_nested_groups(self): """Test if entity ids epands to nested groups.""" group.Group.create_group(self.hass, "light", ["light.test_1", "light.test_2"]) group.Group.create_group(self.hass, "switch", ["switch.test_1", "switch.test_2"]) group.Group.create_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"])), )
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'])))
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.create_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])))
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'])))
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])))
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.create_group(self.hass, "init_group", ["light.Bowl", "light.Ceiling"], False) assert sorted(["light.ceiling", "light.bowl"]) == sorted( group.expand_entity_ids(self.hass, [test_group.entity_id]))
def test_expand_entity_ids_recursive(self): """Test expand_entity_ids method with a group that contains itself.""" self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF) test_group = group.Group.create_group( self.hass, 'init_group', ['light.Bowl', 'light.Ceiling', 'group.init_group'], False) self.assertEqual( sorted(['light.ceiling', 'light.bowl']), sorted(group.expand_entity_ids(self.hass, [test_group.entity_id])))
def validate_entities(val: dict[str, Any]) -> dict[str, Any]: """Validate entities exist and are from the zwave_js platform.""" val[ATTR_ENTITY_ID] = expand_entity_ids(self._hass, val[ATTR_ENTITY_ID]) for entity_id in val[ATTR_ENTITY_ID]: entry = self._ent_reg.async_get(entity_id) if entry is None or entry.platform != const.DOMAIN: raise vol.Invalid( f"Entity {entity_id} is not a valid {const.DOMAIN} entity." ) return val
async def test_expand_entity_ids(hass): """Test expand_entity_ids method.""" hass.states.async_set("light.Bowl", STATE_ON) hass.states.async_set("light.Ceiling", STATE_OFF) assert await async_setup_component(hass, "group", {}) test_group = await group.Group.async_create_group( hass, "init_group", ["light.Bowl", "light.Ceiling"], False) assert sorted(["light.ceiling", "light.bowl"]) == sorted( group.expand_entity_ids(hass, [test_group.entity_id]))
def test_expand_entity_ids_recursive(self): """Test expand_entity_ids method with a group that contains itself.""" self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF) test_group = group.Group.create_group( self.hass, 'init_group', ['light.Bowl', 'light.Ceiling', 'group.init_group'], False) assert sorted(['light.ceiling', 'light.bowl']) == \ sorted(group.expand_entity_ids( self.hass, [test_group.entity_id]))
def test_expand_entity_ids_recursive(self): """Test expand_entity_ids method with a group that contains itself.""" self.hass.states.set("light.Bowl", STATE_ON) self.hass.states.set("light.Ceiling", STATE_OFF) test_group = group.Group.create_group( self.hass, "init_group", ["light.Bowl", "light.Ceiling", "group.init_group"], False, ) assert sorted(["light.ceiling", "light.bowl"]) == sorted( group.expand_entity_ids(self.hass, [test_group.entity_id]))
def test_expand_entity_ids_expands_nested_groups(self): """Test if entity ids epands to nested groups.""" group.Group.create_group( self.hass, 'light', ['light.test_1', 'light.test_2']) group.Group.create_group( self.hass, 'switch', ['switch.test_1', 'switch.test_2']) group.Group.create_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'])))
def test_expand_entity_ids_expands_nested_groups(self): """Test if entity ids epands to nested groups.""" group.Group.create_group(self.hass, 'light', ['light.test_1', 'light.test_2']) group.Group.create_group(self.hass, 'switch', ['switch.test_1', 'switch.test_2']) group.Group.create_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'])))
def test_expand_entity_ids_expands_nested_groups(self): """Test if entity ids epands to nested groups.""" group.Group.create_group(self.hass, "light", ["light.test_1", "light.test_2"]) group.Group.create_group(self.hass, "switch", ["switch.test_1", "switch.test_2"]) group.Group.create_group(self.hass, "group_of_groups", ["group.light", "group.switch"]) assert [ "light.test_1", "light.test_2", "switch.test_1", "switch.test_2", ] == sorted( group.expand_entity_ids(self.hass, ["group.group_of_groups"]))
def __init__( self, hass: HomeAssistant, unique_id: Optional[str], name: str, start, end, duration, entity_ids: list, precision: int, undef, ): """Initialize the sensor.""" self._start_template = start self._end_template = end self._duration = duration self._period = self.start = self.end = None self._precision = precision self._undef = undef self._temperature_mode = None self.sources = expand_entity_ids(hass, entity_ids) self.count_sources = len(self.sources) self.available_sources = 0 self.count = 0 self.min_value = self.max_value = None self._attr_name = name self._attr_state = None self._attr_unit_of_measurement = None self._attr_icon = None self._attr_state_class = STATE_CLASS_MEASUREMENT self._attr_device_class = None # self._attr_unique_id = ( str( sha1( ";".join( [str(start), str(duration), str(end), ",".join(self.sources)] ).encode("utf-8") ).hexdigest() ) if unique_id == "__legacy__" else unique_id )
async def test_expand_entity_ids_expands_nested_groups(hass): """Test if entity ids epands to nested groups.""" assert await async_setup_component(hass, "group", {}) await group.Group.async_create_group(hass, "light", ["light.test_1", "light.test_2"]) await group.Group.async_create_group(hass, "switch", ["switch.test_1", "switch.test_2"]) await group.Group.async_create_group(hass, "group_of_groups", ["group.light", "group.switch"]) assert [ "light.test_1", "light.test_2", "switch.test_1", "switch.test_2", ] == sorted(group.expand_entity_ids(hass, ["group.group_of_groups"]))
def validate_entities(val: dict[str, Any]) -> dict[str, Any]: """Validate entities exist and are from the zwave_js platform.""" val[ATTR_ENTITY_ID] = expand_entity_ids(self._hass, val[ATTR_ENTITY_ID]) invalid_entities = [] for entity_id in val[ATTR_ENTITY_ID]: entry = self._ent_reg.async_get(entity_id) if entry is None or entry.platform != const.DOMAIN: _LOGGER.info("Entity %s is not a valid %s entity", entity_id, const.DOMAIN) invalid_entities.append(entity_id) # Remove invalid entities val[ATTR_ENTITY_ID] = list( set(val[ATTR_ENTITY_ID]) - set(invalid_entities)) if not val[ATTR_ENTITY_ID]: raise vol.Invalid( f"No {const.DOMAIN} entities found in service call") return val
def __init__( self, hass: HomeAssistant, name: str, start, end, duration, entity_ids: list, precision: int, undef, ): """Initialize the sensor.""" self._hass = hass self._name = name self._start_template = start self._end_template = end self._duration = duration self._period = self.start = self.end = None self._precision = precision self._undef = undef self._state = None self._unit_of_measurement = None self._icon = None self._temperature_mode = None self.sources = expand_entity_ids(hass, entity_ids) self.count_sources = len(self.sources) self.available_sources = 0 self.count = 0 self.min_value = self.max_value = None self._unique_id = str( sha1(";".join( [str(start), str(duration), str(end), ",".join(self.sources)]).encode("utf-8")).hexdigest())
def closest(self, *args): """Find closest entity. Closest to home: closest(states) closest(states.device_tracker) closest('group.children') closest(states.group.children) Closest to a point: closest(23.456, 23.456, 'group.children') closest('zone.school', 'group.children') closest(states.zone.school, 'group.children') """ if len(args) == 1: latitude = self._hass.config.latitude longitude = self._hass.config.longitude entities = args[0] elif len(args) == 2: point_state = self._resolve_state(args[0]) if point_state is None: _LOGGER.warning('Closest:Unable to find state %s', args[0]) return None elif not loc_helper.has_location(point_state): _LOGGER.warning( 'Closest:State does not contain valid location: %s', point_state) return None latitude = point_state.attributes.get(ATTR_LATITUDE) longitude = point_state.attributes.get(ATTR_LONGITUDE) entities = args[1] else: latitude = convert(args[0], float) longitude = convert(args[1], float) if latitude is None or longitude is None: _LOGGER.warning('Closest:Received invalid coordinates: %s, %s', args[0], args[1]) return None entities = args[2] if isinstance(entities, (AllStates, DomainStates)): states = list(entities) else: if isinstance(entities, State): gr_entity_id = entities.entity_id else: gr_entity_id = str(entities) states = [ self._hass.states.get(entity_id) for entity_id in group.expand_entity_ids( self._hass, [gr_entity_id]) ] return loc_helper.closest(latitude, longitude, states)
def _get_entity_ids(self) -> List[str]: _LOGGER.debug("Entity ids: %s", self._entity_ids) expanded = expand_entity_ids(self._hass, self._entity_ids) self.sources = expanded _LOGGER.debug("Expanded entity ids: %s", expanded) return expanded
def test_expand_entity_ids_ignores_non_strings(self): """Test that non string elements in lists are ignored.""" assert [] == group.expand_entity_ids(self.hass, [5, True])
def test_expand_entity_ids(self): """ Test expand_entity_ids method. """ self.assertEqual(sorted(['light.ceiling', 'light.bowl']), sorted(group.expand_entity_ids( self.hass, [self.group_entity_id])))
def test_expand_entity_ids_ignores_non_strings(self): """Test that non string elements in lists are ignored.""" self.assertEqual([], group.expand_entity_ids(self.hass, [5, True]))