133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck#! python
233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Python Serial Port Extension for Win32, Linux, BSD, Jython and .NET/Mono
333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# serial driver for .NET/Mono (IronPython), .NET >= 2
433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# see __init__.py
533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck#
633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# (C) 2008 Chris Liechti <cliechti@gmx.net>
733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# this is distributed under a free software license, see license.txt
833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport clr
1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport System
1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport System.IO.Ports
1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom serial.serialutil import *
1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef device(portnum):
1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    """Turn a port number into a device name"""
1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return System.IO.Ports.SerialPort.GetPortNames()[portnum]
1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# must invoke function with byte array, make a helper to convert strings
2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# to byte arrays
2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Recksab = System.Array[System.Byte]
2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef as_byte_array(string):
2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return sab([ord(x) for x in string])  # XXX will require adaption when run with a 3.x compatible IronPython
2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass IronSerial(SerialBase):
2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    """Serial port implementation for .NET/Mono."""
2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                9600, 19200, 38400, 57600, 115200)
3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def open(self):
3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Open port with current settings. This may throw a SerialException
3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck           if the port cannot be opened."""
3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._port is None:
3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise SerialException("Port must be configured before it can be used.")
3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._isOpen:
3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise SerialException("Port is already open.")
3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        try:
4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle = System.IO.Ports.SerialPort(self.portstr)
4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        except Exception, msg:
4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle = None
4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise SerialException("could not open port %s: %s" % (self.portstr, msg))
4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._reconfigurePort()
4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.Open()
4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._isOpen = True
4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._rtscts:
4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self.setRTS(True)
5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self.setDTR(True)
5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self.flushInput()
5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self.flushOutput()
5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def _reconfigurePort(self):
5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Set communication parameters on opened port."""
5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle:
5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise SerialException("Can only operate on a valid port handle")
5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        #~ self._port_handle.ReceivedBytesThreshold = 1
6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._timeout is None:
6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.ReadTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.ReadTimeout = int(self._timeout*1000)
6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # if self._timeout != 0 and self._interCharTimeout is not None:
6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            # timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:]
6833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._writeTimeout is None:
7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.WriteTimeout = System.IO.Ports.SerialPort.InfiniteTimeout
7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.WriteTimeout = int(self._writeTimeout*1000)
7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # Setup the connection info.
7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        try:
7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.BaudRate = self._baudrate
7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        except IOError, e:
7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            # catch errors from illegal baudrate settings
8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise ValueError(str(e))
8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._bytesize == FIVEBITS:
8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.DataBits     = 5
8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._bytesize == SIXBITS:
8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.DataBits     = 6
8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._bytesize == SEVENBITS:
8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.DataBits     = 7
8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._bytesize == EIGHTBITS:
8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.DataBits     = 8
9033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
9133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
9233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
9333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._parity == PARITY_NONE:
9433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Parity       = getattr(System.IO.Ports.Parity, 'None') # reserved keyword in Py3k
9533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._parity == PARITY_EVEN:
9633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Parity       = System.IO.Ports.Parity.Even
9733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._parity == PARITY_ODD:
9833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Parity       = System.IO.Ports.Parity.Odd
9933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._parity == PARITY_MARK:
10033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Parity       = System.IO.Ports.Parity.Mark
10133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._parity == PARITY_SPACE:
10233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Parity       = System.IO.Ports.Parity.Space
10333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
10433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise ValueError("Unsupported parity mode: %r" % self._parity)
10533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
10633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._stopbits == STOPBITS_ONE:
10733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.StopBits     = System.IO.Ports.StopBits.One
10833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:
10933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.StopBits     = System.IO.Ports.StopBits.OnePointFive
11033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._stopbits == STOPBITS_TWO:
11133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.StopBits     = System.IO.Ports.StopBits.Two
11233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
11333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
11433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
11533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._rtscts and self._xonxoff:
11633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Handshake  = System.IO.Ports.Handshake.RequestToSendXOnXOff
11733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._rtscts:
11833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Handshake  = System.IO.Ports.Handshake.RequestToSend
11933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        elif self._xonxoff:
12033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Handshake  = System.IO.Ports.Handshake.XOnXOff
12133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
12233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Handshake  = getattr(System.IO.Ports.Handshake, 'None')   # reserved keyword in Py3k
12333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
12433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    #~ def __del__(self):
12533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        #~ self.close()
12633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
12733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def close(self):
12833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Close port"""
12933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self._isOpen:
13033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            if self._port_handle:
13133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                try:
13233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                    self._port_handle.Close()
13333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                except System.IO.Ports.InvalidOperationException:
13433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                    # ignore errors. can happen for unplugged USB serial devices
13533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                    pass
13633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                self._port_handle = None
13733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._isOpen = False
13833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
13933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def makeDeviceName(self, port):
14033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        try:
14133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            return device(port)
14233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        except TypeError, e:
14333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise SerialException(str(e))
14433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
14533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
14633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
14733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def inWaiting(self):
14833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Return the number of characters currently in the input buffer."""
14933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
15033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._port_handle.BytesToRead
15133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
15233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def read(self, size=1):
15333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Read size bytes from the serial port. If a timeout is set it may
15433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck           return less characters as requested. With no timeout it will block
15533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck           until the requested number of bytes is read."""
15633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
15733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # must use single byte reads as this is the only way to read
15833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # without applying encodings
15933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        data = bytearray()
16033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        while size:
16133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            try:
16233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                data.append(self._port_handle.ReadByte())
16333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            except System.TimeoutException, e:
16433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                break
16533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            else:
16633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                size -= 1
16733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return bytes(data)
16833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
16933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def write(self, data):
17033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Output the given string over the serial port."""
17133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
17233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not isinstance(data, (bytes, bytearray)):
17333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
17433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        try:
17533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            # must call overloaded method with byte array argument
17633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            # as this is the only one not applying encodings
17733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            self._port_handle.Write(as_byte_array(data), 0, len(data))
17833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        except System.TimeoutException, e:
17933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            raise writeTimeoutError
18033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return len(data)
18133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
18233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def flushInput(self):
18333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Clear input buffer, discarding all that is in the buffer."""
18433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
18533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.DiscardInBuffer()
18633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
18733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def flushOutput(self):
18833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Clear output buffer, aborting the current output and
18933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        discarding all that is in the buffer."""
19033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
19133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.DiscardOutBuffer()
19233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
19333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def sendBreak(self, duration=0.25):
19433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Send break condition. Timed, returns to idle state after given duration."""
19533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
19633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        import time
19733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.BreakState = True
19833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        time.sleep(duration)
19933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.BreakState = False
20033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
20133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def setBreak(self, level=True):
20233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Set break: Controls TXD. When active, to transmitting is possible."""
20333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
20433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.BreakState = bool(level)
20533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
20633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def setRTS(self, level=True):
20733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Set terminal status line: Request To Send"""
20833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
20933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.RtsEnable = bool(level)
21033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
21133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def setDTR(self, level=True):
21233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Set terminal status line: Data Terminal Ready"""
21333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
21433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self._port_handle.DtrEnable = bool(level)
21533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
21633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def getCTS(self):
21733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Read terminal status line: Clear To Send"""
21833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
21933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._port_handle.CtsHolding
22033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
22133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def getDSR(self):
22233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Read terminal status line: Data Set Ready"""
22333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
22433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._port_handle.DsrHolding
22533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
22633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def getRI(self):
22733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Read terminal status line: Ring Indicator"""
22833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
22933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        #~ return self._port_handle.XXX
23033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return False #XXX an error would be better
23133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
23233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def getCD(self):
23333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        """Read terminal status line: Carrier Detect"""
23433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if not self._port_handle: raise portNotOpenError
23533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._port_handle.CDHolding
23633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
23733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # - - platform specific - - - -
23833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # none
23933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
24033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
24133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# assemble Serial class with the platform specific implementation and the base
24233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# for file-like behavior. for Python 2.6 and newer, that provide the new I/O
24333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# library, derive from io.RawIOBase
24433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Recktry:
24533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    import io
24633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckexcept ImportError:
24733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # classic version with our own file-like emulation
24833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    class Serial(IronSerial, FileLike):
24933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        pass
25033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckelse:
25133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    # io library present
25233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    class Serial(IronSerial, io.RawIOBase):
25333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        pass
25433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
25533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
25633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Nur Testfunktion!!
25733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckif __name__ == '__main__':
25833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    import sys
25933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
26033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s = Serial(0)
26133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    sys.stdio.write('%s\n' % s)
26233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
26333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s = Serial()
26433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    sys.stdio.write('%s\n' % s)
26533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
26633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
26733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s.baudrate = 19200
26833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s.databits = 7
26933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s.close()
27033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s.port = 0
27133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    s.open()
27233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    sys.stdio.write('%s\n' % s)
27333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
274