async def state_changed_event_filter_helper(opp): """Run a million events through state changed event helper with 1000 entities that all get filtered.""" count = 0 entity_id = "light.kitchen" events_to_fire = 10 ** 6 @core.callback def listener(*args): """Handle event.""" nonlocal count count += 1 opp.helpers.event.async_track_state_change_event( [f"{entity_id}{idx}" for idx in range(1000)], listener ) event_data = { "entity_id": "switch.no_listeners", "old_state": core.State(entity_id, "off"), "new_state": core.State(entity_id, "on"), } for _ in range(events_to_fire): opp.bus.async_fire(EVENT_STATE_CHANGED, event_data) start = timer() await opp.async_block_till_done() assert count == 0 return timer() - start
async def test_call_to_component(opp): """Test calls to components state reproduction functions.""" with patch( "openpeerpower.components.media_player.reproduce_state.async_reproduce_states" ) as media_player_fun: media_player_fun.return_value = asyncio.Future() media_player_fun.return_value.set_result(None) with patch( "openpeerpower.components.climate.reproduce_state.async_reproduce_states" ) as climate_fun: climate_fun.return_value = asyncio.Future() climate_fun.return_value.set_result(None) state_media_player = ha.State("media_player.test", "bad") state_climate = ha.State("climate.test", "bad") context = "dummy_context" await state.async_reproduce_state( opp, [state_media_player, state_climate], context=context, ) media_player_fun.assert_called_once_with(opp, [state_media_player], context=context, reproduce_options=None) climate_fun.assert_called_once_with(opp, [state_climate], context=context, reproduce_options=None)
def test_state_init(): """Test state.init.""" with pytest.raises(InvalidEntityFormatError): ha.State("invalid_entity_format", "test_state") with pytest.raises(InvalidStateError): ha.State("domain.long_state", "t" * 256)
async def state_changed_helper(opp): """Run a million events through state changed helper with 1000 entities.""" count = 0 entity_id = "light.kitchen" event = asyncio.Event() @core.callback def listener(*args): """Handle event.""" nonlocal count count += 1 if count == 10 ** 6: event.set() for idx in range(1000): opp.helpers.event.async_track_state_change( f"{entity_id}{idx}", listener, "off", "on" ) event_data = { "entity_id": f"{entity_id}0", "old_state": core.State(entity_id, "off"), "new_state": core.State(entity_id, "on"), } for _ in range(10 ** 6): opp.bus.async_fire(EVENT_STATE_CHANGED, event_data) start = timer() await event.wait() return timer() - start
async def test_as_number_coercion(opp): """Test state_as_number with number.""" for _state in ("0", "0.0", 0, 0.0): assert state.state_as_number(ha.State("domain.test", _state, {})) == 0.0 for _state in ("1", "1.0", 1, 1.0): assert state.state_as_number(ha.State("domain.test", _state, {})) == 1.0
async def test_chain_history(opp, values, missing=False): """Test if filter chaining works.""" config = { "sensor": { "platform": "filter", "name": "test", "entity_id": "sensor.test_monitored", "filters": [ {"filter": "outlier", "window_size": 10, "radius": 4.0}, {"filter": "lowpass", "time_constant": 10, "precision": 2}, {"filter": "throttle", "window_size": 1}, ], }, } await async_init_recorder_component(opp) t_0 = dt_util.utcnow() - timedelta(minutes=1) t_1 = dt_util.utcnow() - timedelta(minutes=2) t_2 = dt_util.utcnow() - timedelta(minutes=3) t_3 = dt_util.utcnow() - timedelta(minutes=4) if missing: fake_states = {} else: fake_states = { "sensor.test_monitored": [ ha.State("sensor.test_monitored", 18.0, last_changed=t_0), ha.State("sensor.test_monitored", "unknown", last_changed=t_1), ha.State("sensor.test_monitored", 19.0, last_changed=t_2), ha.State("sensor.test_monitored", 18.2, last_changed=t_3), ] } with patch( "openpeerpower.components.recorder.history.state_changes_during_period", return_value=fake_states, ), patch( "openpeerpower.components.recorder.history.get_last_state_changes", return_value=fake_states, ): with assert_setup_component(1, "sensor"): assert await async_setup_component(opp, "sensor", config) await opp.async_block_till_done() for value in values: opp.states.async_set(config["sensor"]["entity_id"], value.state) await opp.async_block_till_done() state = opp.states.get("sensor.test") if missing: assert state.state == "18.05" else: assert state.state == "17.05"
def test_measure(self): """Test the history statistics sensor measure.""" t0 = dt_util.utcnow() - timedelta(minutes=40) t1 = t0 + timedelta(minutes=20) t2 = dt_util.utcnow() - timedelta(minutes=10) # Start t0 t1 t2 End # |--20min--|--20min--|--10min--|--10min--| # |---off---|---on----|---off---|---on----| fake_states = { "binary_sensor.test_id": [ op.State("binary_sensor.test_id", "on", last_changed=t0), op.State("binary_sensor.test_id", "off", last_changed=t1), op.State("binary_sensor.test_id", "on", last_changed=t2), ] } start = Template("{{ as_timestamp(now()) - 3600 }}", self.opp) end = Template("{{ now() }}", self.opp) sensor1 = HistoryStatsSensor(self.opp, "binary_sensor.test_id", "on", start, end, None, "time", "Test") sensor2 = HistoryStatsSensor(self.opp, "unknown.id", "on", start, end, None, "time", "Test") sensor3 = HistoryStatsSensor(self.opp, "binary_sensor.test_id", "on", start, end, None, "count", "test") sensor4 = HistoryStatsSensor(self.opp, "binary_sensor.test_id", "on", start, end, None, "ratio", "test") assert sensor1._type == "time" assert sensor3._type == "count" assert sensor4._type == "ratio" with patch( "openpeerpower.components.history.state_changes_during_period", return_value=fake_states, ): with patch("openpeerpower.components.history.get_state", return_value=None): sensor1.update() sensor2.update() sensor3.update() sensor4.update() assert sensor1.state == 0.5 assert sensor2.state is None assert sensor3.state == 2 assert sensor4.state == 50
async def test_as_number_states(opp): """Test state_as_number with states.""" zero_states = ( STATE_OFF, STATE_CLOSED, STATE_UNLOCKED, STATE_BELOW_HORIZON, STATE_NOT_HOME, ) one_states = (STATE_ON, STATE_OPEN, STATE_LOCKED, STATE_ABOVE_HORIZON, STATE_HOME) for _state in zero_states: assert state.state_as_number(ha.State("domain.test", _state, {})) == 0 for _state in one_states: assert state.state_as_number(ha.State("domain.test", _state, {})) == 1
def test_initial_outlier(values): """Test issue #13363.""" filt = OutlierFilter(window_size=3, precision=2, entity=None, radius=4.0) out = ha.State("sensor.test_monitored", 4000) for state in [out] + values: filtered = filt.filter_state(state) assert filtered.state == 21
def test_trace_json_encoder(opp): """Test the Trace JSON Encoder.""" ha_json_enc = ExtendedJSONEncoder() state = core.State("test.test", "hello") # Test serializing a datetime now = dt_util.utcnow() assert ha_json_enc.default(now) == now.isoformat() # Test serializing a timedelta data = timedelta( days=50, seconds=27, microseconds=10, milliseconds=29000, minutes=5, hours=8, weeks=2, ) assert ha_json_enc.default(data) == { "__type": str(type(data)), "total_seconds": data.total_seconds(), } # Test serializing a set() data = {"milk", "beer"} assert sorted(ha_json_enc.default(data)) == sorted(data) # Test serializong object which implements as_dict assert ha_json_enc.default(state) == state.as_dict() # Default method falls back to repr(o) o = object() assert ha_json_enc.default(o) == {"__type": str(type(o)), "repr": repr(o)}
def test_state_repr(): """Test state.repr.""" assert (str( ha.State( "happy.happy", "on", last_changed=datetime( 1984, 12, 8, 12, 0, 0))) == "<state happy.happy=on @ 1984-12-08T12:00:00+00:00>") assert (str( ha.State( "happy.happy", "on", {"brightness": 144}, datetime(1984, 12, 8, 12, 0, 0), )) == "<state happy.happy=on; brightness=144 @ " "1984-12-08T12:00:00+00:00>")
def test_state_as_dict(): """Test a State as dictionary.""" last_time = datetime(1984, 12, 8, 12, 0, 0) state = ha.State( "happy.happy", "on", {"pig": "dog"}, last_updated=last_time, last_changed=last_time, ) expected = { "context": { "id": state.context.id, "parent_id": None, "user_id": state.context.user_id, }, "entity_id": "happy.happy", "attributes": { "pig": "dog" }, "last_changed": last_time.isoformat(), "last_updated": last_time.isoformat(), "state": "on", } assert state.as_dict() == expected # 2nd time to verify cache assert state.as_dict() == expected assert state.as_dict() is state.as_dict()
async def test_event_listener_defaults(opp, mock_client): """Test event listener.""" config = {"statsd": {"host": "host", "value_mapping": {"custom": 3}}} config["statsd"][statsd.CONF_RATE] = statsd.DEFAULT_RATE opp.bus.listen = MagicMock() await async_setup_component(opp, statsd.DOMAIN, config) assert opp.bus.listen.called handler_method = opp.bus.listen.call_args_list[0][0][1] valid = {"1": 1, "1.0": 1.0, "custom": 3, STATE_ON: 1, STATE_OFF: 0} for in_, out in valid.items(): state = MagicMock(state=in_, attributes={"attribute key": 3.2}) handler_method(MagicMock(data={"new_state": state})) mock_client.gauge.assert_has_calls( [mock.call(state.entity_id, out, statsd.DEFAULT_RATE)]) mock_client.gauge.reset_mock() assert mock_client.incr.call_count == 1 assert mock_client.incr.call_args == mock.call( state.entity_id, rate=statsd.DEFAULT_RATE) mock_client.incr.reset_mock() for invalid in ("foo", "", object): handler_method( MagicMock( data={"new_state": ha.State("domain.test", invalid, {})})) assert not mock_client.gauge.called assert mock_client.incr.called
async def test_sending_mqtt_commands(opp, mqtt_mock): """Test the sending MQTT commands.""" fake_state = ha.State("scene.test", scene.STATE) with patch( "openpeerpower.helpers.restore_state.RestoreEntity.async_get_last_state", return_value=fake_state, ): assert await async_setup_component( opp, scene.DOMAIN, { scene.DOMAIN: { "platform": "mqtt", "name": "test", "command_topic": "command-topic", "payload_on": "beer on", }, }, ) await opp.async_block_till_done() state = opp.states.get("scene.test") assert state.state == scene.STATE data = {ATTR_ENTITY_ID: "scene.test"} await opp.services.async_call(scene.DOMAIN, SERVICE_TURN_ON, data, blocking=True) mqtt_mock.async_publish.assert_called_once_with( "command-topic", "beer on", 0, False )
def test_get_states(opp_recorder): """Test getting states at a specific point in time.""" opp = opp_recorder() states = [] now = dt_util.utcnow() with patch("openpeerpower.components.recorder.dt_util.utcnow", return_value=now): for i in range(5): state = ha.State( f"test.point_in_time_{i % 5}", f"State {i}", {"attribute_test": i}, ) mock_state_change_event(opp, state) states.append(state) wait_recording_done(opp) future = now + timedelta(seconds=1) with patch("openpeerpower.components.recorder.dt_util.utcnow", return_value=future): for i in range(5): state = ha.State( f"test.point_in_time_{i % 5}", f"State {i}", {"attribute_test": i}, ) mock_state_change_event(opp, state) wait_recording_done(opp) # Get states returns everything before POINT for state1, state2 in zip( states, sorted(history.get_states(opp, future), key=lambda state: state.entity_id), ): assert state1 == state2 # Test get_state here because we have a DB setup assert states[0] == history.get_state(opp, future, states[0].entity_id) time_before_recorder_ran = now - timedelta(days=1000) assert history.get_states(opp, time_before_recorder_ran) == [] assert history.get_state(opp, time_before_recorder_ran, "demo.id") is None
def test_get_states(self): """Test getting states at a specific point in time.""" self.init_recorder() states = [] now = dt_util.utcnow() with patch("openpeerpower.components.recorder.dt_util.utcnow", return_value=now): for i in range(5): state = op.State( "test.point_in_time_{}".format(i % 5), "State {}".format(i), {"attribute_test": i}, ) mock_state_change_event(self.opp, state) states.append(state) self.wait_recording_done() future = now + timedelta(seconds=1) with patch("openpeerpower.components.recorder.dt_util.utcnow", return_value=future): for i in range(5): state = op.State( "test.point_in_time_{}".format(i % 5), "State {}".format(i), {"attribute_test": i}, ) mock_state_change_event(self.opp, state) self.wait_recording_done() # Get states returns everything before POINT for state1, state2 in zip( states, sorted(history.get_states(self.opp, future), key=lambda state: state.entity_id), ): assert state1 == state2 # Test get_state here because we have a DB setup assert states[0] == history.get_state(self.opp, future, states[0].entity_id)
def test_send_to_graphite_errors(self, mock_time): """Test the sending with errors.""" mock_time.return_value = 12345 state = ha.State("domain.entity", STATE_ON, {"foo": 1.0}) with mock.patch.object(self.gf, "_send_to_graphite") as mock_send: mock_send.side_effect = socket.error self.gf._report_attributes("entity", state) mock_send.side_effect = socket.gaierror self.gf._report_attributes("entity", state)
def values(): """Fixture for a list of test States.""" values = [] raw_values = [20, 19, 18, 21, 22, 0] timestamp = dt_util.utcnow() for val in raw_values: values.append(ha.State("sensor.test_monitored", val, last_updated=timestamp)) timestamp += timedelta(minutes=1) return values
async def json_serialize_states(opp): """Serialize million states with websocket default encoder.""" states = [ core.State("light.kitchen", "on", {"friendly_name": "Kitchen Lights"}) for _ in range(10 ** 6) ] start = timer() JSON_DUMP(states) return timer() - start
async def test_reproduce_with_no_entity(opp): """Test reproduce_state with no entity.""" calls = async_mock_service(opp, "light", SERVICE_TURN_ON) await state.async_reproduce_state(opp, ha.State("light.test", "on")) await opp.async_block_till_done() assert len(calls) == 0 assert opp.states.get("light.test") is None
def test_lowpass(values): """Test if lowpass filter works.""" filt = LowPassFilter(window_size=10, precision=2, entity=None, time_constant=10) out = ha.State("sensor.test_monitored", "unknown") for state in [out] + values + [out]: try: filtered = filt.filter_state(state) except ValueError: assert state.state == "unknown" assert filtered.state == 18.05
def test_unknown_state_outlier(values): """Test issue #32395.""" filt = OutlierFilter(window_size=3, precision=2, entity=None, radius=4.0) out = ha.State("sensor.test_monitored", "unknown") for state in [out] + values + [out]: try: filtered = filt.filter_state(state) except ValueError: assert state.state == "unknown" assert filtered.state == 21
async def test_reproduce_bad_state(opp): """Test reproduce_state with bad state.""" calls = async_mock_service(opp, "light", SERVICE_TURN_ON) opp.states.async_set("light.test", "off") await state.async_reproduce_state(opp, ha.State("light.test", "bad")) await opp.async_block_till_done() assert len(calls) == 0 assert opp.states.get("light.test").state == "off"
def test_from_event(self): """Test converting event to db state.""" state = op.State("sensor.temperature", "18") event = op.Event( EVENT_STATE_CHANGED, { "entity_id": "sensor.temperature", "old_state": None, "new_state": state }, context=state.context, ) assert state == States.from_event(event).to_native()
async def test_optimistic(opp, mqtt_mock): """Test optimistic mode.""" fake_state = op.State( "light.test", "on", { "brightness": 95, "hs_color": [100, 100], "effect": "random", "color_temp": 100, "white_value": 50, }, ) with patch( "openpeerpower.helpers.restore_state.RestoreEntity.async_get_last_state", return_value=mock_coro(fake_state), ): with assert_setup_component(1, light.DOMAIN): assert await async_setup_component( opp, light.DOMAIN, { light.DOMAIN: { "platform": "mqtt", "schema": "template", "name": "test", "command_topic": "test_light_rgb/set", "command_on_template": "on," "{{ brightness|d }}," "{{ color_temp|d }}," "{{ white_value|d }}," "{{ red|d }}-" "{{ green|d }}-" "{{ blue|d }}", "command_off_template": "off", "effect_list": ["colorloop", "random"], "qos": 2, } }, ) state = opp.states.get("light.test") assert state.state == STATE_ON assert state.attributes.get("brightness") == 95 assert state.attributes.get("hs_color") == (100, 100) assert state.attributes.get("effect") == "random" assert state.attributes.get("color_temp") == 100 assert state.attributes.get("white_value") == 50 assert state.attributes.get(ATTR_ASSUMED_STATE)
async def test_history_time(opp): """Test loading from history based on a time window.""" config = { "sensor": { "platform": "filter", "name": "test", "entity_id": "sensor.test_monitored", "filters": [{"filter": "time_throttle", "window_size": "00:01"}], }, } await async_init_recorder_component(opp) t_0 = dt_util.utcnow() - timedelta(minutes=1) t_1 = dt_util.utcnow() - timedelta(minutes=2) t_2 = dt_util.utcnow() - timedelta(minutes=3) fake_states = { "sensor.test_monitored": [ ha.State("sensor.test_monitored", 18.0, last_changed=t_0), ha.State("sensor.test_monitored", 19.0, last_changed=t_1), ha.State("sensor.test_monitored", 18.2, last_changed=t_2), ] } with patch( "openpeerpower.components.recorder.history.state_changes_during_period", return_value=fake_states, ), patch( "openpeerpower.components.recorder.history.get_last_state_changes", return_value=fake_states, ): with assert_setup_component(1, "sensor"): assert await async_setup_component(opp, "sensor", config) await opp.async_block_till_done() await opp.async_block_till_done() state = opp.states.get("sensor.test") assert state.state == "18.0"
async def test_reproduce_turn_off(opp): """Test reproduce_state with SERVICE_TURN_OFF.""" calls = async_mock_service(opp, "light", SERVICE_TURN_OFF) opp.states.async_set("light.test", "on") await state.async_reproduce_state(opp, ha.State("light.test", "off")) await opp.async_block_till_done() assert len(calls) > 0 last_call = calls[-1] assert last_call.domain == "light" assert last_call.service == SERVICE_TURN_OFF assert last_call.data.get("entity_id") == "light.test"
def test_from_event_to_db_state(): """Test converting event to db state.""" state = ha.State("sensor.temperature", "18") event = ha.Event( EVENT_STATE_CHANGED, { "entity_id": "sensor.temperature", "old_state": None, "new_state": state }, context=state.context, ) # We don't restore context unless we need it by joining the # events table on the event_id for state_changed events state.context = ha.Context(id=None) assert state == States.from_event(event).to_native()
def test_from_event_to_delete_state(self): """Test converting deleting state event to db state.""" event = op.Event( EVENT_STATE_CHANGED, { "entity_id": "sensor.temperature", "old_state": op.State("sensor.temperature", "18"), "new_state": None, }, ) db_state = States.from_event(event) assert db_state.entity_id == "sensor.temperature" assert db_state.domain == "sensor" assert db_state.state == "" assert db_state.last_changed == event.time_fired assert db_state.last_updated == event.time_fired
async def test_reproduce_complex_data(opp): """Test reproduce_state with complex service data.""" calls = async_mock_service(opp, "light", SERVICE_TURN_ON) opp.states.async_set("light.test", "off") complex_data = [255, 100, 100] await state.async_reproduce_state( opp, ha.State("light.test", "on", {"rgb_color": complex_data})) await opp.async_block_till_done() assert len(calls) > 0 last_call = calls[-1] assert last_call.domain == "light" assert last_call.service == SERVICE_TURN_ON assert last_call.data.get("rgb_color") == complex_data