2 # vim: set expandtab tabstop=4 shiftwidth=4 :
3 #----------------------------------------------------------------------------
5 #----------------------------------------------------------------------------
6 # This file is part of etherled.
8 # etherled is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by the Free
10 # Software Foundation; either version 2 of the License, or (at your option)
13 # etherled is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 # You should have received a copy of the GNU General Public License along
19 # with etherled; if not, write to the Free Software Foundation, Inc., 59
20 # Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #----------------------------------------------------------------------------
22 # Creado: sáb oct 29 00:45:52 ART 2005
23 # Autores: Leandro Lucarella <llucare@fi.uba.ar>
24 #----------------------------------------------------------------------------
29 __all__ = ('SendError', 'RecvError', 'Client', 'NetworkedDevice', 'DummyServer')
34 # Cantidad de bytes de la columna de leds
37 class SendError(socket.error):
40 class RecvError(socket.error):
45 def __init__(self, host='localhost', port=38437, timeout=3.0):
48 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
49 self._sock.connect(self.addr)
50 self._sock.settimeout(timeout)
54 def send(self, type, var, data=None):
55 pkt = packet.ClientPacket(type, var, self._getId(type, var), data)
57 sent = self._sock.send(str(pkt))
58 except socket.timeout:
59 raise SendError, "Tiempo de espera agotado"
61 raise SendError, "Sólo se enviaron %d bytes de %d" \
65 msg = self._sock.recv(_BUFSIZ)
66 except socket.timeout:
67 raise RecvError, "Tiempo de espera agotado"
68 pkt_r = packet.ClientPacket(msg)
75 return self.send(packet.TYPE_GET, var)
77 def set(self, var, data):
78 self.send(packet.TYPE_SET, var, data)
80 def _getId(self, type, var):
81 id = self._ids.get((type, var), 0)
82 self._ids[type, var] = (id + 1) % packet.MAX_ID
92 return (self._host, self._port)
97 host = property(_getHost, doc='Host al cual enviar datos')
98 port = property(_getPort, doc='Puerto al cual enviar datos')
99 addr = property(_getAddr, doc='Tupla (host, port)')
100 drop = property(_getDrop, doc='Cantidad de paquetes descartados')
102 class NetworkedDevice(Client):
104 def _getMatrix(self):
105 stream = self.get(packet.VAR_MATRIX)
106 return _stream2Matrix(stream)
108 def _setMatrix(self, matrix):
109 stream = _matrix2Stream(matrix)
110 self.set(packet.VAR_MATRIX, stream)
112 matrix = property(_getMatrix, _setMatrix, doc='Matriz de leds')
116 def __init__(self, host='localhost', port=38437, timeout=3.0):
119 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
120 self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
121 self._sock.bind(self.addr)
122 self._vars = [None for i in xrange(8)]
126 (msg, addr) = self._sock.recvfrom(_BUFSIZ)
127 pkt = packet.ServerPacket(msg)
128 print 'Recibido:', repr(pkt)
129 if pkt.type == packet.TYPE_GET:
130 pkt.data = self._vars[pkt.var]
131 elif pkt.type == packet.TYPE_SET:
132 if pkt.var == packet.VAR_MATRIX:
133 _print_matrix(_stream2Matrix(pkt.data))
134 self._vars[pkt.var] = pkt.data
135 pkt = packet.ServerPacket(pkt.type, pkt.var, pkt.id)
136 sent = self._sock.sendto(str(pkt), addr)
138 raise SendError, "Sólo se enviaron %d bytes de %d" \
139 % (sent, len(packet))
140 print 'Enviado:', repr(pkt)
141 if pkt.type == packet.TYPE_GET and pkt.var == packet.VAR_MATRIX:
142 _print_matrix(_stream2Matrix(pkt.data))
151 return (self._host, self._port)
153 host = property(_getHost, doc='Host al cual enviar datos')
154 port = property(_getPort, doc='Puerto al cual enviar datos')
155 addr = property(_getAddr, doc='Tupla (host, port)')
157 def _stream2Matrix(stream):
158 cols = ord(stream[0]) # Obtiene tamaño
159 stream = stream[1:1+cols*_LED_BYTES] # me quedo con el resto
161 for col in xrange(cols-1, -1, -1):
162 for row_byte in xrange(_LED_BYTES):
163 byte = ord(stream[(cols-col-1)*_LED_BYTES+row_byte])
166 matrix[row_byte*8+i,col] = (byte >> shift) & 1
169 def _matrix2Stream(matrix):
170 cols = len(matrix) / (_LED_BYTES*8)
171 stream = chr(cols) # primero va el tamaño
172 for col in xrange(cols-1, -1, -1):
173 for i in xrange(_LED_BYTES):
175 for row in xrange(8):
177 byte += matrix[row+i*8,col] << shift
181 def _print_matrix(matrix):
182 for row in xrange(_LED_BYTES*8):
183 for col in xrange(len(matrix)/(_LED_BYTES*8)):
184 print matrix[row,col],
188 def _print_stream(stream):
190 print '0x%02X' % ord(c),
195 if __name__ == '__main__':
200 # Creo dispositivo por red
201 dev = NetworkedDevice()
204 for col in xrange(16):
205 for row in xrange(16):
206 matrix[row,col] = row % 2
208 print 'Matriz enviada:'
209 _print_matrix(matrix)
211 print 'Matriz recibida:'
212 _print_matrix(dev.matrix)
214 assert matrix == dev.matrix
215 ###########################
218 for col in xrange(16):
219 for row in xrange(16):
220 matrix[row,col] = col % 2
222 print 'Matriz enviada:'
223 _print_matrix(matrix)
225 print 'Matriz recibida:'
226 _print_matrix(dev.matrix)
228 assert matrix == dev.matrix
229 ###########################
232 for col in xrange(16):
233 for row in xrange(16):
234 matrix[row,col] = (col+row) % 2
236 print 'Matriz enviada:'
237 _print_matrix(matrix)
239 print 'Matriz recibida:'
240 _print_matrix(dev.matrix)
242 assert matrix == dev.matrix
243 ###########################
246 for col in xrange(16):
247 for row in xrange(16):
266 print 'Matriz enviada:'
267 _print_matrix(matrix)
269 print 'Matriz recibida:'
270 _print_matrix(dev.matrix)
272 assert matrix == dev.matrix
273 # Matamos al servidor
276 server = DummyServer()