예제 #1
0
def test_repr():
    """Test service representation."""
    service = Service(uuid1(), "TestService")
    service.characteristics = [get_chars()[0]]
    assert (
        service.__repr__() == "<service display_name=TestService chars={'Char 1': 0}>"
    )
예제 #2
0
 def get(self, name):
    serv_info = super(ServiceLoader, self).get(name)
    type_id = uuid.UUID(serv_info["type_id"])
    s = Service(type_id, name)
    chars = [self.char_loader.get(c) for c in serv_info["characteristics"]]
    s.add_characteristic(*chars)
    return s
예제 #3
0
def test_add_linked_service():
    """Test adding linked service to a service."""
    service = Service(uuid1(), "Test Service")
    assert len(service.linked_services) == 0

    linked_service = Service(uuid1(), "Test Linked Service")
    service.add_linked_service(linked_service)

    assert len(service.linked_services) == 1
    assert service.linked_services[0] == linked_service
예제 #4
0
def test_linked_service_to_HAP():
    """Test created HAP representation of a service."""
    uuid = uuid1()
    pyhap_char_to_HAP = "pyhap.characteristic.Characteristic.to_HAP"

    service = Service(uuid, "Test Service")
    linked_service = Service(uuid1(), "Test Linked Service")
    service.add_linked_service(linked_service)
    service.characteristics = get_chars()
    with patch(pyhap_char_to_HAP) as mock_char_HAP, patch.object(
        service, "broker"
    ) as mock_broker, patch.object(linked_service, "broker") as mock_linked_broker:
        mock_iid = mock_broker.iid_manager.get_iid
        mock_iid.return_value = 2
        mock_linked_iid = mock_linked_broker.iid_manager.get_iid
        mock_linked_iid.return_value = 3
        mock_char_HAP.side_effect = ("Char 1", "Char 2")
        hap_repr = service.to_HAP()
        mock_iid.assert_called_with(service)
        assert hap_repr == {
            "iid": 2,
            "type": str(uuid).upper(),
            "characteristics": ["Char 1", "Char 2"],
            "linked": [mock_linked_iid()],
        }
        # Verify we can readd it without dupes
        service.add_linked_service(linked_service)
        assert hap_repr == {
            "iid": 2,
            "type": str(uuid).upper(),
            "characteristics": ["Char 1", "Char 2"],
            "linked": [mock_linked_iid()],
        }
예제 #5
0
def test_is_primary_service():
    """Test setting is_primary_service on a service."""
    service = Service(uuid1(), "Test Service")

    assert service.is_primary_service is None

    service.is_primary_service = True
    assert service.is_primary_service is True

    service.is_primary_service = False
    assert service.is_primary_service is False
예제 #6
0
 def get_service(self, name):
     """Return new service object."""
     service_dict = self.serv_types[name].copy()
     if 'RequiredCharacteristics' not in service_dict or \
             'UUID' not in service_dict:
         raise KeyError('Could not load service {}!'.format(name))
     return Service.from_dict(name, service_dict, self)
예제 #7
0
def test_linked_service_to_HAP():
    """Test created HAP representation of a service."""
    uuid = uuid1()
    pyhap_char_to_HAP = 'pyhap.characteristic.Characteristic.to_HAP'

    service = Service(uuid, 'Test Service')
    linked_service = Service(uuid1(), 'Test Linked Service')
    service.add_linked_service(linked_service)
    service.characteristics = get_chars()
    with patch(pyhap_char_to_HAP) as mock_char_HAP, \
            patch.object(service, 'broker') as mock_broker, \
            patch.object(linked_service, 'broker') as mock_linked_broker:
        mock_iid = mock_broker.iid_manager.get_iid
        mock_iid.return_value = 2
        mock_linked_iid = mock_linked_broker.iid_manager.get_iid
        mock_linked_iid.return_value = 3
        mock_char_HAP.side_effect = ('Char 1', 'Char 2')
        hap_repr = service.to_HAP()
        mock_iid.assert_called_with(service)

    assert hap_repr == {
        'iid': 2,
        'type': str(uuid).upper(),
        'characteristics': ['Char 1', 'Char 2'],
        'linked': [mock_linked_iid()],
    }
