示例#1
0
    def add_entities(self):
        """Process the entity map and create HA entities."""
        # pylint: disable=import-error
        from homekit.model.services import ServicesTypes

        for accessory in self.accessories:
            aid = accessory['aid']
            for service in accessory['services']:
                iid = service['iid']
                if (aid, iid) in self.entities:
                    # Don't add the same entity again
                    continue

                devtype = ServicesTypes.get_short(service['type'])
                _LOGGER.debug("Found %s", devtype)
                service_info = {
                    'serial': self.hkid,
                    'aid': aid,
                    'iid': service['iid'],
                    'model': self.model,
                    'device-type': devtype
                }
                component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None)
                if component is not None:
                    discovery.load_platform(self.hass, component, DOMAIN,
                                            service_info, self.config)
                    self.entities.append((aid, iid))
示例#2
0
    def accessory_setup(self):
        """Handle setup of a HomeKit accessory."""
        # pylint: disable=import-error
        from homekit.model.services import ServicesTypes

        self.pairing.pairing_data['AccessoryIP'] = self.host
        self.pairing.pairing_data['AccessoryPort'] = self.port

        try:
            data = self.pairing.list_accessories_and_characteristics()
        except HomeKitConnectionError:
            call_later(self.hass, RETRY_INTERVAL,
                       lambda _: self.accessory_setup())
            return
        for accessory in data:
            serial = get_serial(accessory)
            if serial in self.hass.data[KNOWN_ACCESSORIES]:
                continue
            self.hass.data[KNOWN_ACCESSORIES][serial] = self
            aid = accessory['aid']
            for service in accessory['services']:
                devtype = ServicesTypes.get_short(service['type'])
                _LOGGER.debug("Found %s", devtype)
                service_info = {
                    'serial': serial,
                    'aid': aid,
                    'iid': service['iid'],
                    'model': self.model,
                    'device-type': devtype
                }
                component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None)
                if component is not None:
                    discovery.load_platform(self.hass, component, DOMAIN,
                                            service_info, self.config)
示例#3
0
    def accessory_setup(self):
        """Handle setup of a HomeKit accessory."""
        # pylint: disable=import-error
        from homekit.model.services import ServicesTypes
        from homekit.exceptions import AccessoryDisconnectedError

        self.pairing.pairing_data['AccessoryIP'] = self.host
        self.pairing.pairing_data['AccessoryPort'] = self.port

        try:
            data = self.pairing.list_accessories_and_characteristics()
        except AccessoryDisconnectedError:
            call_later(
                self.hass, RETRY_INTERVAL, lambda _: self.accessory_setup())
            return
        for accessory in data:
            aid = accessory['aid']
            for service in accessory['services']:
                iid = service['iid']
                if (aid, iid) in self.entities:
                    # Don't add the same entity again
                    continue

                devtype = ServicesTypes.get_short(service['type'])
                _LOGGER.debug("Found %s", devtype)
                service_info = {'serial': self.hkid,
                                'aid': aid,
                                'iid': service['iid'],
                                'model': self.model,
                                'device-type': devtype}
                component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None)
                if component is not None:
                    discovery.load_platform(self.hass, component, DOMAIN,
                                            service_info, self.config)
    def add_entities(self):
        """Process the entity map and create HA entities."""
        # pylint: disable=import-error
        from homekit.model.services import ServicesTypes

        for accessory in self.accessories:
            aid = accessory['aid']
            for service in accessory['services']:
                iid = service['iid']
                if (aid, iid) in self.entities:
                    # Don't add the same entity again
                    continue

                devtype = ServicesTypes.get_short(service['type'])
                _LOGGER.debug("Found %s", devtype)
                service_info = {'serial': self.hkid,
                                'aid': aid,
                                'iid': service['iid'],
                                'model': self.model,
                                'device-type': devtype}
                component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None)
                if component is not None:
                    discovery.load_platform(self.hass, component, DOMAIN,
                                            service_info, self.config)
                    self.entities.append((aid, iid))
