Пример #1
0
    def _gadget_needs_update(local_gadget: Gadget, fetched_gadget: Gadget):
        """
        Checks if the gadget on the remote storage needs an update by comparing the gadgets characteristics boundaries

        :param local_gadget: The local gadget (master)
        :param fetched_gadget: The fetched gadget to compare it with
        :return: Whether the fetched gadget needs to be updated
        """
        needs_update = local_gadget.get_characteristics(
        ) != fetched_gadget.get_characteristics()
        return needs_update
Пример #2
0
    def merge_gadgets(self, old_gadget: Gadget, new_gadget: Gadget) -> Gadget:
        """
        Merges two gadgets (typically one 'original' and a new one with update information) into a new gadget
        containing with name, client and class of the old and characteristics of the new one.

        :param old_gadget: Original gadget to base merged gadget on
        :param new_gadget: Gadget wth update information
        :return: The emrged gadget
        :raise GadgetMergeError: If anything goes wrong during merges
        """
        encoder = ApiEncoder()
        if not isinstance(
                new_gadget,
                AnyGadget) and old_gadget.__class__ != new_gadget.__class__:
            raise GadgetMergeError(
                f"Cannot merge gadgets with different classes {old_gadget.__class__.__name__} "
                f"and {new_gadget.__class__.__name__}")
        try:
            gadget_type = encoder.encode_gadget_identifier(old_gadget)
        except IdentifierEncodeError as err:
            raise GadgetMergeError(err.args[0])
        try:
            merged_gadget = self.create_gadget(
                gadget_type, old_gadget.get_name(),
                old_gadget.get_host_client(), new_gadget.get_characteristics())
        except GadgetCreationError as err:
            raise GadgetMergeError(err.args[0])
        return merged_gadget
Пример #3
0
    def encode_gadget(self, gadget: Gadget) -> dict:
        """
        Serializes a gadget according to api specification

        :param gadget: The gadget to serialize
        :return: The serialized version of the gadget as dict
        :raises GadgetEncodeError: If anything goes wrong during the serialization process
        """
        try:
            identifier = self.encode_gadget_identifier(gadget)
        except IdentifierEncodeError as err:
            self._logger.error(err.args[0])
            raise GadgetEncodeError(gadget.__class__.__name__, gadget.get_name())

        characteristics_json = [self.encode_characteristic(x) for x in gadget.get_characteristics()]

        mapping_json = {}
        for mapping in gadget.get_event_mapping():
            if mapping.get_id() in mapping_json:
                self._logger.error(f"found double mapping for {mapping.get_id()}")
                continue
            mapping_json[mapping.get_id()] = mapping.get_list()

        gadget_json = {"type": int(identifier),
                       "id": gadget.get_name(),
                       "characteristics": characteristics_json,
                       "event_map": mapping_json}

        return gadget_json
Пример #4
0
    def receive_gadget(self, gadget: Gadget):
        if self._last_published_gadget is not None and self._last_published_gadget == gadget.get_name(
        ):
            return
        fetched_gadget = self._fetch_gadget_data(gadget.get_name())
        if fetched_gadget is None:
            # Gadget with given name does not exist on the remote system, or is broken somehow
            try:
                self.create_gadget(gadget)
            except GadgetCreationError as err:
                self._logger.error(err.args[0])
                raise GadgetUpdateError(gadget.get_name())
        else:
            if self._gadget_needs_update(gadget, fetched_gadget):
                # Gadget needs to be recreated due to characteristic boundaries changes
                try:
                    self.remove_gadget(gadget.get_name())
                except GadgetDeletionError as err:
                    self._logger.error(err.args[0])

                try:
                    self.create_gadget(gadget)
                except GadgetCreationError as err:
                    self._logger.error(err.args[0])
                    raise GadgetUpdateError(gadget.get_name())

            else:
                # Gadget does not need to be re-created, only updated
                for characteristic in gadget.get_characteristics():
                    fetched_characteristic = fetched_gadget.get_characteristic(
                        characteristic.get_type())
                    if fetched_characteristic.get_true_value(
                    ) != characteristic.get_true_value():
                        self._update_characteristic(gadget,
                                                    characteristic.get_type())
Пример #5
0
 def create_gadget(self, gadget: Gadget):
     self._logger.info(
         f"Creating gadget '{gadget.get_name()}' on external source")
     adding_successful = self._network_connector.add_gadget(gadget)
     if not adding_successful:
         raise GadgetCreationError(gadget.get_name())
     for characteristic in gadget.get_characteristics():
         self._update_characteristic(gadget, characteristic.get_type())
Пример #6
0
    def encode_gadget_update(self, gadget: Gadget) -> dict:
        """
        Serializes gadget update information according to api specification

        :param gadget: The gadget to serialize
        :return: The serialized version of the changeable gadget information as dict
        :raises GadgetEncodeError: If anything goes wrong during the serialization process
        """
        characteristics_json = [self.encode_characteristic_update(x) for x in gadget.get_characteristics()]

        gadget_json = {"id": gadget.get_name(),
                       "characteristics": characteristics_json}

        return gadget_json
Пример #7
0
 def receive_gadget_update(self, gadget: Gadget):
     for identifier in [x.get_type() for x in gadget.get_characteristics()]:
         try:
             self._update_characteristic(gadget, identifier)
         except CharacteristicParsingError as err:
             self._logger.info(err.args[0])