예제 #8
0
    def add_service(self, service: Service):
        service.instance_id = self.object_count
        self.object_count += 1

        for characteristic in service.characteristics:
            characteristic.instance_id = self.object_count
            self.characteristics[characteristic.instance_id] = characteristic
            self.object_count += 1

        self.services.append(service)
예제 #9
0
def test_get_characteristic():
    """Test getting a characteristic from a service."""
    service = Service(uuid1(), "Test Service")
    chars = get_chars()
    service.characteristics = chars
    assert service.get_characteristic("Char 1") == chars[0]
    with pytest.raises(ValueError):
        service.get_characteristic("Not found")
예제 #10
0
def test_is_primary_service_to_HAP():
    """Test created HAP representation of primary service."""
    uuid = uuid1()
    pyhap_char_to_HAP = "pyhap.characteristic.Characteristic.to_HAP"

    service = Service(uuid, "Test Service")
    service.characteristics = get_chars()
    service.is_primary_service = True
    with patch(pyhap_char_to_HAP) as mock_char_HAP, patch.object(
        service, "broker"
    ) as mock_broker:
        mock_iid = mock_broker.iid_manager.get_iid
        mock_iid.return_value = 2
        mock_char_HAP.side_effect = ("Char 1", "Char 2")
        hap_repr = service.to_HAP()
        mock_iid.assert_called_with(service)

    assert hap_repr == {
        "iid": 2,
        "type": str(uuid).upper(),
        "characteristics": ["Char 1", "Char 2"],
        "primary": True,
    }
예제 #11
0
def test_add_characteristic():
    """Test adding characteristics to a service."""
    service = Service(uuid1(), "Test Service")
    chars = get_chars()
    service.add_characteristic(*chars)
    for char_service, char_original in zip(service.characteristics, chars):
        assert char_service == char_original

    service.add_characteristic(chars[0])
    assert len(service.characteristics) == 2
예제 #12
0
def test_from_dict():
    """Test creating a service from a dictionary."""
    uuid = uuid1()
    chars = get_chars()
    mock_char_loader = Mock()
    mock_char_loader.get_char.side_effect = chars

    json_dict = {
        'UUID': str(uuid),
        'RequiredCharacteristics': {
            'Char 1',
            'Char 2',
        }
    }

    service = Service.from_dict('Test Service', json_dict, mock_char_loader)
    assert service.display_name == 'Test Service'
    assert service.type_id == uuid
    assert service.characteristics == chars

    mock_char_loader.get_char.assert_has_calls(
        [call('Char 1'), call('Char 2')], any_order=True)
예제 #13
0
def test_from_dict():
    """Test creating a service from a dictionary."""
    uuid = uuid1()
    chars = get_chars()
    mock_char_loader = Mock()
    mock_char_loader.get_char.side_effect = chars

    json_dict = {
        "UUID": str(uuid),
        "RequiredCharacteristics": {
            "Char 1",
            "Char 2",
        },
    }

    service = Service.from_dict("Test Service", json_dict, mock_char_loader)
    assert service.display_name == "Test Service"
    assert service.type_id == uuid
    assert service.characteristics == chars

    mock_char_loader.get_char.assert_has_calls(
        [call("Char 1"), call("Char 2")], any_order=True
    )