示例#5
0
文件: common.py 项目: mmmahammm/core
async def setup_test_component(hass, services):
    """Load a fake homekit accessory based on a homekit accessory model."""
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, 'Cannot map test homekit services to homeassistant domain'

    config = {'discovery': {}}

    with mock.patch('homekit.Controller') as controller:
        fake_controller = controller.return_value = FakeController()
        await async_setup_component(hass, DOMAIN, config)

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.extend(services)
    pairing = fake_controller.add(accessory)

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            'md': 'TestDevice',
            'id': '00:00:00:00:00:00',
            'c#': 1,
        }
    }

    fire_service_discovered(hass, SERVICE_HOMEKIT, discovery_info)
    await hass.async_block_till_done()

    return Helper(hass, '.'.join((domain, 'testdevice')), pairing, accessory)
def get_accessory_information(accessory):
    """Obtain the accessory information service of a HomeKit device."""
    result = {}
    for service in accessory["services"]:
        stype = service["type"].upper()
        if ServicesTypes.get_short(stype) != "accessory-information":
            continue
        for characteristic in service["characteristics"]:
            ctype = CharacteristicsTypes.get_short(characteristic["type"])
            if "value" in characteristic:
                result[ctype] = characteristic["value"]
    return result
示例#7
0
    def __init__(self, hass, entity_id, pairing, accessory):
        """Create a helper for a given accessory/entity."""
        self.hass = hass
        self.entity_id = entity_id
        self.pairing = pairing
        self.accessory = accessory

        self.characteristics = {}
        for service in self.accessory.services:
            service_name = ServicesTypes.get_short(service.type)
            for char in service.characteristics:
                char_name = CharacteristicsTypes.get_short(char.type)
                self.characteristics[(service_name, char_name)] = char
示例#8
0
    def __init__(self, hass, entity_id, pairing, accessory):
        """Create a helper for a given accessory/entity."""
        self.hass = hass
        self.entity_id = entity_id
        self.pairing = pairing
        self.accessory = accessory

        self.characteristics = {}
        for service in self.accessory.services:
            service_name = ServicesTypes.get_short(service.type)
            for char in service.characteristics:
                char_name = CharacteristicsTypes.get_short(char.type)
                self.characteristics[(service_name, char_name)] = char
示例#9
0
def get_accessory_information(accessory):
    """Obtain the accessory information service of a HomeKit device."""
    # pylint: disable=import-error
    from homekit.model.services import ServicesTypes
    from homekit.model.characteristics import CharacteristicsTypes

    result = {}
    for service in accessory['services']:
        stype = service['type'].upper()
        if ServicesTypes.get_short(stype) != 'accessory-information':
            continue
        for characteristic in service['characteristics']:
            ctype = CharacteristicsTypes.get_short(characteristic['type'])
            if 'value' in characteristic:
                result[ctype] = characteristic['value']
    return result
示例#10
0
def get_accessory_information(accessory):
    """Obtain the accessory information service of a HomeKit device."""
    # pylint: disable=import-error
    from homekit.model.services import ServicesTypes
    from homekit.model.characteristics import CharacteristicsTypes

    result = {}
    for service in accessory['services']:
        stype = service['type'].upper()
        if ServicesTypes.get_short(stype) != 'accessory-information':
            continue
        for characteristic in service['characteristics']:
            ctype = CharacteristicsTypes.get_short(characteristic['type'])
            if 'value' in characteristic:
                result[ctype] = characteristic['value']
    return result
示例#11
0
def get_serial(accessory):
    """Obtain the serial number of a HomeKit device."""
    # pylint: disable=import-error
    from homekit.model.services import ServicesTypes
    from homekit.model.characteristics import CharacteristicsTypes

    for service in accessory['services']:
        if ServicesTypes.get_short(service['type']) != \
           'accessory-information':
            continue
        for characteristic in service['characteristics']:
            ctype = CharacteristicsTypes.get_short(characteristic['type'])
            if ctype != 'serial-number':
                continue
            return characteristic['value']
    return None
示例#12
0
    def _add_new_entities(self, callbacks):
        for accessory in self.accessories:
            aid = accessory["aid"]
            for service in accessory["services"]:
                iid = service["iid"]
                stype = ServicesTypes.get_short(service["type"].upper())
                service["stype"] = stype

                if (aid, iid) in self.entities:
                    # Don't add the same entity again
                    continue

                for listener in callbacks:
                    if listener(aid, service):
                        self.entities.append((aid, iid))
                        break
