Esempio n. 1
0
    def val2bytes(val, att: str) -> bytes:
        """
        Convert value to bytes for given UBX attribute type.

        :param object val: attribute value e.g. 25
        :param str att: attribute type e.g. 'U004'
        :return: attribute value as bytes
        :rtype: bytes
        :raises: UBXTypeError

        """

        if att == ubt.CH:  # single variable-length string (e.g. INF-NOTICE)
            return val.encode("utf-8", "backslashreplace")
        atts = attsiz(att)
        if atttyp(att) in ("C", "X"):  # byte or char
            valb = val
        elif atttyp(att) in ("E", "L", "U"):  # unsigned integer
            valb = val.to_bytes(atts, byteorder="little", signed=False)
        elif atttyp(att) == "I":  # signed integer
            valb = val.to_bytes(atts, byteorder="little", signed=True)
        elif att == ubt.R4:  # single precision floating point
            valb = struct.pack("<f", val)
        elif att == ubt.R8:  # double precision floating point
            valb = struct.pack("<d", val)
        else:
            raise ube.UBXTypeError(f"Unknown attribute type {att}")
        return valb
Esempio n. 2
0
    def bytes2val(valb: bytes, att: str) -> object:
        """
        Convert bytes to value for given UBX attribute type.

        :param bytes valb: attribute value in byte format e.g. b'\\\\x19\\\\x00\\\\x00\\\\x00'
        :param str att: attribute type e.g. 'U004'
        :return: attribute value as int, float, str or bytes
        :rtype: object
        :raises: UBXTypeError

        """

        if att == ubt.CH:  # single variable-length string (e.g. INF-NOTICE)
            val = valb.decode("utf-8", "backslashreplace")
        elif atttyp(att) in ("X", "C"):
            val = valb
        elif atttyp(att) in ("E", "L", "U"):  # unsigned integer
            val = int.from_bytes(valb, "little", signed=False)
        elif atttyp(att) == "I":  # signed integer
            val = int.from_bytes(valb, "little", signed=True)
        elif att == ubt.R4:  # single precision floating point
            val = struct.unpack("<f", valb)[0]
        elif att == ubt.R8:  # double precision floating point
            val = struct.unpack("<d", valb)[0]
        else:
            raise ube.UBXTypeError(f"Unknown attribute type {att}")
        return val
Esempio n. 3
0
    def nomval(att: str) -> object:
        """
        Get nominal value for given UBX attribute type.

        :param str att: attribute type e.g. 'U004'
        :return: attribute value as int, float, str or bytes
        :rtype: object
        :raises: UBXTypeError

        """

        if att == "CH":
            val = ""
        elif atttyp(att) in ("X", "C"):
            val = b"\x00" * attsiz(att)
        elif atttyp(att) == "R":
            val = 0.0
        elif atttyp(att) in ("E", "I", "L", "U"):
            val = 0
        else:
            raise ube.UBXTypeError(f"Unknown attribute type {att}")
        return val
Esempio n. 4
0
    def _set_attribute_single(self, att: str, offset: int, key: str,
                              index: list, **kwargs) -> int:
        """
        Set individual attribute value.

        :param str att: attribute type e.g. 'U002'
        :param int offset: payload offset
        :param str key: attribute keyword
        :param list index: repeating group index array
        :param kwargs: optional payload key/value pairs
        :return: offset
        :rtype: int

        """
        # pylint: disable=no-member

        # if attribute is part of a (nested) repeating group, suffix name with index
        keyr = key
        for i in index:  # one index for each nested level
            if i > 0:
                keyr = keyr + "_{0:0=2d}".format(i)

        # determine attribute size (bytes)
        if att == ubt.CH:  # variable length string
            atts = len(self._payload)
        else:
            atts = attsiz(att)

        # if payload keyword has been provided,
        # use the appropriate offset of the payload
        if "payload" in kwargs:
            valb = self._payload[offset:offset + atts]
            val = self.bytes2val(valb, att)
        else:
            # if individual attribute keyword has been provided
            if keyr in kwargs:
                val = kwargs[keyr]
            # else set attribute to nominal value (0)
            else:
                if atttyp(att) in ("X", "C"):  # byte or char
                    val = b"\x00" * atts
                else:
                    val = 0
            valb = self.val2bytes(val, att)
            self._payload += valb

        setattr(self, keyr, val)
        offset += atts

        return offset
Esempio n. 5
0
    def _do_valset(self):
        """
        Send a CFG-VALSET message.

        :return: valid entry flag
        :rtype: bool
        """

        valid_entry = True
        att = atttyp(self._cfgatt.get())
        atts = attsiz(self._cfgatt.get())
        val = self._cfgval.get()
        layers = self._cfglayer.get()
        if layers == "BBR":
            layers = 2
        elif layers == "FLASH":
            layers = 4
        else:
            layers = 1
        try:
            if att in ("C", "X"):  # byte or char
                if len(val) == atts * 2:  # 2 hex chars per byte
                    val = bytearray.fromhex(val)
                else:
                    valid_entry = False
            elif att in ("E", "U"):  # unsigned integer
                val = int(val)
                if val < 0:
                    valid_entry = False
            elif att == "L":  # bool
                val = int(val)
                if val not in (0, 1):
                    valid_entry = False
            elif att == "I":  # signed integer
                val = int(val)
            elif att == "R":  # floating point
                val = float(val)
            transaction = 0
            cfgData = [
                (self._cfgval_keyname, val),
            ]
        except ValueError:
            valid_entry = False

        if valid_entry:
            msg = UBXMessage.config_set(layers, transaction, cfgData)
            self.__app.serial_handler.serial_write(msg.serialize())
            self._ent_val.configure(bg=ENTCOL)
            self._lbl_send_command.config(image=self._img_pending)
            self.__container.set_status("CFG-VALSET SET message sent", "blue")
            self.__container.set_pending(UBX_CFGVAL, ("ACK-ACK", "ACK-NAK"))
        else:
            self._ent_val.configure(bg=ERRCOL)
            self._lbl_send_command.config(image=self._img_warn)
            typ = ATTDICT[att]
            self.__container.set_status(
                ("INVALID ENTRY - must conform to parameter "
                 f"type {att} ({typ}) and size {atts} bytes"),
                "red",
            )

        return valid_entry