2 # -*- coding: utf-8 -*-
3 # vim: set expandtab tabstop=4 shiftwidth=4 :
4 #----------------------------------------------------------------------------
6 #----------------------------------------------------------------------------
7 # This file is part of etherled.
9 # etherled is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the Free
11 # Software Foundation; either version 2 of the License, or (at your option)
14 # etherled is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 # You should have received a copy of the GNU General Public License along
20 # with etherled; if not, write to the Free Software Foundation, Inc., 59
21 # Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #----------------------------------------------------------------------------
23 # Creado: sáb oct 29 00:45:52 ART 2005
24 # Autores: Leandro Lucarella <llucare@fi.uba.ar>
25 #----------------------------------------------------------------------------
30 __all__ = ('SendError', 'RecvError', 'Client', 'NetworkedDevice', 'DummyServer')
35 # Cantidad de bytes de la columna de leds
38 class SendError(socket.error):
41 class RecvError(socket.error):
46 def __init__(self, host='localhost', port=9876, timeout=3.0):
49 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
50 self._sock.connect(self.addr)
51 self._sock.settimeout(timeout)
55 def send(self, type, var, data=None):
56 pkt = packet.ClientPacket(type, var, self._getId(type, var), data)
58 sent = self._sock.send(str(pkt))
59 except socket.timeout:
60 raise SendError, "Tiempo de espera agotado"
62 raise SendError, "Sólo se enviaron %d bytes de %d" \
66 msg = self._sock.recv(_BUFSIZ)
67 except socket.timeout:
68 raise RecvError, "Tiempo de espera agotado"
69 pkt_r = packet.ClientPacket(msg)
77 return self.send(packet.TYPE_GET, var)
79 def set(self, var, data):
80 self.send(packet.TYPE_SET, var, data)
82 def _getId(self, type, var):
83 id = self._ids.get((type, var), 0)
84 self._ids[type, var] = (id + 1) % (packet.MAX_ID + 1)
94 return (self._host, self._port)
99 host = property(_getHost, doc='Host al cual enviar datos')
100 port = property(_getPort, doc='Puerto al cual enviar datos')
101 addr = property(_getAddr, doc='Tupla (host, port)')
102 drop = property(_getDrop, doc='Cantidad de paquetes descartados')
104 class NetworkedDevice(Client):
107 self.set(packet.VAR_OFF)
109 def _getMatrix(self):
110 stream = self.get(packet.VAR_MATRIX)
111 return _stream2Matrix(stream)
113 def _setMatrix(self, matrix):
114 stream = _matrix2Stream(matrix)
115 self.set(packet.VAR_MATRIX, stream)
117 def _getPaused(self):
118 return bool(ord(self.get(packet.VAR_PAUSE)))
120 def _setPaused(self, paused):
121 self.set(packet.VAR_PAUSE, chr(paused))
124 return ord(self.get(packet.VAR_DELAY))
126 def _setDelay(self, delay):
127 self.set(packet.VAR_DELAY, chr(delay & 0xFF))
129 matrix = property(_getMatrix, _setMatrix, doc='Matriz de leds')
130 paused = property(_getPaused, _setPaused,
131 doc='Indica si el dispositivo está en pausa')
132 delay = property(_getDelay, _setDelay,
133 doc='Timpo de retardo del dibujado')
137 def __init__(self, host='localhost', port=9876, timeout=3.0):
140 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
141 self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
142 self._sock.bind(self.addr)
143 self._vars = [None for i in xrange(8)]
147 (msg, addr) = self._sock.recvfrom(_BUFSIZ)
148 pkt = packet.ServerPacket(msg)
149 print 'Recibido:', repr(pkt)
150 if pkt.type == packet.TYPE_GET:
151 pkt.data = self._vars[pkt.var]
152 elif pkt.type == packet.TYPE_SET:
153 if pkt.var == packet.VAR_MATRIX:
154 _print_matrix(_stream2Matrix(pkt.data))
155 self._vars[pkt.var] = pkt.data
156 pkt = packet.ServerPacket(pkt.type, pkt.var, pkt.id)
157 sent = self._sock.sendto(str(pkt), addr)
159 raise SendError, "Sólo se enviaron %d bytes de %d" \
160 % (sent, len(packet))
161 print 'Enviado:', repr(pkt)
162 if pkt.type == packet.TYPE_GET and pkt.var == packet.VAR_MATRIX:
163 _print_matrix(_stream2Matrix(pkt.data))
172 return (self._host, self._port)
174 host = property(_getHost, doc='Host al cual enviar datos')
175 port = property(_getPort, doc='Puerto al cual enviar datos')
176 addr = property(_getAddr, doc='Tupla (host, port)')
178 def _stream2Matrix(stream):
179 cols = ord(stream[0]) # Obtiene tamaño
180 stream = stream[1:1+cols*_LED_BYTES] # me quedo con el resto
182 for col in xrange(cols):
183 for row_byte in xrange(_LED_BYTES):
184 byte = ord(stream[col*_LED_BYTES+_LED_BYTES-row_byte-1])
186 matrix[row_byte*8+i,col] = (byte >> i) & 1
189 def _matrix2Stream(matrix):
190 cols = len(matrix) / (_LED_BYTES*8)
191 stream = chr(cols) # primero va el tamaño
192 for col in xrange(cols):
193 for i in xrange(_LED_BYTES-1, -1, -1):
195 for row in xrange(7, -1, -1):
196 byte += matrix[row+i*8,col] << row
200 def _print_matrix(matrix):
201 for row in xrange(_LED_BYTES*8):
202 for col in xrange(len(matrix)/(_LED_BYTES*8)):
203 print matrix[row,col],
207 def _print_stream(stream):
209 print '0x%02X' % ord(c),
214 if __name__ == '__main__':
219 # Creo dispositivo por red
220 dev = NetworkedDevice()
223 for col in xrange(16):
224 for row in xrange(16):
225 matrix[row,col] = row % 2
227 print 'Matriz enviada:'
228 _print_matrix(matrix)
230 print 'Matriz recibida:'
231 _print_matrix(dev.matrix)
233 assert matrix == dev.matrix
234 ###########################
237 for col in xrange(16):
238 for row in xrange(16):
239 matrix[row,col] = col % 2
241 print 'Matriz enviada:'
242 _print_matrix(matrix)
244 print 'Matriz recibida:'
245 _print_matrix(dev.matrix)
247 assert matrix == dev.matrix
248 ###########################
251 for col in xrange(16):
252 for row in xrange(16):
253 matrix[row,col] = (col+row) % 2
255 print 'Matriz enviada:'
256 _print_matrix(matrix)
258 print 'Matriz recibida:'
259 _print_matrix(dev.matrix)
261 assert matrix == dev.matrix
262 ###########################
265 for col in xrange(16):
266 for row in xrange(16):
285 print 'Matriz enviada:'
286 _print_matrix(matrix)
288 print 'Matriz recibida:'
289 _print_matrix(dev.matrix)
291 assert matrix == dev.matrix
292 # Probamos con otras cositas
294 assert dev.paused == True
296 assert dev.paused == False
298 assert dev.delay == 0x40
300 assert dev.delay == 0xff
301 # Matamos al servidor
304 server = DummyServer()