a
    &ìÌfÕ  ã                   @   sf   d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlZG dd„ dƒZdS )uØ  
GestiÃ³n de conexiones individuales con los medidores.

Este mÃ³dulo maneja la conexiÃ³n, comunicaciÃ³n y procesamiento de datos para cada medidor individual.

Desarrolladores:
- Para modificar el comportamiento de la conexiÃ³n, ajuste los mÃ©todos de la clase MeterConnection
- Para aÃ±adir soporte para nuevos protocolos, actualice el mÃ©todo get_protocol()
- La detecciÃ³n de anomalÃ­as se realiza en el mÃ©todo save_data(). Expanda esta lÃ³gica segÃºn sea necesario.
é    N)Údatetime)ÚIEC62056Protocol)ÚForeÚStylec                   @   s>   e Zd Zddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ ZdS )ÚMeterConnectionFé<   c                 C   s^   || _ || _|| _|| _d| _d| _|  |¡| _t 	d|› d|› �¡| _
|| _|| _|| _dS )u  
        Inicializa una conexiÃ³n de medidor.

        Args:
            host (str): DirecciÃ³n IP del medidor.
            port (int): Puerto del medidor.
            mode (str): Modo de conexiÃ³n ("client" o "server").
            meter_type (str): Tipo de protocolo del medidor.
            alert_system (AlertSystem): Sistema de alertas.
            interrogation_enabled (bool): Si se debe interrogar activamente al medidor.
            interrogation_frequency (int): Frecuencia de interrogaciÃ³n en segundos.
        NFzMeterConnection-ú:)ÚhostÚportÚmodeÚ
meter_typeÚsockÚ	connectedÚget_protocolÚprotocolÚloggingZ	getLoggerÚloggerÚalert_systemÚinterrogation_enabledÚinterrogation_frequency)Úselfr	   r
   r   r   r   r   r   © r   ú0/var/www/blue/EV-AMI-Back_02/meter_connection.pyÚ__init__   s    zMeterConnection.__init__c                 C   s   dt ƒ i}| |t ƒ ¡S )z>Selecciona el protocolo adecuado basado en el tipo de medidor.ÚIEC62056)r   Úget)r   r   Ú	protocolsr   r   r   r   /   s    ÿzMeterConnection.get_protocolc              
   C   sÆ   | j sÂzrt tjtj¡| _| j | j| jf¡ | j 	t
j› d| j› d| j› tj› �¡ d| _ | jrvtj| jdd� ¡  W q  ty¾ } z.| j | j| jt|ƒ¡ t d¡ W Y d}~q d}~0 0 q dS )u&   Establece la conexiÃ³n con el medidor.zCliente conectado a r   T)ÚtargetÚdaemoné   N)r   ÚsocketZAF_INETZSOCK_STREAMr   Úconnectr	   r
   r   Úinfor   ÚGREENr   Ú	RESET_ALLr   Ú	threadingÚThreadÚinterrogate_meterÚstartÚ	Exceptionr   Úconnection_errorÚstrÚtimeÚsleep©r   Úer   r   r   r!   7   s    (zMeterConnection.connectc              
   C   s¨   | j r¤zD| j d¡ | j tj› d| j› d| j› t	j
› �¡ t | j¡ W q  ty  } z>| j | j| jd|› �¡ d| _ | j ¡  |  ¡  W Y d}~q d}~0 0 q dS )u8   EnvÃ­a periÃ³dicamente solicitudes de estado al medidor.s   estadozEnviada solicitud de estado a r   z%Error al enviar solicitud de estado: FN)r   r   Zsendallr   r"   r   ÚCYANr	   r
   r   r$   r,   r-   r   r)   r   r*   Úcloser!   r.   r   r   r   r'   E   s    (
z!MeterConnection.interrogate_meterc              
   C   s”   z8| j  d¡}|stdƒ‚| j | d¡¡}|  |¡ W q  tyŒ } z<| j | j	| j
t|ƒ¡ d| _| j  ¡  |  ¡  W Y d}~q d}~0 0 q dS )u*   Maneja la recepciÃ³n de datos del medidor.i   u%   ConexiÃ³n cerrada por el otro extremozutf-8FN)r   Zrecvr)   r   Zprocess_messageÚdecodeÚ	save_datar   r*   r	   r
   r+   r   r1   r!   )r   ÚdataZprocessed_datar/   r   r   r   Úhandle_connectionR   s    
z!MeterConnection.handle_connectionc                 C   sÖ   t  ¡  ¡ }tj|| j› d| j› �|dœdd�}tddƒ�}| |d ¡ W d  ƒ n1 s^0    Y  | j	 
tj› d	|› tj› �¡ d
|v rÒd|d
 v rÒt|d
  d¡d  d¡d ƒdkrÒ| j | j| jd¡ dS )uŸ   
        Guarda los datos procesados en un archivo y detecta anomalÃ­as.
        
        Args:
            data (dict): Datos procesados del medidor.
        r   )Ú	timestampZmeterr4   é   )Zindentzmeter_readings.txtÚaÚ
NzDatos guardados: ZOBISz1.8.0z1.8.0(é   Ú*r   i@B u%   Consumo de energÃ­a anormalmente alto)r   ZnowZ	isoformatÚjsonÚdumpsr	   r
   ÚopenÚwriter   r"   r   r#   r   r$   ÚfloatÚsplitr   Zdata_anomaly)r   r4   r6   Z	json_dataÚfr   r   r   r3   a   s    ýü,8zMeterConnection.save_dataN)Fr   )	Ú__name__Ú
__module__Ú__qualname__r   r   r!   r'   r5   r3   r   r   r   r   r      s   
r   )Ú__doc__r    r<   r%   r,   r   r   r   Úcoloramar   r   r   r   r   r   r   r   Ú<module>   s   