예제 #14
0
def test_mixing_service_char_callbacks_partial_failure(driver):
    bridge = Bridge(driver, "mybridge")
    acc = Accessory(driver, "TestAcc", aid=2)
    acc2 = UnavailableAccessory(driver, "TestAcc2", aid=3)

    service = Service(uuid1(), "Lightbulb")
    char_on = Characteristic("On", uuid1(), CHAR_PROPS)
    char_brightness = Characteristic("Brightness", uuid1(), CHAR_PROPS)

    service.add_characteristic(char_on)
    service.add_characteristic(char_brightness)

    def fail_callback(*_):
        raise ValueError

    service.setter_callback = fail_callback

    acc.add_service(service)
    bridge.add_accessory(acc)

    service2 = Service(uuid1(), "Lightbulb")
    char_on2 = Characteristic("On", uuid1(), CHAR_PROPS)
    char_brightness2 = Characteristic("Brightness", uuid1(), CHAR_PROPS)

    service2.add_characteristic(char_on2)
    service2.add_characteristic(char_brightness2)

    char_on2.setter_callback = fail_callback

    acc2.add_service(service2)
    bridge.add_accessory(acc2)

    char_on_iid = char_on.to_HAP()[HAP_REPR_IID]
    char_brightness_iid = char_brightness.to_HAP()[HAP_REPR_IID]
    char_on2_iid = char_on2.to_HAP()[HAP_REPR_IID]
    char_brightness2_iid = char_brightness2.to_HAP()[HAP_REPR_IID]

    driver.add_accessory(bridge)

    response = driver.set_characteristics(
        {
            HAP_REPR_CHARS: [
                {
                    HAP_REPR_AID: acc.aid,
                    HAP_REPR_IID: char_on_iid,
                    HAP_REPR_VALUE: True,
                },
                {
                    HAP_REPR_AID: acc.aid,
                    HAP_REPR_IID: char_brightness_iid,
                    HAP_REPR_VALUE: 88,
                },
                {
                    HAP_REPR_AID: acc2.aid,
                    HAP_REPR_IID: char_on2_iid,
                    HAP_REPR_VALUE: True,
                },
                {
                    HAP_REPR_AID: acc2.aid,
                    HAP_REPR_IID: char_brightness2_iid,
                    HAP_REPR_VALUE: 12,
                },
            ]
        },
        "mock_addr",
    )

    assert response == {
        HAP_REPR_CHARS: [
            {
                HAP_REPR_AID: acc.aid,
                HAP_REPR_IID: char_on_iid,
                HAP_REPR_STATUS:
                HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE,
            },
            {
                HAP_REPR_AID: acc.aid,
                HAP_REPR_IID: char_brightness_iid,
                HAP_REPR_STATUS:
                HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE,
            },
            {
                HAP_REPR_AID: acc2.aid,
                HAP_REPR_IID: char_on2_iid,
                HAP_REPR_STATUS:
                HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE,
            },
            {
                HAP_REPR_AID: acc2.aid,
                HAP_REPR_IID: char_brightness2_iid,
                HAP_REPR_STATUS: 0,
            },
        ]
    }
