def test_speed_to_homekit(): """Test speed conversion from HA to Homekit.""" speed_mapping = HomeKitSpeedMapping(['off', 'low', 'high']) assert speed_mapping.speed_to_homekit(None) is None assert speed_mapping.speed_to_homekit('off') == 0 assert speed_mapping.speed_to_homekit('low') == 50 assert speed_mapping.speed_to_homekit('high') == 100
def test_homekit_speed_mapping(): """Test if the SpeedRanges from a speed_list are as expected.""" # A standard 2-speed fan speed_mapping = HomeKitSpeedMapping(['off', 'low', 'high']) assert speed_mapping.speed_ranges == { 'off': SpeedRange(0, 0), 'low': SpeedRange(100 / 3, 50), 'high': SpeedRange(200 / 3, 100), } # A standard 3-speed fan speed_mapping = HomeKitSpeedMapping(['off', 'low', 'medium', 'high']) assert speed_mapping.speed_ranges == { 'off': SpeedRange(0, 0), 'low': SpeedRange(100 / 4, 100 / 3), 'medium': SpeedRange(200 / 4, 200 / 3), 'high': SpeedRange(300 / 4, 100), } # a Dyson-like fan with 10 speeds speed_mapping = HomeKitSpeedMapping([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) assert speed_mapping.speed_ranges == { 0: SpeedRange(0, 0), 1: SpeedRange(10, 100 / 9), 2: SpeedRange(20, 200 / 9), 3: SpeedRange(30, 300 / 9), 4: SpeedRange(40, 400 / 9), 5: SpeedRange(50, 500 / 9), 6: SpeedRange(60, 600 / 9), 7: SpeedRange(70, 700 / 9), 8: SpeedRange(80, 800 / 9), 9: SpeedRange(90, 100), }
def test_speed_to_homekit(): """Test speed conversion from HA to Homekit.""" speed_mapping = HomeKitSpeedMapping(["off", "low", "high"]) assert speed_mapping.speed_to_homekit(None) is None assert speed_mapping.speed_to_homekit("off") == 0 assert speed_mapping.speed_to_homekit("low") == 50 assert speed_mapping.speed_to_homekit("high") == 100
def test_speed_to_states(): """Test speed conversion from Homekit to HA.""" speed_mapping = HomeKitSpeedMapping(['off', 'low', 'high']) assert speed_mapping.speed_to_states(-1) == 'off' assert speed_mapping.speed_to_states(0) == 'off' assert speed_mapping.speed_to_states(33) == 'off' assert speed_mapping.speed_to_states(34) == 'low' assert speed_mapping.speed_to_states(50) == 'low' assert speed_mapping.speed_to_states(66) == 'low' assert speed_mapping.speed_to_states(67) == 'high' assert speed_mapping.speed_to_states(100) == 'high'
def test_speed_to_states(): """Test speed conversion from Homekit to HA.""" speed_mapping = HomeKitSpeedMapping(["off", "low", "high"]) assert speed_mapping.speed_to_states(-1) == "off" assert speed_mapping.speed_to_states(0) == "off" assert speed_mapping.speed_to_states(33) == "off" assert speed_mapping.speed_to_states(34) == "low" assert speed_mapping.speed_to_states(50) == "low" assert speed_mapping.speed_to_states(66) == "low" assert speed_mapping.speed_to_states(67) == "high" assert speed_mapping.speed_to_states(100) == "high"
def test_speed_to_states(): """Test speed conversion from Homekit to HA.""" speed_mapping = HomeKitSpeedMapping(['off', 'low', 'high']) assert speed_mapping.speed_to_states(0) == 'off' assert speed_mapping.speed_to_states(33) == 'off' assert speed_mapping.speed_to_states(34) == 'low' assert speed_mapping.speed_to_states(50) == 'low' assert speed_mapping.speed_to_states(66) == 'low' assert speed_mapping.speed_to_states(67) == 'high' assert speed_mapping.speed_to_states(100) == 'high'
async def test_fan_speed(hass, hk_driver, cls, events): """Test fan with speed.""" entity_id = "fan.demo" speed_list = [SPEED_OFF, SPEED_LOW, SPEED_HIGH] hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED, ATTR_SPEED: SPEED_OFF, ATTR_SPEED_LIST: speed_list, }, ) await hass.async_block_till_done() acc = cls.fan(hass, hk_driver, "Fan", entity_id, 2, None) # Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the # speed to 100 when turning on a fan on a freshly booted up server. assert acc.char_speed.value != 0 await hass.async_add_job(acc.run) assert (acc.speed_mapping.speed_ranges == HomeKitSpeedMapping( speed_list).speed_ranges) acc.speed_mapping.speed_to_homekit = Mock(return_value=42) acc.speed_mapping.speed_to_states = Mock(return_value="ludicrous") hass.states.async_set(entity_id, STATE_ON, {ATTR_SPEED: SPEED_HIGH}) await hass.async_block_till_done() acc.speed_mapping.speed_to_homekit.assert_called_with(SPEED_HIGH) assert acc.char_speed.value == 42 # Set from HomeKit call_set_speed = async_mock_service(hass, DOMAIN, "set_speed") await hass.async_add_job(acc.char_speed.client_update_value, 42) await hass.async_block_till_done() acc.speed_mapping.speed_to_states.assert_called_with(42) assert call_set_speed[0] assert call_set_speed[0].data[ATTR_ENTITY_ID] == entity_id assert call_set_speed[0].data[ATTR_SPEED] == "ludicrous" assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "ludicrous"
async def test_fan_speed(hass, hk_driver, cls, events): """Test fan with speed.""" entity_id = 'fan.demo' speed_list = [SPEED_OFF, SPEED_LOW, SPEED_HIGH] hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED, ATTR_SPEED: SPEED_OFF, ATTR_SPEED_LIST: speed_list }) await hass.async_block_till_done() acc = cls.fan(hass, hk_driver, 'Fan', entity_id, 2, None) assert acc.char_speed.value == 0 await hass.async_add_job(acc.run) assert acc.speed_mapping.speed_ranges == \ HomeKitSpeedMapping(speed_list).speed_ranges acc.speed_mapping.speed_to_homekit = Mock(return_value=42) acc.speed_mapping.speed_to_states = Mock(return_value='ludicrous') hass.states.async_set(entity_id, STATE_ON, {ATTR_SPEED: SPEED_HIGH}) await hass.async_block_till_done() acc.speed_mapping.speed_to_homekit.assert_called_with(SPEED_HIGH) assert acc.char_speed.value == 42 # Set from HomeKit call_set_speed = async_mock_service(hass, DOMAIN, 'set_speed') await hass.async_add_job(acc.char_speed.client_update_value, 42) await hass.async_block_till_done() acc.speed_mapping.speed_to_states.assert_called_with(42) assert call_set_speed[0] assert call_set_speed[0].data[ATTR_ENTITY_ID] == entity_id assert call_set_speed[0].data[ATTR_SPEED] == 'ludicrous' assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == 'ludicrous'
async def test_fan_set_all_one_shot(hass, hk_driver, cls, events): """Test fan with speed.""" entity_id = "fan.demo" speed_list = [SPEED_OFF, SPEED_LOW, SPEED_HIGH] hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED | SUPPORT_OSCILLATE | SUPPORT_DIRECTION, ATTR_SPEED: SPEED_OFF, ATTR_OSCILLATING: False, ATTR_DIRECTION: DIRECTION_FORWARD, ATTR_SPEED_LIST: speed_list, }, ) await hass.async_block_till_done() acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None) hk_driver.add_accessory(acc) # Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the # speed to 100 when turning on a fan on a freshly booted up server. assert acc.char_speed.value != 0 await acc.run_handler() await hass.async_block_till_done() assert ( acc.speed_mapping.speed_ranges == HomeKitSpeedMapping(speed_list).speed_ranges ) acc.speed_mapping.speed_to_homekit = Mock(return_value=42) acc.speed_mapping.speed_to_states = Mock(return_value="ludicrous") hass.states.async_set( entity_id, STATE_OFF, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED | SUPPORT_OSCILLATE | SUPPORT_DIRECTION, ATTR_SPEED: SPEED_OFF, ATTR_OSCILLATING: False, ATTR_DIRECTION: DIRECTION_FORWARD, ATTR_SPEED_LIST: speed_list, }, ) await hass.async_block_till_done() assert hass.states.get(entity_id).state == STATE_OFF # Set from HomeKit call_set_speed = async_mock_service(hass, DOMAIN, "set_speed") call_oscillate = async_mock_service(hass, DOMAIN, "oscillate") call_set_direction = async_mock_service(hass, DOMAIN, "set_direction") call_turn_on = async_mock_service(hass, DOMAIN, "turn_on") call_turn_off = async_mock_service(hass, DOMAIN, "turn_off") char_active_iid = acc.char_active.to_HAP()[HAP_REPR_IID] char_direction_iid = acc.char_direction.to_HAP()[HAP_REPR_IID] char_swing_iid = acc.char_swing.to_HAP()[HAP_REPR_IID] char_speed_iid = acc.char_speed.to_HAP()[HAP_REPR_IID] hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_active_iid, HAP_REPR_VALUE: 1, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_speed_iid, HAP_REPR_VALUE: 42, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_swing_iid, HAP_REPR_VALUE: 1, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_direction_iid, HAP_REPR_VALUE: 1, }, ] }, "mock_addr", ) await hass.async_block_till_done() acc.speed_mapping.speed_to_states.assert_called_with(42) assert not call_turn_on assert call_set_speed[0] assert call_set_speed[0].data[ATTR_ENTITY_ID] == entity_id assert call_set_speed[0].data[ATTR_SPEED] == "ludicrous" assert call_oscillate[0] assert call_oscillate[0].data[ATTR_ENTITY_ID] == entity_id assert call_oscillate[0].data[ATTR_OSCILLATING] is True assert call_set_direction[0] assert call_set_direction[0].data[ATTR_ENTITY_ID] == entity_id assert call_set_direction[0].data[ATTR_DIRECTION] == DIRECTION_REVERSE assert len(events) == 3 assert events[0].data[ATTR_VALUE] is True assert events[1].data[ATTR_VALUE] == DIRECTION_REVERSE assert events[2].data[ATTR_VALUE] == "ludicrous" hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED | SUPPORT_OSCILLATE | SUPPORT_DIRECTION, ATTR_SPEED: SPEED_OFF, ATTR_OSCILLATING: False, ATTR_DIRECTION: DIRECTION_FORWARD, ATTR_SPEED_LIST: speed_list, }, ) await hass.async_block_till_done() hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_active_iid, HAP_REPR_VALUE: 1, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_speed_iid, HAP_REPR_VALUE: 42, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_swing_iid, HAP_REPR_VALUE: 1, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_direction_iid, HAP_REPR_VALUE: 1, }, ] }, "mock_addr", ) # Turn on should not be called if its already on # and we set a fan speed await hass.async_block_till_done() acc.speed_mapping.speed_to_states.assert_called_with(42) assert len(events) == 6 assert call_set_speed[1] assert call_set_speed[1].data[ATTR_ENTITY_ID] == entity_id assert call_set_speed[1].data[ATTR_SPEED] == "ludicrous" assert call_oscillate[1] assert call_oscillate[1].data[ATTR_ENTITY_ID] == entity_id assert call_oscillate[1].data[ATTR_OSCILLATING] is True assert call_set_direction[1] assert call_set_direction[1].data[ATTR_ENTITY_ID] == entity_id assert call_set_direction[1].data[ATTR_DIRECTION] == DIRECTION_REVERSE assert events[-3].data[ATTR_VALUE] is True assert events[-2].data[ATTR_VALUE] == DIRECTION_REVERSE assert events[-1].data[ATTR_VALUE] == "ludicrous" hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_active_iid, HAP_REPR_VALUE: 0, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_speed_iid, HAP_REPR_VALUE: 42, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_swing_iid, HAP_REPR_VALUE: 1, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_direction_iid, HAP_REPR_VALUE: 1, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert len(events) == 7 assert call_turn_off assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id assert len(call_set_speed) == 2 assert len(call_oscillate) == 2 assert len(call_set_direction) == 2
def test_speed_to_homekit(): """Test speed conversion from HA to Homekit.""" speed_mapping = HomeKitSpeedMapping(['off', 'low', 'high']) assert speed_mapping.speed_to_homekit('off') == 0 assert speed_mapping.speed_to_homekit('low') == 50 assert speed_mapping.speed_to_homekit('high') == 100
async def test_fan_speed(hass, hk_driver, cls, events): """Test fan with speed.""" entity_id = "fan.demo" speed_list = [SPEED_OFF, SPEED_LOW, SPEED_HIGH] hass.states.async_set( entity_id, STATE_ON, { ATTR_SUPPORTED_FEATURES: SUPPORT_SET_SPEED, ATTR_SPEED: SPEED_OFF, ATTR_SPEED_LIST: speed_list, }, ) await hass.async_block_till_done() acc = cls.fan(hass, hk_driver, "Fan", entity_id, 1, None) hk_driver.add_accessory(acc) # Initial value can be anything but 0. If it is 0, it might cause HomeKit to set the # speed to 100 when turning on a fan on a freshly booted up server. assert acc.char_speed.value != 0 await acc.run_handler() await hass.async_block_till_done() assert (acc.speed_mapping.speed_ranges == HomeKitSpeedMapping( speed_list).speed_ranges) acc.speed_mapping.speed_to_homekit = Mock(return_value=42) acc.speed_mapping.speed_to_states = Mock(return_value="ludicrous") hass.states.async_set(entity_id, STATE_ON, {ATTR_SPEED: SPEED_HIGH}) await hass.async_block_till_done() acc.speed_mapping.speed_to_homekit.assert_called_with(SPEED_HIGH) assert acc.char_speed.value == 42 # Set from HomeKit call_set_speed = async_mock_service(hass, DOMAIN, "set_speed") char_speed_iid = acc.char_speed.to_HAP()[HAP_REPR_IID] char_active_iid = acc.char_active.to_HAP()[HAP_REPR_IID] hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_speed_iid, HAP_REPR_VALUE: 42, }, ] }, "mock_addr", ) await hass.async_add_executor_job(acc.char_speed.client_update_value, 42) await hass.async_block_till_done() acc.speed_mapping.speed_to_states.assert_called_with(42) assert acc.char_speed.value == 42 assert acc.char_active.value == 1 assert call_set_speed[0] assert call_set_speed[0].data[ATTR_ENTITY_ID] == entity_id assert call_set_speed[0].data[ATTR_SPEED] == "ludicrous" assert len(events) == 1 assert events[-1].data[ATTR_VALUE] == "ludicrous" # Verify speed is preserved from off to on hass.states.async_set(entity_id, STATE_OFF, {ATTR_SPEED: SPEED_OFF}) await hass.async_block_till_done() assert acc.char_speed.value == 42 assert acc.char_active.value == 0 hk_driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_active_iid, HAP_REPR_VALUE: 1, }, ] }, "mock_addr", ) await hass.async_block_till_done() assert acc.char_speed.value == 42 assert acc.char_active.value == 1