def test_switch_set_state(self): """Test if accessory and HA are updated accordingly.""" entity_id = 'switch.test' domain = split_entity_id(entity_id)[0] acc = Switch(self.hass, entity_id, 'Switch', aid=2) acc.run() self.assertEqual(acc.aid, 2) self.assertEqual(acc.category, 8) # Switch self.assertEqual(acc.char_on.value, False) self.hass.states.set(entity_id, STATE_ON) self.hass.block_till_done() self.assertEqual(acc.char_on.value, True) self.hass.states.set(entity_id, STATE_OFF) self.hass.block_till_done() self.assertEqual(acc.char_on.value, False) # Set from HomeKit acc.char_on.set_value(True) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], domain) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) acc.char_on.set_value(False) self.hass.block_till_done() self.assertEqual(self.events[1].data[ATTR_DOMAIN], domain) self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
def test_switch_set_state(self): """Test if accessory and HA are updated accordingly.""" entity_id = 'switch.test' domain = split_entity_id(entity_id)[0] acc = Switch(self.hass, entity_id, 'Switch', aid=2) acc.run() self.assertEqual(acc.aid, 2) self.assertEqual(acc.category, 8) # Switch self.assertEqual(acc.char_on.value, False) self.hass.states.set(entity_id, STATE_ON) self.hass.block_till_done() self.assertEqual(acc.char_on.value, True) self.hass.states.set(entity_id, STATE_OFF) self.hass.block_till_done() self.assertEqual(acc.char_on.value, False) # Set from HomeKit acc.char_on.set_value(True) self.hass.block_till_done() self.assertEqual( self.events[0].data[ATTR_DOMAIN], domain) self.assertEqual( self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) acc.char_on.set_value(False) self.hass.block_till_done() self.assertEqual( self.events[1].data[ATTR_DOMAIN], domain) self.assertEqual( self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
def test_input_boolean_set_state(self): """Test service call for remote as domain.""" entity_id = 'input_boolean.test' domain = split_entity_id(entity_id)[0] acc = Switch(self.hass, entity_id, 'Switch', aid=2) acc.run() self.assertEqual(acc.char_on.value, False) # Set from HomeKit acc.char_on.set_value(True) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], domain) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(acc.char_on.value, True)
async def test_switch_set_state(hass, entity_id): """Test if accessory and HA are updated accordingly.""" domain = split_entity_id(entity_id)[0] hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Switch(hass, 'Switch', entity_id, 2, None) await hass.async_add_job(acc.run) assert acc.aid == 2 assert acc.category == 8 # Switch assert acc.char_on.value is False hass.states.async_set(entity_id, STATE_ON) await hass.async_block_till_done() assert acc.char_on.value is True hass.states.async_set(entity_id, STATE_OFF) await hass.async_block_till_done() assert acc.char_on.value is False # Set from HomeKit call_turn_on = async_mock_service(hass, domain, 'turn_on') call_turn_off = async_mock_service(hass, domain, 'turn_off') await hass.async_add_job(acc.char_on.client_update_value, True) await hass.async_block_till_done() assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id await hass.async_add_job(acc.char_on.client_update_value, False) await hass.async_block_till_done() assert call_turn_off assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
async def test_reset_switch(hass, hk_driver, entity_id, attrs, events): """Test if switch accessory is reset correctly.""" domain = split_entity_id(entity_id)[0] hass.states.async_set(entity_id, None, attrs) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await acc.run_handler() await hass.async_block_till_done() assert acc.activate_only is True assert acc.char_on.value is False call_turn_on = async_mock_service(hass, domain, "turn_on") call_turn_off = async_mock_service(hass, domain, "turn_off") await hass.async_add_executor_job(acc.char_on.client_update_value, True) await hass.async_block_till_done() assert acc.char_on.value is True assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 1 assert events[-1].data[ATTR_VALUE] is None future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1 assert not call_turn_off await hass.async_add_executor_job(acc.char_on.client_update_value, False) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1
def test_remote_set_state(self): """Test service call for remote as domain.""" entity_id = 'remote.test' domain = split_entity_id(entity_id)[0] acc = Switch(self.hass, 'Switch', entity_id, 2, config=None) acc.run() self.assertEqual(acc.char_on.value, False) # Set from HomeKit acc.char_on.client_update_value(True) self.hass.block_till_done() self.assertEqual(self.events[0].data[ATTR_DOMAIN], domain) self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(acc.char_on.value, True)
def test_input_boolean_set_state(self): """Test service call for remote as domain.""" entity_id = 'input_boolean.test' domain = split_entity_id(entity_id)[0] acc = Switch(self.hass, entity_id, 'Switch', aid=2) acc.run() self.assertEqual(acc.char_on.value, False) # Set from HomeKit acc.char_on.set_value(True) self.hass.block_till_done() self.assertEqual( self.events[0].data[ATTR_DOMAIN], domain) self.assertEqual( self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON) self.assertEqual(acc.char_on.value, True)
async def test_camera_stream_source_configured_with_failing_ffmpeg( hass, run_driver, events): """Test a camera that can stream with a configured source with ffmpeg failing.""" await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) await async_setup_component(hass, camera.DOMAIN, {camera.DOMAIN: { "platform": "demo" }}) await hass.async_block_till_done() entity_id = "camera.demo_camera" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Camera( hass, run_driver, "Camera", entity_id, 2, { CONF_STREAM_SOURCE: "/dev/null", CONF_SUPPORT_AUDIO: True }, ) not_camera_acc = Switch( hass, run_driver, "Switch", entity_id, 4, {}, ) bridge = HomeBridge("hass", run_driver, "Test Bridge") bridge.add_accessory(acc) bridge.add_accessory(not_camera_acc) await acc.run() assert acc.aid == 2 assert acc.category == 17 # Camera await _async_setup_endpoints(hass, acc) with patch( "homeassistant.components.demo.camera.DemoCamera.stream_source", return_value="rtsp://example.local", ), patch( "homeassistant.components.homekit.type_cameras.HAFFmpeg", return_value=_get_failing_mock_ffmpeg(), ): await _async_start_streaming(hass, acc) await _async_stop_all_streams(hass, acc) # Calling a second time should not throw await _async_stop_all_streams(hass, acc)
async def test_reset_switch_reload(hass, hk_driver, events): """Test reset switch after script reload.""" entity_id = "script.test" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await acc.run_handler() await hass.async_block_till_done() assert acc.activate_only is False hass.states.async_set(entity_id, None) await hass.async_block_till_done() assert acc.char_on.value is False
async def test_reset_switch_reload(hass, hk_driver, events): """Test reset switch after script reload.""" entity_id = "script.test" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await hass.async_add_job(acc.run) await hass.async_block_till_done() assert acc.activate_only is True hass.states.async_set(entity_id, None, {ATTR_CAN_CANCEL: True}) await hass.async_block_till_done() assert acc.activate_only is False hass.states.async_set(entity_id, None, {ATTR_CAN_CANCEL: False}) await hass.async_block_till_done() assert acc.activate_only is True
async def test_script_switch(hass, hk_driver, events): """Test if script switch accessory is reset correctly.""" domain = "script" entity_id = "script.test" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await acc.run() await hass.async_block_till_done() assert acc.activate_only is True assert acc.char_on.value is False call_turn_on = async_mock_service(hass, domain, "test") call_turn_off = async_mock_service(hass, domain, "turn_off") acc.char_on.client_update_value(True) await hass.async_block_till_done() assert acc.char_on.value is True assert call_turn_on assert call_turn_on[0].data == {} assert len(events) == 1 assert events[-1].data[ATTR_VALUE] is None future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is True future = dt_util.utcnow() + timedelta(seconds=10) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1 assert not call_turn_off acc.char_on.client_update_value(False) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1
async def test_switch_set_state(hass, hk_driver, entity_id, attrs, events): """Test if accessory and HA are updated accordingly.""" domain = split_entity_id(entity_id)[0] hass.states.async_set(entity_id, None, attrs) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await acc.run() await hass.async_block_till_done() assert acc.aid == 2 assert acc.category == 8 # Switch assert acc.activate_only is False assert acc.char_on.value is False hass.states.async_set(entity_id, STATE_ON, attrs) await hass.async_block_till_done() assert acc.char_on.value is True hass.states.async_set(entity_id, STATE_OFF, attrs) await hass.async_block_till_done() assert acc.char_on.value is False # Set from HomeKit call_turn_on = async_mock_service(hass, domain, "turn_on") call_turn_off = async_mock_service(hass, domain, "turn_off") await hass.async_add_executor_job(acc.char_on.client_update_value, True) await hass.async_block_till_done() assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 1 assert events[-1].data[ATTR_VALUE] is None await hass.async_add_executor_job(acc.char_on.client_update_value, False) await hass.async_block_till_done() assert call_turn_off assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 2 assert events[-1].data[ATTR_VALUE] is None
async def test_button_switch(hass, hk_driver, events): """Test switch accessory from a button entity.""" domain = "button" entity_id = "button.test" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Switch(hass, hk_driver, "Switch", entity_id, 2, None) await acc.run() await hass.async_block_till_done() assert acc.activate_only is True assert acc.char_on.value is False call_press = async_mock_service(hass, domain, "press") acc.char_on.client_update_value(True) await hass.async_block_till_done() assert acc.char_on.value is True assert len(call_press) == 1 assert call_press[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 1 assert events[-1].data[ATTR_VALUE] is None future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is True future = dt_util.utcnow() + timedelta(seconds=10) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1 assert len(call_press) == 1 acc.char_on.client_update_value(False) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1
async def test_camera_stream_source_configured(hass, run_driver, events): """Test a camera that can stream with a configured source.""" await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) await async_setup_component(hass, camera.DOMAIN, {camera.DOMAIN: { "platform": "demo" }}) await hass.async_block_till_done() entity_id = "camera.demo_camera" hass.states.async_set(entity_id, None) await hass.async_block_till_done() acc = Camera( hass, run_driver, "Camera", entity_id, 2, { CONF_STREAM_SOURCE: "/dev/null", CONF_SUPPORT_AUDIO: True }, ) not_camera_acc = Switch( hass, run_driver, "Switch", entity_id, 4, {}, ) bridge = HomeBridge("hass", run_driver, "Test Bridge") bridge.add_accessory(acc) bridge.add_accessory(not_camera_acc) await acc.run() assert acc.aid == 2 assert acc.category == 17 # Camera await _async_setup_endpoints(hass, acc) working_ffmpeg = _get_working_mock_ffmpeg() session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID] with patch( "homeassistant.components.demo.camera.DemoCamera.stream_source", return_value=None, ), patch( "homeassistant.components.homekit.type_cameras.HAFFmpeg", return_value=working_ffmpeg, ): await _async_start_streaming(hass, acc) await _async_stop_all_streams(hass, acc) expected_output = ( "-map 0:v:0 -an -c:v libx264 -profile:v high -tune zerolatency -pix_fmt " "yuv420p -r 30 -b:v 299k -bufsize 1196k -maxrate 299k -payload_type 99 -ssrc {v_ssrc} -f " "rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params " "zdPmNLWeI86DtLJHvVLI6YPvqhVeeiLsNtrAgbgL " "srtp://192.168.208.5:51246?rtcpport=51246&localrtcpport=51246&pkt_size=1316 -map 0:a:0 " "-vn -c:a libopus -application lowdelay -ac 1 -ar 24k -b:a 24k -bufsize 96k -payload_type " "110 -ssrc {a_ssrc} -f rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params " "shnETgfD+7xUQ8zRdsaytY11wu6CO73IJ+RZVJpU " "srtp://192.168.208.5:51108?rtcpport=51108&localrtcpport=51108&pkt_size=188" ) working_ffmpeg.open.assert_called_with( cmd=[], input_source="-i /dev/null", output=expected_output.format(**session_info), stdout_pipe=False, extra_cmd="-hide_banner -nostats", stderr_pipe=True, ) await _async_setup_endpoints(hass, acc) working_ffmpeg = _get_working_mock_ffmpeg() session_info = acc.sessions[MOCK_START_STREAM_SESSION_UUID] with patch( "homeassistant.components.demo.camera.DemoCamera.stream_source", return_value="rtsp://example.local", ), patch( "homeassistant.components.homekit.type_cameras.HAFFmpeg", return_value=working_ffmpeg, ): await _async_start_streaming(hass, acc) await _async_stop_all_streams(hass, acc) # Calling a second time should not throw await _async_stop_all_streams(hass, acc) turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12, second_width=300, second_height=200) with patch("turbojpeg.TurboJPEG", return_value=turbo_jpeg): TurboJPEGSingleton() assert await acc.async_get_snapshot({ "aid": 2, "image-width": 300, "image-height": 200 }) # Verify the bridge only forwards async_get_snapshot for # cameras and valid accessory ids assert await bridge.async_get_snapshot({ "aid": 2, "image-width": 300, "image-height": 200 }) with pytest.raises(ValueError): assert await bridge.async_get_snapshot({ "aid": 3, "image-width": 300, "image-height": 200 }) with pytest.raises(ValueError): assert await bridge.async_get_snapshot({ "aid": 4, "image-width": 300, "image-height": 200 })