예제 #15
0
def test_service_callbacks(driver):
    bridge = Bridge(driver, "mybridge")
    acc = Accessory(driver, "TestAcc", aid=2)
    acc2 = UnavailableAccessory(driver, "TestAcc2", aid=3)

    service = Service(uuid1(), "Lightbulb")
    char_on = Characteristic("On", uuid1(), CHAR_PROPS)
    char_brightness = Characteristic("Brightness", uuid1(), CHAR_PROPS)

    service.add_characteristic(char_on)
    service.add_characteristic(char_brightness)

    mock_callback = MagicMock()
    service.setter_callback = mock_callback

    acc.add_service(service)
    bridge.add_accessory(acc)

    service2 = Service(uuid1(), "Lightbulb")
    char_on2 = Characteristic("On", uuid1(), CHAR_PROPS)
    char_brightness2 = Characteristic("Brightness", uuid1(), CHAR_PROPS)

    service2.add_characteristic(char_on2)
    service2.add_characteristic(char_brightness2)

    mock_callback2 = MagicMock()
    service2.setter_callback = mock_callback2

    acc2.add_service(service2)
    bridge.add_accessory(acc2)

    char_on_iid = char_on.to_HAP()[HAP_REPR_IID]
    char_brightness_iid = char_brightness.to_HAP()[HAP_REPR_IID]
    char_on2_iid = char_on2.to_HAP()[HAP_REPR_IID]
    char_brightness2_iid = char_brightness2.to_HAP()[HAP_REPR_IID]

    driver.add_accessory(bridge)

    response = driver.set_characteristics(
        {
            HAP_REPR_CHARS: [
                {
                    HAP_REPR_AID: acc.aid,
                    HAP_REPR_IID: char_on_iid,
                    HAP_REPR_VALUE: True,
                },
                {
                    HAP_REPR_AID: acc.aid,
                    HAP_REPR_IID: char_brightness_iid,
                    HAP_REPR_VALUE: 88,
                },
                {
                    HAP_REPR_AID: acc2.aid,
                    HAP_REPR_IID: char_on2_iid,
                    HAP_REPR_VALUE: True,
                },
                {
                    HAP_REPR_AID: acc2.aid,
                    HAP_REPR_IID: char_brightness2_iid,
                    HAP_REPR_VALUE: 12,
                },
            ]
        },
        "mock_addr",
    )
    assert response is None

    mock_callback2.assert_called_with({"On": True, "Brightness": 12})
    mock_callback.assert_called_with({"On": True, "Brightness": 88})

    get_chars = driver.get_characteristics([
        "{}.{}".format(acc.aid, char_on_iid),
        "{}.{}".format(acc2.aid, char_on2_iid)
    ])
    assert get_chars == {
        "characteristics": [
            {
                "aid": acc.aid,
                "iid": char_on_iid,
                "status": 0,
                "value": True
            },
            {
                "aid": acc2.aid,
                "iid": char_on2_iid,
                "status": -70402
            },
        ]
    }

    def _fail_func():
        raise ValueError

    char_brightness.getter_callback = _fail_func
    get_chars = driver.get_characteristics([
        "{}.{}".format(acc.aid, char_on_iid),
        "{}.{}".format(acc2.aid, char_on2_iid),
        "{}.{}".format(acc2.aid, char_brightness_iid),
        "{}.{}".format(acc.aid, char_brightness2_iid),
    ])
    assert get_chars == {
        "characteristics": [
            {
                "aid": acc.aid,
                "iid": char_on_iid,
                "status": 0,
                "value": True
            },
            {
                "aid": acc2.aid,
                "iid": char_on2_iid,
                "status": -70402
            },
            {
                "aid": acc2.aid,
                "iid": char_brightness2_iid,
                "status": -70402
            },
            {
                "aid": acc.aid,
                "iid": char_brightness_iid,
                "status": -70402
            },
        ]
    }
예제 #16
0
def test_configure_char():
    """Test preconfiguring a characteristic from a service."""
    pyhap_char = "pyhap.characteristic.Characteristic"

    service = Service(uuid1(), "Test Service")
    chars = get_chars()
    service.characteristics = chars

    with pytest.raises(ValueError):
        service.configure_char("Char not found")
    assert service.configure_char("Char 1") == chars[0]

    with patch(pyhap_char + ".override_properties") as mock_override_prop, patch(
        pyhap_char + ".set_value"
    ) as mock_set_value:
        service.configure_char("Char 1")
        mock_override_prop.assert_not_called()
        mock_set_value.assert_not_called()
        assert service.get_characteristic("Char 1").setter_callback is None

    with patch(pyhap_char + ".override_properties") as mock_override_prop:
        new_properties = {"Format": "string"}
        new_valid_values = {0: "on", 1: "off"}
        service.configure_char("Char 1", properties=new_properties)
        mock_override_prop.assert_called_with(new_properties, None)
        service.configure_char("Char 1", valid_values=new_valid_values)
        mock_override_prop.assert_called_with(None, new_valid_values)
        service.configure_char(
            "Char 1", properties=new_properties, valid_values=new_valid_values
        )
        mock_override_prop.assert_called_with(new_properties, new_valid_values)

    with patch(pyhap_char + ".set_value") as mock_set_value:
        new_value = 1
        service.configure_char("Char 1", value=new_value)
        mock_set_value.assert_called_with(1, should_notify=False)

    new_setter_callback = "Test callback"
    service.configure_char("Char 1", setter_callback=new_setter_callback)
    assert service.get_characteristic("Char 1").setter_callback == new_setter_callback
예제 #17
0
 def test_abstract(self):
     with self.assertRaises(NotImplementedError):
         service = Service()
         service.service_uuid  # pylint: disable=pointless-statement
