Beispiel #1
0
    def _cmd(self, command, byte0=None, byte1=None):
        std_cmd = True

        # Set the first two command bytes; use defaults in most cases
        if not byte0:
            std_cmd = False
            byte0 = self.byte0
        if not byte1:
            std_cmd = False
            byte1 = self.byte1

        # Convery first two bytes to hex
        if isinstance(byte0, int): byte0 = hex(byte0)[2:].zfill(2)
        if isinstance(byte1, int): byte1 = hex(byte1)[2:].zfill(2)

        cmd = [byte0, byte1]

        # Each command has a category code.
        code = command[0]
        if isinstance(code, int): code = hex(code)[2:].zfill(2)

        # Each command has a length (of its data) associated with it.
        # N.B. this length INCLUDES the checksum value!
        length = command[1]
        if isinstance(length, int): length = hex(length)[2:].zfill(2)
        required_length = int(length, 16)

        # Add the category code and length to the command
        cmd.extend([code, length])

        # The actual command data. Include the checksum for length calculation
        data = command[2:]
        newdata = []
        for d in data:
            if isinstance(d, int):
                d = hex(d)[2:].zfill(2)
            newdata.append(d)
        data = newdata
        data_length = len(data) + 1

        # If issuing TV commands and the lengths don't match, zero-pad value
        if std_cmd and data_length != required_length:
            missing_data_length = required_length - data_length
            zero_pad = ['00' for x in range(missing_data_length)]
            data = zero_pad + data

        # Add the data to the command
        cmd.extend(data)

        # Calculate the checksum and add it to the command
        checksum = self._chksum(cmd)
        cmd.append(checksum)

        # Add a carriage return? Required? Probably not.
        #cmd.append('0D')

        # Uncomment for debugging; what is the whole command?
        #print "FINAL COMMAND:", cmd

        # Hex-encode the command for transmission
        try:
            enccmd = hexencode(''.join(cmd))
        except TypeError:
            raise EncodeError("Cannot encode command: '%s'" % command)

        # Write the command to the serial port connection
        self.__conn.write(enccmd)
        self.__conn.flushOutput()

        # Command responses are always going to be 3 (hex) bytes:
        # 0x70 (header), 0xXX (response code), 0xXX (checksum)
        response = self.__conn.read(6)

        # Wait longer to read the response if nothing was returned
        if len(response) is 0:
            #self.__conn.timeout = 0.1
            response = self.__conn.read(3)
            #self.__conn.timeout = self.command_interval

        # Zero-length responses are an error
        if len(response) is 0:
            raise ResponseError("No response received for command '%s'" % cmd)

        # Decode the hexadecimal response
        dec_response = hexdecode(response)

        # Extract the response (discard header and checksum)
        try:
            response_code = self._nsplit(dec_response)[1]
        except IndexError:
            raise ResponseError("Garbled response: '%s'" % response)

        # Raise exceptions if abnormal termination
        if response_code == '01':
            raise LimitOverError("Value overrun (exceeds maximum limit)")
        elif response_code == '02':
            raise LimitUnderError("Value underrun (below minimum limit)")
        elif response_code == '03':
            raise CommandCancelled("Invalid data/length (command cancelled)")
        elif response_code == '04':
            raise ParseError("Invalid command (parser error)")

        return response_code
Beispiel #2
0
 def serialize(self, sw, pyobj, name=None, attrtext='', **kw):
     String.serialize(self, sw, hexencode(pyobj).upper(), orig=pyobj, **kw)
    def _cmd(self, command, byte0=None, byte1=None):
        std_cmd = True

        # Set the first two command bytes; use defaults in most cases
        if not byte0:
            std_cmd = False
            byte0 = self.byte0
        if not byte1:
            std_cmd = False
            byte1 = self.byte1

        # Convert first two bytes to hex
        if isinstance(byte0, int):
            byte0 = hex(byte0)[2:].zfill(2)
        if isinstance(byte1, int):
            byte1 = hex(byte1)[2:].zfill(2)

        cmd = [byte0, byte1]

        # Each command has a category code.
        code = command[0]
        if isinstance(code, int):
            code = hex(code)[2:].zfill(2)

        # Each command has a length (of its data) associated with it.
        # N.B. this length INCLUDES the checksum value!
        length = command[1]
        if isinstance(length, int):
            length = hex(length)[2:].zfill(2)
        required_length = int(length, 16)

        # Add the category code and length to the command
        cmd.extend([code, length])

        # The actual command data. Include the checksum for length calculation
        data = command[2:]
        newdata = []
        for d in data:
            if isinstance(d, int):
                d = hex(d)[2:].zfill(2)
            newdata.append(d)
        data = newdata
        data_length = len(data) + 1

        # If issuing TV commands and the lengths don't match, zero-pad value
        if std_cmd and data_length != required_length:
            missing_data_length = required_length - data_length
            zero_pad = ['00' for x in range(missing_data_length)]
            data = zero_pad + data

        # Add the data to the command
        cmd.extend(data)

        # Calculate the checksum and add it to the command
        checksum = self._chksum(cmd)
        cmd.append(checksum)

        # Add a carriage return? Required? Probably not.
        # cmd.append('0D')

        # Hex-encode the command for transmission
        try:
            enccmd = hexencode(''.join(cmd))
        except TypeError:
            raise EncodeError("Cannot encode command: '%s'" % command)

        # Write the command to the serial port connection
        self.__conn.write(enccmd)
        self.__conn.flushOutput()

        # Command responses are always going to be 3 (hex) bytes:
        # 0x70 (header), 0xXX (response code), 0xXX (checksum)
        response = self.__conn.read(6)

        # Wait longer to read the response if nothing was returned
        if len(response) is 0:
            # self.__conn.timeout = 0.1
            response = self.__conn.read(3)
            # self.__conn.timeout = self.command_interval

        # Zero-length responses are an error
        if len(response) is 0:
            raise ResponseError("No response received for command '%s'" % cmd)

        # Decode the hexadecimal response
        dec_response = hexdecode(response)

        # Extract the response (discard header and checksum)
        try:
            response_code = self._nsplit(dec_response)[1]
            response_int = int(response_code, 16)
        except IndexError:
            raise ResponseError("Garbled response: '%s'" % response)

        # Raise exceptions if abnormal termination
        if response_int == 1:
            raise LimitOverError("Value overrun (exceeds maximum limit)")
        elif response_int == 2:
            raise LimitUnderError("Value underrun (below minimum limit)")
        elif response_int == 3:
            raise CommandCancelled("Invalid data/length (command cancelled)")
        elif response_int == 4:
            raise ParseError("Invalid command (parser error)")

        return response_int