async def test_homekit_too_many_accessories(opp, hk_driver, caplog, mock_zeroconf): """Test adding too many accessories to HomeKit.""" entry = await async_init_integration(opp) entity_filter = generate_filter(["cover", "light"], ["demo.test"], [], []) homekit = _mock_homekit(opp, entry, HOMEKIT_MODE_BRIDGE, entity_filter) def _mock_bridge(*_): mock_bridge = HomeBridge(opp, hk_driver, "mock_bridge") # The bridge itself counts as an accessory mock_bridge.accessories = range(MAX_DEVICES) return mock_bridge homekit.driver = hk_driver homekit.driver.accessory = Accessory(hk_driver, "any") opp.states.async_set("light.demo", "on") opp.states.async_set("light.demo2", "on") opp.states.async_set("light.demo3", "on") with patch("pyhap.accessory_driver.AccessoryDriver.async_start"), patch( f"{PATH_HOMEKIT}.show_setup_message"), patch( f"{PATH_HOMEKIT}.HomeBridge", _mock_bridge): await homekit.async_start() await opp.async_block_till_done() assert "would exceed" in caplog.text
def __init__( self, opp: OpenPeerPower, keep_days: int, purge_interval: int, uri: str, include: Dict, exclude: Dict, ) -> None: """Initialize the recorder.""" threading.Thread.__init__(self, name="Recorder") self.opp = opp self.keep_days = keep_days self.purge_interval = purge_interval self.queue: Any = queue.Queue() self.recording_start = dt_util.utcnow() self.db_url = uri self.async_db_ready = asyncio.Future() self.engine: Any = None self.run_info: Any = None self.entity_filter = generate_filter( include.get(CONF_DOMAINS, []), include.get(CONF_ENTITIES, []), exclude.get(CONF_DOMAINS, []), exclude.get(CONF_ENTITIES, []), ) self.exclude_t = exclude.get(CONF_EVENT_TYPES, []) self.get_session = None
def test_no_filters_case_1(): """If include and exclude not included, pass everything.""" incl_dom = {} incl_ent = {} excl_dom = {} excl_ent = {} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent) for value in ("sensor.test", "sun.sun", "light.test"): assert testfilter(value)
def test_excludes_only_case_3(): """If exclude specified, pass all but specified (Case 3).""" incl_dom = {} incl_ent = {} excl_dom = {"light", "sensor"} excl_ent = {"binary_sensor.working"} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent) assert testfilter("sensor.test") is False assert testfilter("light.test") is False assert testfilter("binary_sensor.working") is False assert testfilter("binary_sensor.another") assert testfilter("sun.sun") is True
def test_includes_only_case_2(): """If include specified, only pass if specified (Case 2).""" incl_dom = {"light", "sensor"} incl_ent = {"binary_sensor.working"} excl_dom = {} excl_ent = {} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent) assert testfilter("sensor.test") assert testfilter("light.test") assert testfilter("binary_sensor.working") assert testfilter("binary_sensor.notworking") is False assert testfilter("sun.sun") is False
def _mock_homekit(opp, entry, homekit_mode, entity_filter=None): return HomeKit( opp=opp, name=BRIDGE_NAME, port=DEFAULT_PORT, ip_address=None, entity_filter=entity_filter or generate_filter([], [], [], []), exclude_accessory_mode=False, entity_config={}, homekit_mode=homekit_mode, advertise_ip=None, entry_id=entry.entry_id, entry_title=entry.title, )
def test_with_include_domain_case4a(): """Test case 4a - include and exclude specified, with included domain.""" incl_dom = {"light", "sensor"} incl_ent = {"binary_sensor.working"} excl_dom = {} excl_ent = {"light.ignoreme", "sensor.notworking"} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent) assert testfilter("sensor.test") assert testfilter("sensor.notworking") is False assert testfilter("light.test") assert testfilter("light.ignoreme") is False assert testfilter("binary_sensor.working") assert testfilter("binary_sensor.another") is False assert testfilter("sun.sun") is False
async def async_setup(opp, config): """Set up the MQTT state feed.""" conf = config.get(DOMAIN, {}) base_topic = conf.get(CONF_BASE_TOPIC) pub_include = conf.get(CONF_INCLUDE, {}) pub_exclude = conf.get(CONF_EXCLUDE, {}) publish_attributes = conf.get(CONF_PUBLISH_ATTRIBUTES) publish_timestamps = conf.get(CONF_PUBLISH_TIMESTAMPS) publish_filter = generate_filter( pub_include.get(CONF_DOMAINS, []), pub_include.get(CONF_ENTITIES, []), pub_exclude.get(CONF_DOMAINS, []), pub_exclude.get(CONF_ENTITIES, []), ) if not base_topic.endswith("/"): base_topic = base_topic + "/" @callback def _state_publisher(entity_id, old_state, new_state): if new_state is None: return if not publish_filter(entity_id): return payload = new_state.state mybase = base_topic + entity_id.replace(".", "/") + "/" opp.components.mqtt.async_publish(mybase + "state", payload, 1, True) if publish_timestamps: if new_state.last_updated: opp.components.mqtt.async_publish( mybase + "last_updated", new_state.last_updated.isoformat(), 1, True) if new_state.last_changed: opp.components.mqtt.async_publish( mybase + "last_changed", new_state.last_changed.isoformat(), 1, True) if publish_attributes: for key, val in new_state.attributes.items(): encoded_val = json.dumps(val, cls=JSONEncoder) opp.components.mqtt.async_publish(mybase + key, encoded_val, 1, True) async_track_state_change(opp, MATCH_ALL, _state_publisher) return True
def _generate_filter_from_config(config): excluded_entities = [] excluded_domains = [] included_entities = [] included_domains = [] exclude = config.get(CONF_EXCLUDE) if exclude: excluded_entities = exclude.get(CONF_ENTITIES, []) excluded_domains = exclude.get(CONF_DOMAINS, []) include = config.get(CONF_INCLUDE) if include: included_entities = include.get(CONF_ENTITIES, []) included_domains = include.get(CONF_DOMAINS, []) return generate_filter(included_domains, included_entities, excluded_domains, excluded_entities)
async def test_homekit_entity_filter(opp, mock_zeroconf): """Test the entity filter.""" entry = await async_init_integration(opp) entity_filter = generate_filter(["cover"], ["demo.test"], [], []) homekit = _mock_homekit(opp, entry, HOMEKIT_MODE_BRIDGE, entity_filter) homekit.bridge = Mock() homekit.bridge.accessories = {} opp.states.async_set("cover.test", "open") opp.states.async_set("demo.test", "on") opp.states.async_set("light.demo", "on") filtered_states = await homekit.async_configure_accessories() assert opp.states.get("cover.test") in filtered_states assert opp.states.get("demo.test") in filtered_states assert opp.states.get("light.demo") not in filtered_states
def test_excludes_only_with_glob_case_3(): """If exclude specified, pass all but specified (Case 3).""" incl_dom = {} incl_glob = {} incl_ent = {} excl_dom = {"light", "sensor"} excl_glob = {"cover.*_window"} excl_ent = {"binary_sensor.working"} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent, incl_glob, excl_glob) assert testfilter("sensor.test") is False assert testfilter("light.test") is False assert testfilter("cover.bedroom_window") is False assert testfilter("binary_sensor.working") is False assert testfilter("binary_sensor.another") assert testfilter("sun.sun") is True assert testfilter("cover.garage_door")
def test_includes_only_with_glob_case_2(): """If include specified, only pass if specified (Case 2).""" incl_dom = {"light", "sensor"} incl_glob = {"cover.*_window"} incl_ent = {"binary_sensor.working"} excl_dom = {} excl_glob = {} excl_ent = {} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent, incl_glob, excl_glob) assert testfilter("sensor.test") assert testfilter("light.test") assert testfilter("cover.bedroom_window") assert testfilter("binary_sensor.working") assert testfilter("binary_sensor.notworking") is False assert testfilter("sun.sun") is False assert testfilter("cover.garage_door") is False
def test_exclude_glob_case4b(): """Test case 4b - include and exclude specified, with excluded glob.""" incl_dom = {} incl_glob = {} incl_ent = {"binary_sensor.working"} excl_dom = {} excl_glob = {"binary_sensor.*"} excl_ent = {"light.ignoreme", "sensor.notworking"} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent, incl_glob, excl_glob) assert testfilter("sensor.test") assert testfilter("sensor.notworking") is False assert testfilter("light.test") assert testfilter("light.ignoreme") is False assert testfilter("binary_sensor.working") assert testfilter("binary_sensor.another") is False assert testfilter("sun.sun") is True
def test_with_include_domain_glob_filtering_case4a(): """Test case 4a - include and exclude specified, both have domains and globs.""" incl_dom = {"light"} incl_glob = {"*working"} incl_ent = {} excl_dom = {"binary_sensor"} excl_glob = {"*notworking"} excl_ent = {"light.ignoreme"} testfilter = generate_filter(incl_dom, incl_ent, excl_dom, excl_ent, incl_glob, excl_glob) assert testfilter("sensor.working") assert testfilter("sensor.notworking") is False assert testfilter("light.test") assert testfilter("light.notworking") is False assert testfilter("light.ignoreme") is False assert testfilter("binary_sensor.not_working") is False assert testfilter("binary_sensor.another") is False assert testfilter("sun.sun") is False
async def test_homekit_start_with_a_broken_accessory(opp, hk_driver, mock_zeroconf): """Test HomeKit start method.""" entry = MockConfigEntry(domain=DOMAIN, data={ CONF_NAME: "mock_name", CONF_PORT: 12345 }) entity_filter = generate_filter(["cover", "light"], ["demo.test"], [], []) await async_init_entry(opp, entry) homekit = _mock_homekit(opp, entry, HOMEKIT_MODE_BRIDGE, entity_filter) homekit.bridge = Mock() homekit.bridge.accessories = [] homekit.driver = hk_driver homekit.driver.accessory = Accessory(hk_driver, "any") opp.states.async_set("light.demo", "on") opp.states.async_set("light.broken", "on") with patch(f"{PATH_HOMEKIT}.get_accessory", side_effect=Exception), patch( f"{PATH_HOMEKIT}.show_setup_message") as mock_setup_msg, patch( "pyhap.accessory_driver.AccessoryDriver.async_start" ) as hk_driver_start: await homekit.async_start() await opp.async_block_till_done() mock_setup_msg.assert_called_with(opp, entry.entry_id, "Mock Title (Open Peer Power Bridge)", ANY, ANY) assert hk_driver_start.called assert homekit.status == STATUS_RUNNING # Test start() if already started hk_driver_start.reset_mock() await homekit.async_start() await opp.async_block_till_done() assert not hk_driver_start.called
def _get_events( opp, start_day, end_day, entity_ids=None, filters=None, entities_filter=None, entity_matches_only=False, context_id=None, ): """Get events for a period of time.""" assert not (entity_ids and context_id), "can't pass in both entity_ids and context_id" entity_attr_cache = EntityAttributeCache(opp) context_lookup = {None: None} def yield_events(query): """Yield Events that are not filtered away.""" for row in query.yield_per(1000): event = LazyEventPartialState(row) context_lookup.setdefault(event.context_id, event) if event.event_type == EVENT_CALL_SERVICE: continue if event.event_type == EVENT_STATE_CHANGED or _keep_event( opp, event, entities_filter): yield event if entity_ids is not None: entities_filter = generate_filter([], entity_ids, [], []) with session_scope(opp=opp) as session: old_state = aliased(States, name="old_state") if entity_ids is not None: query = _generate_events_query_without_states(session) query = _apply_event_time_filter(query, start_day, end_day) query = _apply_event_types_filter( opp, query, ALL_EVENT_TYPES_EXCEPT_STATE_CHANGED) if entity_matches_only: # When entity_matches_only is provided, contexts and events that do not # contain the entity_ids are not included in the logbook response. query = _apply_event_entity_id_matchers(query, entity_ids) query = query.union_all( _generate_states_query(session, start_day, end_day, old_state, entity_ids)) else: query = _generate_events_query(session) query = _apply_event_time_filter(query, start_day, end_day) query = _apply_events_types_and_states_filter( opp, query, old_state).filter((States.last_updated == States.last_changed) | (Events.event_type != EVENT_STATE_CHANGED)) if filters: query = query.filter(filters.entity_filter() | ( Events.event_type != EVENT_STATE_CHANGED)) if context_id is not None: query = query.filter(Events.context_id == context_id) query = query.order_by(Events.time_fired) return list( humanify(opp, yield_events(query), entity_attr_cache, context_lookup))