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 class SendError(socket.error):
38 class RecvError(socket.error):
43 def __init__(self, host='localhost', port=38437, timeout=3.0):
46 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
47 self._sock.connect(self.addr)
48 self._sock.settimeout(timeout)
52 def send(self, type, var, data=None):
53 pkt = packet.ClientPacket(type, var, self._getId(type, var), data)
55 sent = self._sock.send(str(pkt))
56 except socket.timeout:
57 raise SendError, "Tiempo de espera agotado"
59 raise SendError, "Sólo se enviaron %d bytes de %d" \
63 msg = self._sock.recv(_BUFSIZ)
64 except socket.timeout:
65 raise RecvError, "Tiempo de espera agotado"
66 pkt_r = packet.ClientPacket(msg)
73 return self.send(packet.TYPE_GET, var)
75 def set(self, var, data):
76 self.send(packet.TYPE_SET, var, data)
78 def _getId(self, type, var):
79 id = self._ids.get((type, var), 0)
80 self._ids[type, var] = (id + 1) % packet.MAX_ID
90 return (self._host, self._port)
95 host = property(_getHost, doc='Host al cual enviar datos')
96 port = property(_getPort, doc='Puerto al cual enviar datos')
97 addr = property(_getAddr, doc='Tupla (host, port)')
98 drop = property(_getDrop, doc='Cantidad de paquetes descartados')
100 class NetworkedDevice(Client):
104 def _getMatrix(self):
105 stream = self.get(packet.VAR_MATRIX)
106 return self._stream2Matrix(stream)
108 def _setMatrix(self, matrix):
109 stream = self._matrix2Stream(matrix)
110 self.set(packet.VAR_MATRIX, stream)
112 def _stream2Matrix(self, stream):
113 cols = ord(stream[0]) # Obtiene tamaño
114 stream = stream[1:1+cols*self.LED_BYTES] # me quedo con el resto
116 for col in xrange(cols-1, -1, -1):
117 for row_byte in xrange(self.LED_BYTES):
118 byte = ord(stream[(cols-col-1)*self.LED_BYTES+row_byte])
121 matrix[col, row_byte*8+i] = (byte >> shift) & 1
124 def _matrix2Stream(self, matrix):
125 cols = len(matrix) / (self.LED_BYTES*8)
126 stream = chr(cols) # primero va el tamaño
127 for col in xrange(cols-1, -1, -1):
128 for i in xrange(self.LED_BYTES):
130 for row in xrange(8):
132 byte += matrix[col,row] << shift
136 matrix = property(_getMatrix, _setMatrix, doc='Matriz de leds')
140 def __init__(self, host='localhost', port=38437, timeout=3.0):
143 self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
144 self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
145 self._sock.bind(self.addr)
146 self._vars = [None for i in xrange(8)]
150 (msg, addr) = self._sock.recvfrom(_BUFSIZ)
151 pkt = packet.ServerPacket(msg)
152 if pkt.type == packet.TYPE_GET:
153 pkt.data = self._vars[pkt.var]
154 elif pkt.type == packet.TYPE_SET:
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))
169 return (self._host, self._port)
171 host = property(_getHost, doc='Host al cual enviar datos')
172 port = property(_getPort, doc='Puerto al cual enviar datos')
173 addr = property(_getAddr, doc='Tupla (host, port)')
175 def _print_matrix(matrix):
176 for row in xrange(NetworkedDevice.LED_BYTES*8):
177 for col in xrange(len(matrix)/(NetworkedDevice.LED_BYTES*8)):
178 print matrix[row,col],
182 def _print_stream(stream):
184 print '0x%02X' % ord(c),
189 if __name__ == '__main__':
194 # Creo dispositivo por red
195 dev = NetworkedDevice()
198 for col in xrange(16):
199 for row in xrange(16):
200 matrix[row,col] = row % 2
202 print 'Matriz enviada:'
203 _print_matrix(matrix)
205 print 'Matriz recibida:'
206 _print_matrix(dev.matrix)
208 assert matrix == dev.matrix
209 ###########################
212 for col in xrange(16):
213 for row in xrange(16):
214 matrix[row,col] = col % 2
216 print 'Matriz enviada:'
217 _print_matrix(matrix)
219 print 'Matriz recibida:'
220 _print_matrix(dev.matrix)
222 assert matrix == dev.matrix
223 ###########################
226 for col in xrange(16):
227 for row in xrange(16):
228 matrix[row,col] = (col+row) % 2
230 print 'Matriz enviada:'
231 _print_matrix(matrix)
233 print 'Matriz recibida:'
234 _print_matrix(dev.matrix)
236 assert matrix == dev.matrix
237 # Matamos al servidor
240 server = DummyServer()