#!/usr/bin/env python #-*- coding: iso8859-15 -*- ########################################################## # FILE_SIGNALS v1.0 # ########################################################## # Autor: Juan Miguel Taboada Godoy # # Fecha: Szczecin, 02 de Agosto de 2006 # # Descripción: Cargador de datos de ficheros SIGNALS # # Versión: 2006121300 # # # # Codigo fuente bajo licencia GNU/GPL # # Centrologic (Computational Logistic Center) # # http://www.centrologic.com - info@centrologic.com # ########################################################## # Librerías que voy a usar {{{1 import time import datetime from CRYPTOGRAFY import CRYPTOGRAFY from socket import socket, AF_INET, SOCK_DGRAM from INTERFACES import READABLE,REGISTRADOR from HERENCIA import BASE from MATH_GRA import digitos # }}}1 # Funcion general {{{1 # Errores conocidos por la clase {{{2 def error_conocido(error,return_list=False): # Construyo la lista de errores manejables lista=[] lista.append("ERROR_NET") # Devuelvo el resultado del analisis if (return_list): # Devuelvo la lista de errors conocidos return lista else: # Devuelvo si el error es conocido o no return (error in lista) # }}}2 # Transforma una fecha EPOCH a una cadena de texto sin espacios "dd/mm/aaaa_hh:mm:ss" {{{2 def fecha_str(timestamp): fechahora=datetime.datetime.fromtimestamp(float(timestamp)) fechatuple=fechahora.timetuple() fecha="%s/%s/%s" % (digitos("%s" % fechatuple[2],2),digitos("%s" % fechatuple[1],2),fechatuple[0]) hora="%s:%s:%s" % (digitos("%s" % fechatuple[3],2),digitos("%s" % fechatuple[4],2),digitos("%s" % fechatuple[5],2)) return "%s_%s" % (fecha,hora) # }}}2 # }}}1 # ### NET_UDP ### ################################ ## \internal ## NET_UDP: Libreria para manejo de conexiones mediante UDP ## \version 16/03/2007 1413 Szczecin class NET_UDP(BASE,READABLE,REGISTRADOR): # Constructor {{{1 ## Constructor ## \param self - ## \param ip Direccion IP del destino ## \param id ID que nos identifica ## \param bdsenales Objeto senales con todas las senales ## \param key3des Clave 3DES a usar def __init__(self,ip=None,id=None,bdsenales=None,key3des="abcdefghijklmnopqrstuvwx",port=57221): # Cargo las acciones del padre BASE.__init__(self,id,"NET_UDP") # Guarda la ip self.__ip=ip # Guarda las senales self.__bdsenales=bdsenales # Puerto de comunicaicones self.__port=port # Tamaño del buffer self.__bufsize=1024 # Arranco el sistema de encriptación self.__crypto=CRYPTOGRAFY() self.__crypto.load("3des",key3des) # Obtengo el socket de conexión self.__socket=socket(AF_INET, SOCK_DGRAM) self.__socket.bind(('',0)) # Creo la informacion del destinatario self.__destination=self.__ip,self.__port # Caracter de salida para valores nulos self.__nulo='x' # Lista de señales self.__signals=[] # Registrar cabecera de no-error errores_conocidos=error_conocido(None,True) self.__cabecera_no_error={} for dato in errores_conocidos: self.__cabecera_no_error[dato]=True # }}}1 # Devuelve la IP del sistema remoto atendido {{{1 ## Devuelve la IP del sistema remoto atendido ## \param self - def ip(self): return self.__ip # }}}1 # Carga el listado de senales entregadas {{{1 ## Carga la lista de senales entregadas ## \param self - ## \param referencia Nombre del telemando del que obtener senales o listado de senales def load(self,referencia): # Compruebo que tengo base de datos de senales if (self.__bdsenales==None): raise IOError,"Al crear el objeto no se ha entregado una base de datos de senales" # Obtengo el listado de senales si no fue entregado aun if (type(referencia)==type("abc")): senales=self.__bdsenales.search_tele(referencia) if (senales==[]): raise IOError,"No se ha encontrado ninguna senal para la referencia: %s" % (referencia) elif (type(referencia)==type([])): senales=referencia else: raise IOError,"El argumento de referencia solo puede ser el nombre de un Telemando o un listado de senales. Recibido: %s" % (referencia) # Proceso la lista de senales a recolectar for senal in senales: # Reviso si es el nombre de una senal o si es una senal compuesta if (type(senal)==type("abc")): # Busco la señal en la lista de senales (senalid,name,telemando,descripcion,tiposenal,conector,param1,param2)=self.__bdsenales.search(None,senal) else: # Descompongo la senal (senalid,name,telemando,descripcion,tiposenal,conector,param1,param2)=senal # Comprueba el resultado if (senalid==None): raise IOError,"No se ha encontrado la senal %s en el listado de senales" % (senal) # Descompongo el tipo tipopos=conector.split(":") if (len(tipopos)==2): (tipo,posicion)=tipopos slotpin=posicion.split(",") if (len(slotpin)==2): (slot,pin)=slotpin posicion=int(self.adamposition(slot,pin,(tiposenal=='a'))) tipodato=None elif (len(tipopos)==3): (tipo,posicion,tipodato)=tipopos slotpin=posicion.split(",") if (len(slotpin)==2): (slot,pin)=slotpin posicion=int(self.adamposition(slot,pin,(tiposenal=='a'))) else: raise IOError,"Error descomponiendo el conector" # Traduzco la posicion a entero posicion=int(posicion) # Añado la señal para ser procesada self.add(tipo,posicion) # }}}1 # Añade una señal para ser exportada por esta clase {{{1 ## Anade una senal para ser exportada por esta clase ## \param self - ## \param tipo Tipo de senal ## \param id ID de la senal def add(self,tipo,id): # Comprueba si la señal ya existe if ((tipo,id) in self.__signals): # Emite un error porque la señal ya existe raise IOError,"La senal %s ha sido repetida" % ((tipo,id)) else: # Añade la señal a la lista de señales aceptadas self.__signals.append((tipo,id)) # }}}1 # Registra un dato en la clase {{{1 ## \internal ## Funcion para registrar un dato en la clase (lo manda por UDP al destino) ## \param self - ## \param id Valor alfanumerico que representa al dato ## \param tipo Tipo del dato a almacenar ## \param valor Valor en este instante def register(self,id,tipo,valor): # Compruebo si la señal es aceptada if ((tipo,id) in self.__signals): # Compruebo si es un valor nulo if (valor==None): valor=self.__nulo # Obtengo la fecha en este instante ahora=time.time() # Crea el paquete paquete="%s#%s#%s#%s#%s" % (self.internal_id(),ahora,id,tipo,valor) # Encripto el paquete paquete_encriptado=self.__crypto.encrypt(paquete) # Envia el paquete self.__socket.sendto(paquete_encriptado,self.__destination) # }}}1 # Registrar un error (lo manda por UDP al destino) {{{1 ## Registra un error (lo manda por UDP al destino) ## \param self - ## \param tipo Tipo de error ## \param valor Valor del error def register_error(self,tipo,valor=1): # Compruebo si la señal es aceptada if (id in self.__signals): # Comprueba si es un valor nulo if (valor==None): valor=self.__nulo # Compruebo el tipo recibido es un error conocido if (error_conocido(tipo)): # Obtengo la fecha en este instante ahora=time.time() # Crea el paquete paquete="%s#%s#ERROR#%s#%s" % (self.internal_id(),ahora,tipo,valor) # Encripto el paquete paquete_encriptado=self.__crypto.encrypt(paquete) # Envia el paquete self.__socket.sendto(paquete_encriptado,self.__destination) else: raise IOError,"Registrar error: ERROR '%s' es desconocido" % (tipo) # }}}1 # Escribe los datos de la clase a disco (dummy) {{{1 ## \internal ## Escribe los datos de la clase a disco (dummy) ## \param self - ## \param limpiar_feedback Puede ser True o False, para indicar que tras escribir a disco se limpie la informacion de feedback (por defecto True) ## \param viaje_temporal Nos mueve en el tiempo ## \warning Esta funion no tiene ningun efecto cuando es usada, es DUMMY def write(self,limpiar_feedback=True,viaje_temporal=None): pass # }}}1 # Conversion of positions of memory for adam {{{1 ## Conversion of positions of memory for adam ## \param self - ## \param slot Slot number ## \param pin Pin number ## \param da Is analogic? (Default: False) def adamposition(self,slot,pin,analogic=False): # Get the number of pin per slot if (analogic): slot_pins=8 else: slot_pins=16 # Calculate the position of memory return (slot_pins*int(slot)+int(pin)) # }}}1 # ### EXCEPTIONS ### ################################## # EXCEPTION CLASSES {{{1 # Excepciones básicas # Except (General Exception) {{{2 class Except(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string #}}}2 # IOError (Error de entrada/salida) {{{2 class IOError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # ExecutionError (Error de ejecucción) {{{2 class ExecutionError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # Excepciones graves # TerminalError (Error irrecuperable del programa) {{{2 class TerminalError(Exception): def __init__(self,string): self.string=string def __str__(self): return self.string # }}}2 # }}}1