def test_service_callbacks(driver):
    bridge = Bridge(driver, "mybridge")
    acc = Accessory(driver, 'TestAcc', aid=2)
    acc2 = Accessory(driver, 'TestAcc2', aid=3)

    service = Service(uuid1(), 'Lightbulb')
    char_on = Characteristic('On', uuid1(), CHAR_PROPS)
    char_brightness = Characteristic('Brightness', uuid1(), CHAR_PROPS)

    service.add_characteristic(char_on)
    service.add_characteristic(char_brightness)

    mock_callback = MagicMock()
    service.setter_callback = mock_callback

    acc.add_service(service)
    bridge.add_accessory(acc)

    service2 = Service(uuid1(), 'Lightbulb')
    char_on2 = Characteristic('On', uuid1(), CHAR_PROPS)
    char_brightness2 = Characteristic('Brightness', uuid1(), CHAR_PROPS)

    service2.add_characteristic(char_on2)
    service2.add_characteristic(char_brightness2)

    mock_callback2 = MagicMock()
    service2.setter_callback = mock_callback2

    acc2.add_service(service2)
    bridge.add_accessory(acc2)

    char_on_iid = char_on.to_HAP()[HAP_REPR_IID]
    char_brightness_iid = char_brightness.to_HAP()[HAP_REPR_IID]
    char_on2_iid = char_on2.to_HAP()[HAP_REPR_IID]
    char_brightness2_iid = char_brightness2.to_HAP()[HAP_REPR_IID]

    driver.add_accessory(bridge)

    driver.set_characteristics(
        {
            HAP_REPR_CHARS: [{
                HAP_REPR_AID: acc.aid,
                HAP_REPR_IID: char_on_iid,
                HAP_REPR_VALUE: True
            }, {
                HAP_REPR_AID: acc.aid,
                HAP_REPR_IID: char_brightness_iid,
                HAP_REPR_VALUE: 88
            }, {
                HAP_REPR_AID: acc2.aid,
                HAP_REPR_IID: char_on2_iid,
                HAP_REPR_VALUE: True
            }, {
                HAP_REPR_AID: acc2.aid,
                HAP_REPR_IID: char_brightness2_iid,
                HAP_REPR_VALUE: 12
            }]
        }, "mock_addr")

    mock_callback2.assert_called_with({'On': True, 'Brightness': 12})
    mock_callback.assert_called_with({'On': True, 'Brightness': 88})
예제 #19
0
def test_configure_char():
    """Test preconfiguring a characteristic from a service."""
    pyhap_char = 'pyhap.characteristic.Characteristic'

    service = Service(uuid1(), 'Test Service')
    chars = get_chars()
    service.characteristics = chars

    with pytest.raises(ValueError):
        service.configure_char('Char not found')
    assert service.configure_char('Char 1') == chars[0]

    with patch(pyhap_char + '.override_properties') as mock_override_prop, \
            patch(pyhap_char + '.set_value') as mock_set_value:
        service.configure_char('Char 1')
        mock_override_prop.assert_not_called()
        mock_set_value.assert_not_called()
        assert service.get_characteristic('Char 1').setter_callback is None

    with patch(pyhap_char + '.override_properties') as mock_override_prop:
        new_properties = {'Format': 'string'}
        new_valid_values = {0: 'on', 1: 'off'}
        service.configure_char('Char 1', properties=new_properties)
        mock_override_prop.assert_called_with(new_properties, None)
        service.configure_char('Char 1', valid_values=new_valid_values)
        mock_override_prop.assert_called_with(None, new_valid_values)
        service.configure_char('Char 1',
                               properties=new_properties,
                               valid_values=new_valid_values)
        mock_override_prop.assert_called_with(new_properties, new_valid_values)

    with patch(pyhap_char + '.set_value') as mock_set_value:
        new_value = 1
        service.configure_char('Char 1', value=new_value)
        mock_set_value.assert_called_with(1, should_notify=False)

    new_setter_callback = 'Test callback'
    service.configure_char('Char 1', setter_callback=new_setter_callback)
    assert service.get_characteristic('Char 1').setter_callback == \
        new_setter_callback