
    (Jhh'                     H    S SK r S SKrS SKJrJrJr  S SKJr   " S S5      rg)    N)datetime	timedeltatimezone)DatabaseConnectionc                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)EstadoMonitor   uL   Monitorea el estado de los medidores basado en la última medición recibidac                     [        5       U l        [        [        R                  " SS5      5      U l        SU l        SU l        g )NTIEMPO_SIN_REPORTE_HORAS$         )r   dbintosgetenvtiempo_sin_reporte_horasESTADO_NORMALESTADO_FALTA_REPORTE)selfs    ;/var/www/ev-aguas/ev-aguas-proceso/models/estado_monitor.py__init__EstadoMonitor.__init__	   s8    $&(+BII6PRT,U(V% $%!    c           	      T    [         R                  " S5        [         R                  " SU R                   S35        U R                  R	                  5       (       d5  [         R
                  " S5        SSS.U R                  R                  5         $ U R                  5       nU(       d7  [         R                  " S5        S	S
S
S
S.U R                  R                  5         $ U R                  U5      n[         R                  " SUS    SUS    SUS    35        UU R                  R                  5         $ ! [         aK  n[         R
                  " SU 35        S[        U5      S.s SnAU R                  R                  5         $ SnAff = f! U R                  R                  5         f = f)u   
Función principal que actualiza los estados de todos los medidores
en la tabla tiempo_real basado en la última medición recibida
u3   Iniciando actualización de estados de medidores...z Tiempo sin reporte configurado: z horasz&No se pudo conectar a la base de datosFu%   Error de conexión a la base de datos)successerrorz*No se encontraron mediciones para procesarTr   r   medidores_procesadosmedidores_normalesmedidores_sin_reporteu'   Actualización completada. Procesados: r   z, Normales: r    z, Sin reporte: r!   u,   Error durante la actualización de estados: N)logginginfor   r   connectr   
disconnect_obtener_ultimas_medicioneswarning_procesar_y_actualizar_estados	Exceptionstr)r   ultimas_mediciones	resultadoes       r   actualizar_estados_medidores*EstadoMonitor.actualizar_estados_medidores   s   
(	!LLNPLL;D<Y<Y;ZZ`ab 77??$$FG$DB GG 7 "&!A!A!C% LM#,-*+-.	. GG  ;;<NOILLB9McCdBe f%%./C%D$E F((12I(J'KM N  GG   	MMHLM Q 
 GG 	 GG s<   A3D3 3D3 :D3 3
F=&F#F$F FF F'c                 ~    U R                   R                  5       nSnUR                  U5        UR                  5       n[        R
                  " S[        U5       S35        / nU H!  nUR                  US   US   US   S.5        M#     U$ ! [         a%  n[        R                  " SU 35        / s S	nA$ S	nAff = f)
uU   
Obtiene la última medición de cada medidor (la más reciente por fecha_recepcion)
ai  
                SELECT 
                    m1.idMedidor,
                    m1.fecha_recepcion,
                    med.nombre as nombre_medidor
                FROM mediciones m1
                INNER JOIN medidores med ON m1.idMedidor = med.idMedidor
                INNER JOIN (
                    SELECT idMedidor, MAX(fecha_recepcion) as max_fecha
                    FROM mediciones
                    GROUP BY idMedidor
                ) m2 ON m1.idMedidor = m2.idMedidor AND m1.fecha_recepcion = m2.max_fecha
                WHERE med.deleted_at IS NULL
                ORDER BY m1.idMedidor
            zSe encontraron z medidores con medicionesr      r   )	idMedidorfecha_recepcionnombre_medidoru&   Error obteniendo últimas mediciones: N)
r   
get_cursorexecutefetchallr"   r#   lenappendr)   r   )r   cursorquery
resultadosr+   rowr-   s          r   r&   )EstadoMonitor._obtener_ultimas_medicionesA   s    &	WW'')FE  NN5!*JLL?3z?*;;TUV "$!"))!$Q'*1v&)!f+  " &% 	MMB1#FGI	s   B
B 
B<B71B<7B<c                    SnSnSn[         R                  " [        [        SS95      5      nU[        U R                  S9-
  n[
        R                  " SU 35        [
        R                  " SU 35         U R                  R                  5       nU H  nUS   n	US   n
US   nU
R                  c  U
R                  [        [        SS95      S
9n
X:  a  U R                  nUS-  nSnOU R                  nUS-  nSnXZ-
  R                  5       S-  n[
        R                  " SU SU	 SU
 SUS SU 3
5        U R                  XyU5        US-  nM     U R                  R!                  5         [
        R                  " S5        SUUUS.$ ! ["         a:  nU R                  R%                  5         [
        R&                  " SU 35        UeS	nAff = f)zD
Procesa cada medidor y actualiza su estado en la tabla tiempo_real
r   )hourszFecha actual: u%   Límite para considerar sin reporte: r2   r3   r4   N)tzinfor1   NormalzFalta Reportei  zMedidor z (ID: u   ): Última medición: z, Horas transcurridas: z.1fz, Nuevo estado: z8Todos los cambios fueron confirmados en la base de datosTr   z.Error procesando estados, rollback realizado: )r   nowr   r   r   r"   r#   r   r5   rB   replacer   r   total_secondsdebug_actualizar_estado_medidorcommitr)   rollbackr   )r   r+   r   r    r!   ahoralimite_tiempor:   medicion
id_medidorr3   r4   nuevo_estadoestado_deschoras_desde_medicionr-   s                   r   r(   ,EstadoMonitor._procesar_y_actualizar_estadosm   s     ! ! Xib&9:;	0M0M NN~eW-.<]OLM2	WW'')F.%k2
"*+<"=!)*:!; #))1&5&=&=Xi^`NaEb&=&cO #3#'#5#5L&!+&"*K#'#<#<L)Q.)"1K ).(?'N'N'PSW'W$(8zl K22A1B C44H3M N--8M; < //LQ$)$= /B GGNNLLST  (<&8)>	   	GGMMJ1#NOG		s   6DF	 	
G5GGc                     SnUR                  XB45        UR                  5       S   S:  nU(       a2  SnUR                  XcU45        [        R                  " SU SU 35        g
SnUR                  XrU45        [        R                  " SU SU 35        g
! [         a#  n[        R
                  " SU S	U 35        UeS
nAff = f)uG   
Actualiza el estado de un medidor específico en la tabla tiempo_real
z5SELECT COUNT(*) FROM tiempo_real WHERE idMedidor = %sr   z
                    UPDATE tiempo_real 
                    SET estado = %s 
                    WHERE idMedidor = %s
                z#Estado actualizado para medidor ID z: estado = a8  
                    INSERT INTO tiempo_real 
                    (idMedidor, lastReporte, estado, latitud, longitud, 
                     acumulado, diario, rssi, temperatura, cumulFlowUnit, dailyFlowUnit)
                    VALUES 
                    (%s, NOW(), %s, 0, 0, 0, 0, 0, 0, 0, 0)
                z5Nuevo registro creado en tiempo_real para medidor ID z&Error actualizando estado del medidor z: N)r6   fetchoner"   rG   r)   r   )	r   r:   rN   rO   query_checkexistequery_updatequery_insertr-   s	            r   rH   (EstadoMonitor._actualizar_estado_medidor   s    	QKNN;6__&q)A-F 
 |J-GH CJ<{[gZhij  |,-GH UV`Uaalmylz{| 	MMB:,bQRPSTUG	s   A"B %1B 
C!B??Cc                 (    U R                   R                  5       (       d   U R                   R                  5         gU R                   R                  5       nSnUR	                  U5        UR                  5       n0 nU H  nUS   XES   '   M     UU R                   R                  5         $ ! [         a=  n[        R                  " SU 35         SnAU R                   R                  5         gSnAff = f! U R                   R                  5         f = f)z=
Obtiene un resumen del estado actual de todos los medidores
Na  
                SELECT 
                    e.nombre as estado_nombre,
                    COUNT(*) as cantidad
                FROM tiempo_real tr
                INNER JOIN estados e ON tr.estado = e.idEstado
                INNER JOIN medidores med ON tr.idMedidor = med.idMedidor
                WHERE med.deleted_at IS NULL
                GROUP BY tr.estado, e.nombre
                ORDER BY tr.estado
            r1   r   z%Error obteniendo resumen de estados: )	r   r$   r%   r5   r6   r7   r)   r"   r   )r   r:   r;   r<   resumenr=   r-   s          r   obtener_resumen_estados%EstadoMonitor.obtener_resumen_estados   s    	!77??$$: GG 7 WW'')F
E NN5!*JG!"%a&A "  GG 	  	MMA!EFGG 		 GG s/   B+ AB+ +
C25C-C5 -C22C5 5D)r   r   r   r   N)__name__
__module____qualname____firstlineno____doc__r   r.   r&   r(   rH   r\   __static_attributes__ r   r   r   r      s(    V&-!^*XAF!F#!r   r   )r"   r   r   r   r   database.connectionr   r   rd   r   r   <module>rf      s      	 2 2 2p! p!r   