示例#13
0
def get_accessory_information(accessory):
    """Obtain the accessory information service of a HomeKit device."""
    # pylint: disable=import-error
    from homekit.model.services import ServicesTypes
    from homekit.model.characteristics import CharacteristicsTypes

    result = {}
    for service in accessory["services"]:
        stype = service["type"].upper()
        if ServicesTypes.get_short(stype) != "accessory-information":
            continue
        for characteristic in service["characteristics"]:
            ctype = CharacteristicsTypes.get_short(characteristic["type"])
            if "value" in characteristic:
                result[ctype] = characteristic["value"]
    return result
示例#14
0
    def async_load_platforms(self):
        """Load any platforms needed by this HomeKit device."""
        for accessory in self.accessories:
            for service in accessory["services"]:
                stype = ServicesTypes.get_short(service["type"].upper())
                if stype not in HOMEKIT_ACCESSORY_DISPATCH:
                    continue

                platform = HOMEKIT_ACCESSORY_DISPATCH[stype]
                if platform in self.platforms:
                    continue

                self.hass.async_create_task(
                    self.hass.config_entries.async_forward_entry_setup(
                        self.config_entry, platform))
                self.platforms.add(platform)
示例#15
0
def get_serial(accessory):
    """Obtain the serial number of a HomeKit device."""
    # pylint: disable=import-error
    from homekit.model.services import ServicesTypes
    from homekit.model.characteristics import CharacteristicsTypes

    for service in accessory['services']:
        if ServicesTypes.get_short(service['type']) != \
           'accessory-information':
            continue
        for characteristic in service['characteristics']:
            ctype = CharacteristicsTypes.get_short(
                characteristic['type'])
            if ctype != 'serial-number':
                continue
            return characteristic['value']
    return None
示例#16
0
    def _add_new_entities(self, callbacks):
        from homekit.model.services import ServicesTypes

        for accessory in self.accessories:
            aid = accessory['aid']
            for service in accessory['services']:
                iid = service['iid']
                stype = ServicesTypes.get_short(service['type'].upper())
                service['stype'] = stype

                if (aid, iid) in self.entities:
                    # Don't add the same entity again
                    continue

                for listener in callbacks:
                    if listener(aid, service):
                        self.entities.append((aid, iid))
                        break
示例#17
0
    async def async_load_platforms(self):
        """Load any platforms needed by this HomeKit device."""
        for accessory in self.accessories:
            for service in accessory["services"]:
                stype = ServicesTypes.get_short(service["type"].upper())
                if stype not in HOMEKIT_ACCESSORY_DISPATCH:
                    continue

                platform = HOMEKIT_ACCESSORY_DISPATCH[stype]
                if platform in self.platforms:
                    continue

                self.platforms.add(platform)
                try:
                    await self.opp.config_entries.async_forward_entry_setup(
                        self.config_entry, platform)
                except Exception:
                    self.platforms.remove(platform)
                    raise
示例#18
0
async def setup_test_component(hass, services, capitalize=False):
    """Load a fake homekit accessory based on a homekit accessory model.

    If capitalize is True, property names will be in upper case.
    """
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, 'Cannot map test homekit services to homeassistant domain'

    config = {
        'discovery': {
        }
    }

    with mock.patch('homekit.Controller') as controller:
        fake_controller = controller.return_value = FakeController()
        await async_setup_component(hass, DOMAIN, config)

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.extend(services)
    pairing = fake_controller.add(accessory)

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            ('MD' if capitalize else 'md'): 'TestDevice',
            ('ID' if capitalize else 'id'): '00:00:00:00:00:00',
            ('C#' if capitalize else 'c#'): 1,
        }
    }

    fire_service_discovered(hass, SERVICE_HOMEKIT, discovery_info)
    await hass.async_block_till_done()

    return Helper(hass, '.'.join((domain, 'testdevice')), pairing, accessory)
