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