Esempio n. 1
0
def test_xhm_uri(mock_driver):
    acc_1 = Accessory(mock_driver, "Test Accessory 1", aid=2)
    acc_1.category = CATEGORY_CAMERA
    mock_driver.state = State(address="1.2.3.4",
                              mac="AA::BB::CC::DD::EE",
                              pincode=b"653-32-1211",
                              port=44)
    mock_driver.state.setup_id = "AAAA"
    assert acc_1.xhm_uri() == "X-HM://00H708WSBAAAA"

    acc_1.category = CATEGORY_TELEVISION
    mock_driver.state = State(address="1.2.3.4",
                              mac="AA::BB::CC::DD::EE",
                              pincode=b"323-23-1212",
                              port=44)
    mock_driver.state.setup_id = "BBBB"
    assert acc_1.xhm_uri() == "X-HM://00UQBOTF0BBBB"

    acc_1.category = CATEGORY_TARGET_CONTROLLER
    mock_driver.state = State(address="1.2.3.4",
                              mac="AA::BB::CC::DD::EE",
                              pincode=b"323-23-1212",
                              port=44)
    mock_driver.state.setup_id = "BBBB"
    assert acc_1.xhm_uri() == "X-HM://00VPU8UEKBBBB"
Esempio n. 2
0
    def load_accessories(self, override_ids=False):
        """
        Return a list of initialized accessories specified by the config files.

        The characteristics of those accessories should contain three additional
        values: topic_in, topic_out and adapter used by the MqttBridge class.

        :param override_ids: override accessory ids for a new bridge config
        :type override_ids: bool
        """
        # find all cfg files, but skip the bridge.cfg
        fnames = []
        for r, _, fs in os.walk(self.cfg_path):
            fnames += [
                os.path.join(r, f) for f in fs
                if f != 'bridge.cfg' and f != 'accessory.state'
            ]

        for fname in fnames:
            cfg = configparser.ConfigParser()
            cfg.optionxform = str
            cfg.fname = fname

            try:
                cfg.read(fname)
                self.cfgs.append(cfg)
            except Exception as e:
                logger.warn('Skipping "{}" because of Exception: {}'.format(
                    fname, str(e)))

        # sort by aid
        max_aid = 2**63 - 1
        self.cfgs = sorted(
            self.cfgs,
            key=lambda cfg: int(cfg['Accessory'].get('AID', max_aid)))

        self.accs = []
        for cfg in self.cfgs:
            try:
                # init accessory
                acc_def = cfg['Accessory']
                if acc_def['Category'] not in categories:
                    logger.warn('Unknown category: "{}"'.format(
                        acc_def['category']))
                    continue
                if 'DisplayName' not in acc_def.keys():
                    # use filename as display name
                    acc_def['DisplayName'] = os.path.basename(fname).split(
                        '.')[0]

                aid = None
                if not override_ids:
                    aid = acc_def.get('AID', None)
                if aid is not None:
                    aid = int(aid)

                acc = Accessory(self.driver, acc_def['DisplayName'], aid=aid)
                acc.category = categories[acc_def.get('Category', 'Other')]

                acc.set_info_service(acc_def.get('FirmwareRevision', None),
                                     acc_def.get('Manufacturer', None),
                                     acc_def.get('Model', None),
                                     acc_def.get('SerialNumber', None))

                # init services
                serv_types = cfg.sections()
                serv_types.remove('Accessory')
                for serv_type in serv_types:
                    serv_def = cfg[serv_type]
                    serv = loader.get_loader().get_service(serv_type)
                    char_types = serv_def.keys()

                    for char_type in char_types:
                        char_def = serv_def[char_type]
                        char_def = char_def.split()

                        # init characteristic
                        try:
                            char = loader.get_loader().get_char(char_type)

                            if len(char_def) != 3:
                                logger.warn(
                                    'Skipping caracteristic "{}" because of invalid format'
                                    .format(char_type))
                                continue

                            # add topics and adapter
                            char.properties['topic_in'] = None
                            char.properties['topic_out'] = None
                            char.properties['adapter'] = None

                            if char_def[0] != '_':
                                char.properties['topic_in'] = char_def[0]
                            if char_def[1] != '_':
                                char.properties['topic_out'] = char_def[1]
                            if char_def[2] != '_':
                                char.properties['adapter'] = char_def[2]

                            # add characteristic
                            added = False
                            for i, old_char in enumerate(serv.characteristics):
                                if old_char.type_id == char.type_id:
                                    serv.characteristics[i] = char
                                    added = True
                                    break

                            if not added:
                                serv.add_characteristic(char)

                        except KeyError as e:
                            continue

                    acc.add_service(serv)

                self.accs.append(acc)
                logger.info('Added accessory "{}"'.format(acc.display_name))

            except Exception as e:
                logger.warn(
                    'Skipping "{}" because of Exception: {}: {}'.format(
                        type(e), cfg.fname, str(e)))

        return self.accs