示例#19
0
async def setup_test_component(hass, services, capitalize=False, suffix=None):
    """Load a fake homekit accessory based on a homekit accessory model.

    If capitalize is True, property names will be in upper case.

    If suffix is set, entityId will include the suffix
    """
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, 'Cannot map test homekit services to homeassistant domain'

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.extend(services)

    pairing = await setup_test_accessories(hass, [accessory])
    entity = 'testdevice' if suffix is None else 'testdevice_{}'.format(suffix)
    return Helper(hass, '.'.join((domain, entity)), pairing, accessory)
示例#20
0
async def setup_test_component(hass, services, capitalize=False, suffix=None):
    """Load a fake homekit accessory based on a homekit accessory model.

    If capitalize is True, property names will be in upper case.

    If suffix is set, entityId will include the suffix
    """
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, "Cannot map test homekit services to Home Assistant domain"

    accessory = Accessory("TestDevice", "example.com", "Test", "0001", "0.1")
    accessory.services.extend(services)

    config_entry, pairing = await setup_test_accessories(hass, [accessory])
    entity = "testdevice" if suffix is None else "testdevice_{}".format(suffix)
    return Helper(hass, ".".join((domain, entity)), pairing, accessory,
                  config_entry)
示例#21
0
async def setup_test_component(hass, services, capitalize=False, suffix=None):
    """Load a fake homekit accessory based on a homekit accessory model.

    If capitalize is True, property names will be in upper case.

    If suffix is set, entityId will include the suffix
    """
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, 'Cannot map test homekit services to homeassistant domain'

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.extend(services)

    pairing = await setup_test_accessories(hass, [accessory], capitalize)

    entity = 'testdevice' if suffix is None else 'testdevice_{}'.format(suffix)
    return Helper(hass, '.'.join((domain, entity)), pairing, accessory)
示例#22
0
async def setup_test_component(hass, services, capitalize=False, suffix=None):
    """Load a fake homekit accessory based on a homekit accessory model.

    If capitalize is True, property names will be in upper case.

    If suffix is set, entityId will include the suffix
    """
    domain = None
    for service in services:
        service_name = ServicesTypes.get_short(service.type)
        if service_name in HOMEKIT_ACCESSORY_DISPATCH:
            domain = HOMEKIT_ACCESSORY_DISPATCH[service_name]
            break

    assert domain, 'Cannot map test homekit services to homeassistant domain'

    fake_controller = await setup_platform(hass)

    accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1')
    accessory.services.extend(services)
    pairing = fake_controller.add([accessory])

    discovery_info = {
        'host': '127.0.0.1',
        'port': 8080,
        'properties': {
            ('MD' if capitalize else 'md'): 'TestDevice',
            ('ID' if capitalize else 'id'): '00:00:00:00:00:00',
            ('C#' if capitalize else 'c#'): 1,
        }
    }

    fire_service_discovered(hass, SERVICE_HOMEKIT, discovery_info)
    await hass.async_block_till_done()

    entity = 'testdevice' if suffix is None else 'testdevice_{}'.format(suffix)
    return Helper(hass, '.'.join((domain, entity)), pairing, accessory)
示例#23
0
 def test_get_short_lowercase(self):
     self.assertEqual(
         ServicesTypes.get_short('00000086-0000-1000-8000-0026bb765291'),
         'occupancy')
示例#24
0
 def test_get_short_no_service(self):
     self.assertEqual(
         ServicesTypes.get_short('00000023-0000-1000-8000-0026BB765291'),
         'Unknown Service: 00000023-0000-1000-8000-0026BB765291')
示例#25
0
    data = json.load(sys.stdin)
    data = {"accessories": data}
else:
    parser.print_help()

assertions = []
success = True

for accessory in data["accessories"]:
    aid = accessory['aid']
    for service in accessory['services']:
        s_type = service['type']
        s_iid = service['iid']
        if args.print:
            print('{aid}.{iid}: >{stype}<'.format(
                aid=aid, iid=s_iid, stype=ServicesTypes.get_short(s_type)))

        for characteristic in service['characteristics']:
            c_iid = characteristic['iid']
            value = characteristic.get('value', '')

            assertion = {}

            c_type = characteristic['type']
            perms = ','.join(characteristic['perms'])
            desc = characteristic.get('description', '')
            c_type = CharacteristicsTypes.get_short(c_type)
            if 'maxLen' in characteristic:
                maxLen = characteristic.get('maxLen')

                if value is not None and len(value) <= maxLen:
