def read_discreteinputs(self, starting_address, quantity):
        """
        Read Discrete Inputs from Master device (Function code 2)
        starting_address: First discrete input to be read
        quantity: Numer of discrete Inputs to be read
        returns: Boolean Array [0..quantity-1] which contains the discrete Inputs
        """
        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 >2000)):
            raise ValueError("Starting address must be 0 - 65535; quantity must be 0 - 2000");
        function_code = 2
        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)
            if (quantity % 8 != 0):
                bytes_to_read = 6+int(quantity/8)
            else:
                bytes_to_read = 5+int(quantity/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] == 0x82) & (data[2] == 0x01)):
                raise Exceptions.function_codeNotSupportedException("Function code not supported by master");
            if ((data[1] == 0x82) & (data[2] == 0x02)):
                raise Exceptions.starting_addressInvalidException("Starting address invalid or starting address + quantity invalid");
            if ((data[1] == 0x82) & (data[2] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid");
            if ((data[1] == 0x82) & (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(bool((data[int(i/8)+3] >> int(i%8)) & 0x1))            
            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)
            self.__receivedata = bytearray()
            if (quantity % 8 != 0):
                bytes_to_read = 9+int(quantity/8)
            else:
                bytes_to_read = 8+int(quantity/8)
            try:
                while (len(self.__receivedata) == 0):
                    pass
            except Exception:
                raise Exception('Read Timeout')

            data = bytearray(self.__receivedata)
            
            if ((data[1 + 6] == 0x82) & (data[2 + 6] == 0x01)):
                raise Exceptions.function_codeNotSupportedException("Function code not supported by master");
            if ((data[1 + 6] == 0x82) & (data[2+6] == 0x02)):
                raise Exceptions.starting_addressInvalidException("Starting address invalid or starting address + quantity invalid");
            if ((data[1 + 6] == 0x82) & (data[2+6] == 0x03)):
                raise Exceptions.QuantityInvalidException("quantity invalid");
            if ((data[1 + 6] == 0x82) & (data[2+6] == 0x04)):
                raise Exceptions.ModbusException("error reading");
            myList = list()
            for i in range(0, quantity):
                myList.append(bool((data[int(i/8)+3+6] >> int(i%8)) & 0x1))            
            return myList
def read_discreteinputs ( self , starting_address , quantity ) : 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 > 2000 ) ) : raise ValueError ( "Starting address must be 0 - 65535; quantity must be 0 - 2000" ) ; function_code = 2 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 ) if ( quantity % 8 != 0 ) : bytes_to_read = 6 + int ( quantity / 8 ) else : bytes_to_read = 5 + int ( quantity / 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 ] == 0x82 ) & ( data [ 2 ] == 0x01 ) ) : raise Exceptions . function_codeNotSupportedException ( "Function code not supported by master" ) ; if ( ( data [ 1 ] == 0x82 ) & ( data [ 2 ] == 0x02 ) ) : raise Exceptions . starting_addressInvalidException ( "Starting address invalid or starting address + quantity invalid" ) ; if ( ( data [ 1 ] == 0x82 ) & ( data [ 2 ] == 0x03 ) ) : raise Exceptions . QuantityInvalidException ( "quantity invalid" ) ; if ( ( data [ 1 ] == 0x82 ) & ( 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 ( bool ( ( data [ int ( i / 8 ) + 3 ] >> int ( i % 8 ) ) & 0x1 ) ) 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 ) self . __receivedata = bytearray ( ) if ( quantity % 8 != 0 ) : bytes_to_read = 9 + int ( quantity / 8 ) else : bytes_to_read = 8 + int ( quantity / 8 ) try : while ( len ( self . __receivedata ) == 0 ) : pass except Exception : raise Exception ( 'Read Timeout' ) data = bytearray ( self . __receivedata ) if ( ( data [ 1 + 6 ] == 0x82 ) & ( data [ 2 + 6 ] == 0x01 ) ) : raise Exceptions . function_codeNotSupportedException ( "Function code not supported by master" ) ; if ( ( data [ 1 + 6 ] == 0x82 ) & ( data [ 2 + 6 ] == 0x02 ) ) : raise Exceptions . starting_addressInvalidException ( "Starting address invalid or starting address + quantity invalid" ) ; if ( ( data [ 1 + 6 ] == 0x82 ) & ( data [ 2 + 6 ] == 0x03 ) ) : raise Exceptions . QuantityInvalidException ( "quantity invalid" ) ; if ( ( data [ 1 + 6 ] == 0x82 ) & ( data [ 2 + 6 ] == 0x04 ) ) : raise Exceptions . ModbusException ( "error reading" ) ; myList = list ( ) for i in range ( 0 , quantity ) : myList . append ( bool ( ( data [ int ( i / 8 ) + 3 + 6 ] >> int ( i % 8 ) ) & 0x1 ) ) return myList
Read Discrete Inputs from Master device (Function code 2)
        starting_address: First discrete input to be read
        quantity: Numer of discrete Inputs to be read
        returns: Boolean Array [0..quantity-1] which contains the discrete Inputs