Exemple #1
0
    def write_single_register(self, starting_address, value):
        """
        Write single Register to Master device (Function code 6)
        starting_address:  Register to be written
        value: Register Value to be written
        """
        self.__transactionIdentifier += 1
        if (self.__ser is not None):
            if (self.__ser.closed):
                raise Exception.SerialPortNotOpenedException(
                    "serial port not opened")
        function_code = 6
        length = 6
        transaction_identifier_lsb = self.__transactionIdentifier & 0xFF
        transaction_identifier_msb = (
            (self.__transactionIdentifier & 0xFF00) >> 8)
        length_lsb = length & 0xFF
        length_msb = (length & 0xFF00) >> 8
        starting_address_lsb = starting_address & 0xFF
        starting_address_msb = (starting_address & 0xFF00) >> 8
        valueLSB = value & 0xFF
        valueMSB = (value & 0xFF00) >> 8
        if (self.__ser is not None):
            data = bytearray([
                self.__unitIdentifier, function_code, starting_address_msb,
                starting_address_lsb, valueMSB, valueLSB, 0, 0
            ])
            crc = self.__calculateCRC(data, len(data) - 2, 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            data[6] = crcLSB
            data[7] = crcMSB
            self.__ser.write(data)
            bytes_to_read = 8
            data = self.__ser.read(bytes_to_read)
            b = bytearray(data)
            data = b
            #Check for Exception
            if (len(data) < bytes_to_read):
                raise Exceptions.TimeoutError('Read timeout Exception')
            if ((data[1] == 0x86) & (data[2] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1] == 0x86) & (data[2] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Register address invalid")
            if ((data[1] == 0x86) & (data[2] == 0x03)):
                raise Exceptions.QuantityInvalidException(
                    "Invalid Register Value")
            if ((data[1] == 0x86) & (data[2] == 0x04)):
                raise Exceptions.ModbusException("error reading")
            crc = self.__calculateCRC(data, len(data) - 2, 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            if ((crcLSB != data[len(data) - 2]) &
                (crcMSB != data[len(data) - 1])):
                raise Exceptions.CRCCheckFailedException("CRC check failed")

            if data[1] == self.__unitIdentifier:
                return True
            else:
                return False
        else:
            protocolIdentifierLSB = 0x00
            protocolIdentifierMSB = 0x00
            length_lsb = 0x06
            length_msb = 0x00
            data = bytearray([
                transaction_identifier_msb, transaction_identifier_lsb,
                protocolIdentifierMSB, protocolIdentifierLSB, length_msb,
                length_lsb, self.__unitIdentifier, function_code,
                starting_address_msb, starting_address_lsb, valueMSB, valueLSB
            ])
            self.__tcpClientSocket.send(data)
            bytes_to_read = 12
            self.__receivedata = bytearray()
            try:
                while (len(self.__receivedata) == 0):
                    pass
            except Exception:
                raise Exception('Read Timeout')
            data = bytearray(self.__receivedata)
            if ((data[1 + 6] == 0x86) & (data[2 + 6] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1 + 6] == 0x86) & (data[2 + 6] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Register address invalid")
            if ((data[1 + 6] == 0x86) & (data[2 + 6] == 0x03)):
                raise Exceptions.QuantityInvalidException(
                    "Invalid Register Value")
            if ((data[1 + 6] == 0x86) & (data[2 + 6] == 0x04)):
                raise Exceptions.ModbusException("error reading")

                return True
Exemple #2
0
    def write_multiple_registers(self, starting_address, values):
        """
        Write multiple registers to Master device (Function code 16)
        starting_address: First register to be written
        values:  Register Values [0..quantity-1] to be written
        """
        self.__transactionIdentifier += 1
        if (self.__ser is not None):
            if (self.__ser.closed):
                raise Exception.SerialPortNotOpenedException(
                    "serial port not opened")
        function_code = 16
        length = 6
        transaction_identifier_lsb = self.__transactionIdentifier & 0xFF
        transaction_identifier_msb = (
            (self.__transactionIdentifier & 0xFF00) >> 8)
        length_lsb = length & 0xFF
        length_msb = (length & 0xFF00) >> 8
        starting_address_lsb = starting_address & 0xFF
        starting_address_msb = (starting_address & 0xFF00) >> 8
        quantityLSB = len(values) & 0xFF
        quantityMSB = (len(values) & 0xFF00) >> 8
        valueToWrite = list()
        for i in range(0, len(values)):
            valueToWrite.append(values[i])
        if (self.__ser is not None):
            data = bytearray([
                self.__unitIdentifier, function_code, starting_address_msb,
                starting_address_lsb, quantityMSB, quantityLSB
            ])
            data.append(len(valueToWrite) * 2)  #Bytecount
            for i in range(0, len(valueToWrite)):
                data.append((valueToWrite[i] & 0xFF00) >> 8)
                data.append(valueToWrite[i] & 0xFF)
            crc = self.__calculateCRC(data, len(data), 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            data.append(crcLSB)
            data.append(crcMSB)
            self.__ser.write(data)
            bytes_to_read = 8
            data = self.__ser.read(bytes_to_read)
            b = bytearray(data)
            data = b
            if (len(data) < bytes_to_read):
                raise Exceptions.TimeoutError('Read timeout Exception')
            if ((data[1] == 0x90) & (data[2] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1] == 0x90) & (data[2] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Starting address invalid or starting address + quantity invalid"
                )
            if ((data[1] == 0x90) & (data[2] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid")
            if ((data[1] == 0x90) & (data[2] == 0x04)):
                raise Exceptions.ModbusException("error reading")
            crc = self.__calculateCRC(data, len(data) - 2, 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            if ((crcLSB != data[len(data) - 2]) &
                (crcMSB != data[len(data) - 1])):
                raise Exceptions.CRCCheckFailedException("CRC check failed")
            if data[1] == self.__unitIdentifier:
                return True
            else:
                return False
        else:
            protocolIdentifierLSB = 0x00
            protocolIdentifierMSB = 0x00
            length_lsb = 0x06
            length_msb = 0x00
            data = bytearray([
                transaction_identifier_msb, transaction_identifier_lsb,
                protocolIdentifierMSB, protocolIdentifierLSB, length_msb,
                length_lsb, self.__unitIdentifier, function_code,
                starting_address_msb, starting_address_lsb, quantityMSB,
                quantityLSB
            ])
            data.append(len(valueToWrite) * 2)  #Bytecount
            for i in range(0, len(valueToWrite)):
                data.append((valueToWrite[i] & 0xFF00) >> 8)
                data.append(valueToWrite[i] & 0xFF)

            self.__tcpClientSocket.send(data)
            bytes_to_read = 12
            self.__receivedata = bytearray()
            try:
                while (len(self.__receivedata) == 0):
                    pass
            except Exception:
                raise Exception('Read Timeout')
            data = bytearray(self.__receivedata)
            if ((data[1] == 0x90) & (data[2] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1] == 0x90) & (data[2] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Starting address invalid or starting address + quantity invalid"
                )
            if ((data[1] == 0x90) & (data[2] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid")
            if ((data[1] == 0x90) & (data[2] == 0x04)):
                raise Exceptions.ModbusException("error reading")
            return True
Exemple #3
0
    def read_inputregisters(self, starting_address, quantity):
        """
        Read Input Registers from Master device (Function code 4)
        starting_address :  First input register to be read
        quantity:  Number of input registers to be read
        returns:  Int Array [0..quantity-1] which contains the input registers
        """
        self.__transactionIdentifier += 1
        if (self.__ser is not None):
            if (self.__ser.closed):
                raise Exception.SerialPortNotOpenedException(
                    "serial port not opened")
        if (starting_address > 65535) | (quantity > 125):
            raise ValueError(
                "Starting address must be 0 - 65535; quantity must be 0 - 125")
        function_code = 4
        length = 6
        transaction_identifier_lsb = self.__transactionIdentifier & 0xFF
        transaction_identifier_msb = (
            (self.__transactionIdentifier & 0xFF00) >> 8)
        length_lsb = length & 0xFF
        length_msb = (length & 0xFF00) >> 8
        starting_address_lsb = starting_address & 0xFF
        starting_address_msb = (starting_address & 0xFF00) >> 8
        quantity_lsb = quantity & 0xFF
        quantity_msb = (quantity & 0xFF00) >> 8
        if (self.__ser is not None):
            data = bytearray([
                self.__unitIdentifier, function_code, starting_address_msb,
                starting_address_lsb, quantity_msb, quantity_lsb, 0, 0
            ])
            crc = self.__calculateCRC(data, len(data) - 2, 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            data[6] = crcLSB
            data[7] = crcMSB

            self.__ser.write(data)
            bytes_to_read = 5 + int(quantity * 2)

            data = self.__ser.read(bytes_to_read)

            b = bytearray(data)
            data = b

            if (len(data) < bytes_to_read):
                raise Exceptions.TimeoutError("Read timeout Exception")
            if ((data[1] == 0x84) & (data[2] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1] == 0x84) & (data[2] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Starting address invalid or starting address + quantity invalid"
                )
            if ((data[1] == 0x84) & (data[2] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid")
            if ((data[1] == 0x84) & (data[2] == 0x04)):
                raise Exceptions.ModbusException("error reading")
            crc = self.__calculateCRC(data, len(data) - 2, 0)
            crcLSB = crc & 0xFF
            crcMSB = (crc & 0xFF00) >> 8
            if ((crcLSB != data[len(data) - 2]) &
                (crcMSB != data[len(data) - 1])):
                raise Exceptions.CRCCheckFailedException("CRC check failed")
            myList = list()
            for i in range(0, quantity):
                myList.append((data[i * 2 + 3] << 8) + data[i * 2 + 4])
            return myList
        else:
            protocolIdentifierLSB = 0x00
            protocolIdentifierMSB = 0x00
            length_lsb = 0x06
            length_msb = 0x00
            data = bytearray([
                transaction_identifier_msb, transaction_identifier_lsb,
                protocolIdentifierMSB, protocolIdentifierLSB, length_msb,
                length_lsb, self.__unitIdentifier, function_code,
                starting_address_msb, starting_address_lsb, quantity_msb,
                quantity_lsb
            ])
            self.__tcpClientSocket.send(data)
            bytes_to_read = 9 + int(quantity * 2)
            self.__receivedata = bytearray()
            try:
                while (len(self.__receivedata) == 0):
                    pass
            except Exception:
                raise Exception('Read Timeout')
            data = bytearray(self.__receivedata)
            if ((data[1 + 6] == 0x84) & (data[2 + 6] == 0x01)):
                raise Exceptions.function_codeNotSupportedException(
                    "Function code not supported by master")
            if ((data[1 + 6] == 0x84) & (data[2 + 6] == 0x02)):
                raise Exceptions.starting_addressInvalidException(
                    "Starting address invalid or starting address + quantity invalid"
                )
            if ((data[1 + 6] == 0x84) & (data[2 + 6] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid")
            if ((data[1 + 6] == 0x84) & (data[2 + 6] == 0x04)):
                raise Exceptions.ModbusException("error reading")
            myList = list()
            for i in range(0, quantity):
                myList.append((data[i * 2 + 3 + 6] << 8) + data[i * 2 + 4 + 6])
            return myList