def crear_post_evento(self, evento, tweets_procesados, medidas_procesadas): tipo = self.repo_eventos.obtener_tipo_evento(evento['codigoTipo']) estacion = self.repo_estaciones.obtener_estacion(evento['idEstacion']) try: nuevo_post_evento = PostEvento({ 'idEvento': str(evento['_id']), 'tipo': tipo['nombre'], 'lugar': estacion['nombre'], 'idEstacion': evento['idEstacion'], 'coords': estacion['coordenadas'], 'medidas': medidas_procesadas, 'tweets': tweets_procesados, 'fechaInicio': util.convertir_fecha_a_cadena(evento['fechaInicio'], self.cfg.FORMATO_FECHA), 'fechaFin': util.convertir_fecha_a_cadena(evento['fechaFin'], self.cfg.FORMATO_FECHA) }) return nuevo_post_evento except AttributeError as aterr: raise AttributeError(u'Error creando post evento. {0}'.format( aterr.message))
def leer_json(self, datos_json): datos = json.loads(datos_json) ultimo_dato = datos['datos'][0] if not ultimo_dato: raise ValueError( u'No se han podido leer los datos del json devuelto por la api.' ) fecha_utc = util.convertir_cadena_a_fecha( ultimo_dato['fecha'], self.cfg_proveedor.FORMATO_FECHA) if not self.cfg_proveedor.ES_UTC: fecha_utc = util.convertir_a_utc(fecha_utc, cfg.FORMATO_FECHA) return (fecha_utc, ultimo_dato['valor'])
def __crear_evento(self): return Evento({ 'fechaInicio': util.fecha_actual_str(cfg.FORMATO_FECHA), 'fechaFin': util.fecha_actual_str(cfg.FORMATO_FECHA), 'codigoTipo': self.cod_tipo_evento_fluvial, 'idEstacion': self.id_estacion, 'activo': True, 'toponimos': [], 'datosAemet': [], 'datosPuertos': [], 'datosConfederaciones': [], 'datosTwitter': [], 'datosInstagram': [] })
def test_comprueba_parseo_cadena_a_fecha(self): cadena_fecha = "09-02-2017 15:30" cadena_error = "test-error" formato = "%d-%m-%Y %H:%M" try: # Parseo correcto fecha = util.convertir_cadena_a_fecha(cadena_fecha, formato) self.assertIsNotNone(fecha) self.assertIsInstance(fecha, datetime.datetime) # Forzar el error de parseo util.convertir_cadena_a_fecha(cadena_error, formato) except Exception as ex: self.assertTrue(isinstance(ex, ValueError))
def _activar_eventos_costeros_fake(self): tipo_costero = self.repo_tipos_evento.obtener_tipo_evento_costero() proveedor_boyas = self.repo_confederaciones.obtener_proveedor_boyas() estaciones_con_evento = [] for confederacion in self.repo_confederaciones.obtener_confederaciones( ): deteccion = Deteccion(cfg, self.log, proveedor_boyas) estaciones = self.repo_estaciones.obtener_estaciones_de_tipo( confederacion['codigo'], tipo_costero['codigo'], True) if not estaciones: continue estacion_seleccionada = random.choice(estaciones) variable_deteccion = self.repo_variables.obtener_variable_por_nombre( proveedor_boyas.cfg_proveedor.VARIABLE_DETECCION) variable_estacion = util.filtrar_lista( estacion_seleccionada['variables'], 'codigo', variable_deteccion['codigo']) variable_estacion['umbrales'][proveedor_boyas.cfg_proveedor. NIVEL_ALERTA] = 0.01 #Alterar umbral deteccion.comprobar_estado_estaciones([estacion_seleccionada], variable_deteccion) estaciones_con_evento.append(estacion_seleccionada) return estaciones_con_evento
def ultima_medida_de_estacion(self, estacion, variable): '''Descarga el fichero con el ultimo lote de datos de una variable y extrae la ultima medida disponible''' variable_estacion = util.filtrar_lista(estacion['variables'], 'codigo', variable['codigo']) html = self.descargar_html_con_datos(variable_estacion['signal']) medida = self.extraer_medida_de_html(estacion['id'], variable['codigo'], html) return medida
def test_activa_y_desactiva_gestion_de_evento_fluvial(self): tipo_fluvial = self.repo_tipos_evento.obtener_tipo_evento_fluvial() estacion_test = self.__obtener_estacion_aleatoria_de_un_tipo( tipo_fluvial) proveedor_confe = self.repo_confederaciones.obtener_proveedor_saih( self.repo_confederaciones.obtener_confederacion( estacion_test['codigoConfederacion'])) variable_deteccion = self.repo_variables.obtener_variable_por_nombre( proveedor_confe.cfg_proveedor.VARIABLE_DETECCION) # Activar gestion alerta inserted_id = self.Coordinador.gestionar_alerta( estacion_test, variable_deteccion, True) eventos_activos = self.repo_eventos.obtener_eventos_activos_de_tipo( tipo_fluvial['codigo']) evento_estacion = util.filtrar_lista(eventos_activos, 'idEstacion', estacion_test['id']) self.assertIsNotNone(evento_estacion) self.assertTrue(evento_estacion['activo']) # Desactiva gestion alerta self.Coordinador.desactivar_evento(evento_estacion) self.assertFalse(evento_estacion['activo']) self.assertIsNotNone(evento_estacion['fechaFin']) self.repo_eventos.borrar_evento(inserted_id)
def desactivar_evento(self, evento): evento['activo'] = False evento['fechaFin'] = util.fecha_actual(self.cfg.FORMATO_FECHA) res = self.repo_eventos.actualizar_evento(evento) if res.modified_count == 1: self.log.escribir(u' - Valores normalizados, EVENTO DESACTIVADO', self.log.INFO) else: self.log.escribir(u' - No se ha podido desactivar el evento. Error actualizando la BD', self.log.WARNING)
def ultima_medida_de_estacion(self, estacion, variable): '''Hace una peticion a la api y obtiene la ultima medida disponible''' variable_estacion = util.filtrar_lista(estacion['variables'], 'codigo', variable['codigo']) datos_json = self.descargar_json_con_datos(variable_estacion['signal']) medida = self.extraer_medida_de_json(estacion['id'], variable['codigo'], datos_json) return medida
def obtener_umbral(estacion, cod_variable, nivel_alerta): variable_estacion = util.filtrar_lista(estacion['variables'], 'codigo', cod_variable) if not variable_estacion: raise ValueError(u' Variable de detección no disponible') if variable_estacion['umbrales'][nivel_alerta]: return variable_estacion['umbrales'][nivel_alerta] return None
def procesar_medidas(self, medidas): '''Estandarizacion de los datos de los sensores''' self.log.escribir(u' - Estandarización de datos', self.log.INFO) # Pasar las fechas internas de las medidas a cadena para poder insertar # en BD for medida in medidas: medida['fecha'] = util.convertir_fecha_a_cadena( medida['fecha'], self.cfg.FORMATO_FECHA) return medidas
def test_filtro_avanzado_tweets(self): tipo_fluvial = self.repo_tipos_evento.obtener_tipo_evento_fluvial() eventos = self.repo_eventos.obtener_eventos() evento_fluvial = util.filtrar_lista(eventos, 'codigoTipo', tipo_fluvial['codigo']) tweets_filtrados = self.twitter.filtro_avanzado_tweets_evento( evento_fluvial['datosTwitter'], evento_fluvial) self.assertLess(len(tweets_filtrados), len(evento_fluvial['datosTwitter']))
def datetime_parser(json_dict): '''Se busca cualquier campo con fechas para convertir a datetime''' for (key, value) in json_dict.items(): if isinstance(value, basestring): try: json_dict[key] = util.convertir_cadena_a_fecha( value, config.FORMATO_FECHA) except (ValueError, AttributeError): pass return json_dict
def crear_medida_saih(self, id_estacion, codigo_variable, fecha, valor): if not valor: raise ValueError('El valor de la medida esta vacio') try: fecha_utc = util.convertir_a_utc(fecha, cfg.FORMATO_FECHA) valor_convertido = float(valor) return Medida({ 'idEstacion': id_estacion, 'codigoVariable': codigo_variable, 'fecha': util.convertir_fecha_a_cadena(fecha_utc, cfg.FORMATO_FECHA), 'valor': valor_convertido }) except ValueError as verr: raise ValueError('Valores imposibles de convertir. {0}'.format( verr.message))
def insertar_ejecucion(cliente_mongo, ejecucion_ok, nombre_operacional): try: fecha_actual = util.fecha_actual(cfg.FORMATO_FECHA) ejecucion = { 'fecha': fecha_actual, 'estado': ejecucion_ok, 'tipo': nombre_operacional } return cliente_mongo.ejecuciones.insert_one(ejecucion) except PyMongoError as pyerr: raise PyMongoError( u'Error insertando datos de la ejecución en BD (pymongo). {0}'. format(pyerr.message))
def destino_descarga(self, ruta_descarga, id_estacion): fecha_y_hora = util.fecha_actual_str("%d-%m-%Y_%H_%M") nombre_fichero = "{0}_{1}.{2}".format( id_estacion, fecha_y_hora, self.cfg_proveedor.FORMATO_FICHERO_DATOS) if not os.path.exists(ruta_descarga): try: os.mkdir(ruta_descarga) except OSError as oserr: raise OSError(u'Error creando carpeta. {0}'.format( oserr.strerror)) ruta_local = os.path.join(ruta_descarga, nombre_fichero) return ruta_local
def extraer_medida_de_csv(self, id_estacion, codigo_variable, ruta_fichero): try: with open(ruta_fichero, 'rb') as fichero: fila_ultima_medida = self.leer_csv_reverse(fichero) fecha_formateada = util.cambiar_formato_fecha( fila_ultima_medida[0], self.cfg_proveedor.FORMATO_FECHA) nueva_medida = self.crear_medida_saih(id_estacion, codigo_variable, fecha_formateada, fila_ultima_medida[1]) fichero.close() return nueva_medida except IOError: raise IOError('Error leyendo fichero csv')
def test_pide_json_con_datos(self): tipo_costero = self.repo_tipos_evento.obtener_tipo_evento_costero() estacion_test = self.__obtener_estacion_aleatoria_de_un_tipo( tipo_costero) variable_deteccion = self.repo_variables.obtener_variable_por_nombre( self.Boyas.cfg_proveedor.VARIABLE_DETECCION) variable_estacion = util.filtrar_lista(estacion_test['variables'], 'codigo', variable_deteccion['codigo']) datos_json = self.Boyas.descargar_json_con_datos( variable_estacion['signal'], 1) self.assertIsNotNone(datos_json, 'La descarga del html de la url ha fallado.')
def crear_evento(self, id_estacion, cod_tipo, toponimos): try: nuevo_evento = Evento({ 'fechaInicio' : util.fecha_actual_str(self.cfg.FORMATO_FECHA), 'fechaFin': None, 'codigoTipo' : cod_tipo, 'idEstacion' : id_estacion, 'activo': True, 'toponimos': toponimos, 'datosAemet': [], 'datosPuertos':[], 'datosConfederaciones':[], 'datosTwitter':[] }) return nuevo_evento except AttributeError as aterr: raise AttributeError(u'Error creando nuevo evento. {0}'.format(aterr.message))
def test_lanza_excepcion_en_error_peticion(self): estacion_test = self.__obtener_estacion_aleatoria_del_proveedor() variable_deteccion = self.repo_variables.obtener_variable_por_nombre( self.Chsil.cfg_proveedor.VARIABLE_DETECCION) variable_estacion = util.filtrar_lista(estacion_test['variables'], 'codigo', variable_deteccion['codigo']) self.Chsil.cfg_proveedor.URL = self.Chsil.cfg_proveedor.URL.replace( '.php', '.com') parametros = self.Chsil.crear_parametros_peticion( variable_estacion['signal']) with self.assertRaises(IOError): self.Chsil.hacer_peticion_http(parametros) self.Chsil.cfg_proveedor.URL = self.Chsil.cfg_proveedor.URL.replace( '.com', '.php') #volver a poner bien la url del proveedor
def obtener_evento_en_estacion(self, estacion, cod_tipo): '''Devuelve el evento activo en la estacion o None si no hay ninguno''' eventos_activos = self.repo_eventos.obtener_eventos_activos_de_tipo(cod_tipo) return util.filtrar_lista(eventos_activos, 'idEstacion', estacion['id'])