PageRenderTime 304ms CodeModel.GetById 161ms app.highlight 11ms RepoModel.GetById 130ms app.codeStats 0ms

/pyfirmata/mockup.py

https://bitbucket.org/tino/pyfirmata/
Python | 147 lines | 144 code | 2 blank | 1 comment | 0 complexity | 594096c4c19fc21aac2c3d70c2fac5f7 MD5 | raw file
  1from collections import deque
  2import pyfirmata
  3
  4class MockupSerial(deque):
  5    """ 
  6    A Mockup object for python's Serial. Functions as a fifo-stack. Push to
  7    it with ``write``, read from it with ``read``.
  8    
  9    >>> s = MockupSerial('someport', 4800)
 10    >>> s.read()
 11    ''
 12    >>> s.write(chr(100))
 13    >>> s.write('blaat')
 14    >>> s.write(100000)
 15    >>> s.read(2)
 16    ['d', 'blaat']
 17    >>> s.read()
 18    100000
 19    >>> s.read()
 20    ''
 21    >>> s.read(2)
 22    ['', '']
 23    >>> s.close()
 24    """
 25    def __init__(self, port, baudrate, timeout=0.02):
 26        self.port = port or 'somewhere'
 27        
 28    def read(self, count=1):
 29        if count > 1:
 30            val = []
 31            for i in range(count):
 32                try:
 33                    val.append(self.popleft())
 34                except IndexError:
 35                    val.append('')
 36        else:
 37            try:
 38                val = self.popleft()
 39            except IndexError:
 40                val = ''
 41        return val
 42            
 43    def write(self, value):
 44        """
 45        Appends items flat to the deque. So iterables will be unpacked.
 46        """
 47        if hasattr(value, '__iter__'):
 48            self.extend(value)
 49        else:
 50            self.append(value)
 51            
 52    def close(self):
 53        self.clear()
 54        
 55    def inWaiting(self):
 56        return len(self)
 57        
 58class MockupBoard(pyfirmata.Board):
 59
 60    def __init__(self, port, layout, values_dict={}):
 61        self.sp = MockupSerial(port, 57600)
 62        self.setup_layout(layout)
 63        self.values_dict = values_dict
 64        self.id = 1
 65        
 66    def reset_taken(self):
 67        for key in self.taken['analog']:
 68            self.taken['analog'][key] = False
 69        for key in self.taken['digital']:
 70            self.taken['digital'][key] = False
 71        
 72    def update_values_dict(self):
 73        for port in self.digital_ports:
 74            port.values_dict = self.values_dict
 75            port.update_values_dict()
 76        for pin in self.analog:
 77            pin.values_dict = self.values_dict
 78        
 79class MockupPort(pyfirmata.Port):
 80    def __init__(self, board, port_number):
 81        self.board = board
 82        self.port_number = port_number
 83        self.reporting = False
 84        
 85        self.pins = []
 86        for i in range(8):
 87            pin_nr = i + self.port_number * 8
 88            self.pins.append(MockupPin(self.board, pin_nr, type=pyfirmata.DIGITAL, port=self))
 89
 90    def update_values_dict(self):
 91        for pin in self.pins:
 92            pin.values_dict = self.values_dict
 93        
 94class MockupPin(pyfirmata.Pin):
 95    def __init__(self, *args, **kwargs):
 96        self.values_dict = kwargs.get('values_dict', {})
 97        try:
 98            del kwargs['values_dict']
 99        except KeyError:
100            pass
101        super(MockupPin, self).__init__(*args, **kwargs)
102    
103    def read(self):
104        if self.value is None:
105            try:
106                type = self.port and 'd' or 'a'
107                return self.values_dict[type][self.pin_number]
108            except KeyError:
109                return None
110        else:
111            return self.value
112            
113    def get_in_output(self):
114        if not self.port and not self.mode: # analog input
115            return 'i'
116        else:
117            return 'o'
118            
119    def set_active(self, active):
120        self.is_active = active
121        
122    def get_active(self):
123        return self.is_active
124        
125    def write(self, value):
126        if self.mode == pyfirmata.UNAVAILABLE:
127            raise IOError, "Cannot read from pin %d" \
128                           % (self.pin_number)
129        if self.mode == pyfirmata.INPUT:
130            raise IOError, "%s pin %d is not an output" \
131                            % (self.port and "Digital" or "Analog", self.get_pin_number())
132        if not self.port:
133            raise AttributeError, "AnalogPin instance has no attribute 'write'"
134        # if value != self.read():
135        self.value = value
136        
137class Iterator(object):
138    def __init__(self, *args, **kwargs):
139        pass
140    def start(self):
141        pass
142    def stop(self):
143        pass
144
145if __name__ == '__main__':
146    import doctest
147    doctest.testmod()