/pyfirmata/mockup.py

https://bitbucket.org/tino/pyfirmata/ · Python · 147 lines · 142 code · 2 blank · 3 comment · 2 complexity · 594096c4c19fc21aac2c3d70c2fac5f7 MD5 · raw file

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