示例#26
0
        sys.exit(-1)

    if args.decode:
        data = decode_values(data)

    # prepare output
    if args.output == 'json':
        print(json.dumps(data, indent=4, cls=tlv8.JsonEncoder))

    if args.output == 'compact':
        for accessory in data:
            aid = accessory['aid']
            for service in accessory['services']:
                s_type = service['type']
                s_iid = service['iid']
                print('{aid}.{iid}: >{stype}<'.format(aid=aid, iid=s_iid, stype=ServicesTypes.get_short(s_type)))

                for characteristic in service['characteristics']:
                    c_iid = characteristic['iid']
                    value = characteristic.get('value', '')
                    c_type = characteristic['type']
                    c_format = characteristic['format']
                    # we need to get the entry list from the decoder into a string and reformat it for better
                    # readability.
                    if args.decode and c_format in [CharacteristicFormats.tlv8] and isinstance(value, tlv8.EntryList):
                        value = tlv8.format_string(value)
                        value = '      '.join(value.splitlines(keepends=True))
                        value = '\n      ' + value
                    perms = ','.join(characteristic['perms'])
                    desc = characteristic.get('description', '')
                    c_type = CharacteristicsTypes.get_short(c_type)
示例#27
0
 def test_get_short_no_baseid(self):
     self.assertEqual(
         ServicesTypes.get_short('00000023-0000-1000-8000-NOTBASEID'),
         'Unknown Service: 00000023-0000-1000-8000-NOTBASEID')
示例#28
0
def create_proxy(accessories_and_characteristics):
    """
    Create a proxy in front of a set of accessories, services and characteristics. This allows to follow the
    communication of a controller and an accessory (e.g. an iPhone and some HomeKit IP camera).

    :param accessories_and_characteristics: the accessory data as described in the spec on page 73 and following. This
    contains all the data that will be used to create the proxy.
    :return: a list of `Accessory` instances whose services and characteristics are replaced by proxied versions. That
    means characteristic's callback functions for getting and setting values relay those calls to the proxied
    characteristics.
    """
    accessories = []
    logging.info('%<------ creating proxy ------')
    for accessory in accessories_and_characteristics:
        proxy_accessory = Accessory(
            '',
            '',
            '',
            '',
            '',
        )
        aid = accessory['aid']
        proxy_accessory.aid = aid
        logging.info('accessory with aid=%s', aid)
        proxy_accessory.services = []
        accessories.append(proxy_accessory)

        for service in accessory['services']:
            service_iid = service['iid']
            service_type = service['type']
            short_type = ServicesTypes.get_short(service_type)
            logging.info('  %i.%i: >%s< (%s)', aid, service_iid, short_type,
                         service_type)

            proxy_service = ProxyService(service_iid, service_type)
            proxy_accessory.add_service(proxy_service)

            for characteristic in service['characteristics']:
                characteristic_iid = characteristic['iid']
                characteristic_type = characteristic['type']
                short_type = CharacteristicsTypes.get_short(
                    characteristic_type)
                characteristic_format = characteristic['format']
                characteristic_value = characteristic.get('value')
                characteristic_perms = characteristic['perms']
                logging.info('    %i.%i: %s >%s< (%s) [%s] %s', aid,
                             characteristic_iid, characteristic_value,
                             short_type, characteristic_type,
                             ','.join(characteristic_perms),
                             characteristic_format)

                proxy_characteristic = ProxyCharacteristic(
                    characteristic_iid, characteristic_type,
                    characteristic_format)
                proxy_service.append_characteristic(proxy_characteristic)
                if characteristic_value:
                    proxy_characteristic.value = characteristic_value
                proxy_characteristic.perms = characteristic_perms

                proxy_characteristic.set_set_value_callback(
                    generate_set_value_callback(accessory['aid'],
                                                proxy_characteristic))
                proxy_characteristic.set_get_value_callback(
                    generate_get_value_callback(accessory['aid'],
                                                proxy_characteristic))
    logging.info('%<------ finished creating proxy ------')
    return accessories