2 # -*- coding: iso-8859-1 -*-
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=38437, 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)
76 return self.send(packet.TYPE_GET, var)
78 def set(self, var, data):
79 self.send(packet.TYPE_SET, var, data)
81 def _getId(self, type, var):
82 id = self._ids.get((type, var), 0)
83 self._ids[type, var] = (id + 1) % packet.MAX_ID
93 return (self._host, self._port)
98 host = property(_getHost, doc='Host al cual enviar datos')
99 port = property(_getPort, doc='Puerto al cual enviar datos')
100 addr = property(_getAddr, doc='Tupla (host, port)')
101 drop = property(_getDrop, doc='Cantidad de paquetes descartados')
103 class NetworkedDevice(Client):
105 def _getMatrix(self):
106 stream = self.get(packet.VAR_MATRIX)
107 return _stream2Matrix(stream)
109 def _setMatrix(self, matrix):
110 stream = _matrix2Stream(matrix)
111 self.set(packet.VAR_MATRIX, stream)
113 matrix = property(_getMatrix, _setMatrix, doc='Matriz de leds')
117 def __init__(self, host='localhost', port=38437, timeout=3.0):
120 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
121 self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
122 self._sock.bind(self.addr)
123 self._vars = [None for i in xrange(8)]
127 (msg, addr) = self._sock.recvfrom(_BUFSIZ)
128 pkt = packet.ServerPacket(msg)
129 print 'Recibido:', repr(pkt)
130 if pkt.type == packet.TYPE_GET:
131 pkt.data = self._vars[pkt.var]
132 elif pkt.type == packet.TYPE_SET:
133 if pkt.var == packet.VAR_MATRIX:
134 _print_matrix(_stream2Matrix(pkt.data))
135 self._vars[pkt.var] = pkt.data
136 pkt = packet.ServerPacket(pkt.type, pkt.var, pkt.id)
137 sent = self._sock.sendto(str(pkt), addr)
139 raise SendError, "Sólo se enviaron %d bytes de %d" \
140 % (sent, len(packet))
141 print 'Enviado:', repr(pkt)
142 if pkt.type == packet.TYPE_GET and pkt.var == packet.VAR_MATRIX:
143 _print_matrix(_stream2Matrix(pkt.data))
152 return (self._host, self._port)
154 host = property(_getHost, doc='Host al cual enviar datos')
155 port = property(_getPort, doc='Puerto al cual enviar datos')
156 addr = property(_getAddr, doc='Tupla (host, port)')
158 def _stream2Matrix(stream):
159 cols = ord(stream[0]) # Obtiene tamaño
160 stream = stream[1:1+cols*_LED_BYTES] # me quedo con el resto
162 for col in xrange(cols-1, -1, -1):
163 for row_byte in xrange(_LED_BYTES):
164 byte = ord(stream[(cols-col-1)*_LED_BYTES+row_byte])
167 matrix[row_byte*8+i,col] = (byte >> shift) & 1
170 def _matrix2Stream(matrix):
171 cols = len(matrix) / (_LED_BYTES*8)
172 stream = chr(cols) # primero va el tamaño
173 for col in xrange(cols-1, -1, -1):
174 for i in xrange(_LED_BYTES):
176 for row in xrange(8):
178 byte += matrix[row+i*8,col] << shift
182 def _print_matrix(matrix):
183 for row in xrange(_LED_BYTES*8):
184 for col in xrange(len(matrix)/(_LED_BYTES*8)):
185 print matrix[row,col],
189 def _print_stream(stream):
191 print '0x%02X' % ord(c),
196 if __name__ == '__main__':
201 # Creo dispositivo por red
202 dev = NetworkedDevice()
205 for col in xrange(16):
206 for row in xrange(16):
207 matrix[row,col] = row % 2
209 print 'Matriz enviada:'
210 _print_matrix(matrix)
212 print 'Matriz recibida:'
213 _print_matrix(dev.matrix)
215 assert matrix == dev.matrix
216 ###########################
219 for col in xrange(16):
220 for row in xrange(16):
221 matrix[row,col] = col % 2
223 print 'Matriz enviada:'
224 _print_matrix(matrix)
226 print 'Matriz recibida:'
227 _print_matrix(dev.matrix)
229 assert matrix == dev.matrix
230 ###########################
233 for col in xrange(16):
234 for row in xrange(16):
235 matrix[row,col] = (col+row) % 2
237 print 'Matriz enviada:'
238 _print_matrix(matrix)
240 print 'Matriz recibida:'
241 _print_matrix(dev.matrix)
243 assert matrix == dev.matrix
244 ###########################
247 for col in xrange(16):
248 for row in xrange(16):
267 print 'Matriz enviada:'
268 _print_matrix(matrix)
270 print 'Matriz recibida:'
271 _print_matrix(dev.matrix)
273 assert matrix == dev.matrix
274 # Matamos al servidor
277 server = DummyServer()