Opens the device.

        :param baudrate: baudrate to use
        :type baudrate: int
        :param no_reader_thread: whether or not to automatically open the reader
                                 thread.
        :type no_reader_thread: bool

        :raises: :py:class:`~alarmdecoder.util.NoDeviceError`, :py:class:`~alarmdecoder.util.CommError`

def open(self, baudrate=None, no_reader_thread=False):
        """
        Opens the device.

        :param baudrate: baudrate to use
        :type baudrate: int
        :param no_reader_thread: whether or not to automatically open the reader
                                 thread.
        :type no_reader_thread: bool

        :raises: :py:class:`~alarmdecoder.util.NoDeviceError`, :py:class:`~alarmdecoder.util.CommError`
        """

        try:
            self._read_thread = Device.ReadThread(self)

            self._device = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            if self._use_ssl:
                self._init_ssl()

            self._device.connect((self._host, self._port))

            if self._use_ssl:
                while True:
                    try:
                        self._device.do_handshake()
                        break
                    except SSL.WantReadError:
                        pass

            self._id = '{0}:{1}'.format(self._host, self._port)

        except socket.error as err:
            raise NoDeviceError('Error opening device at {0}:{1}'.format(self._host, self._port), err)

        else:
            self._running = True
            self.on_open()

            if not no_reader_thread:
                self._read_thread.start()

        return self