U
    ^¨jî|  ã                   @   sè   d dl mZ d dlmZ d dlmZ d dlmZ d dlmZ ddlm	Z	 ddl
mZ ed	ƒZed
 ZG dd„ dƒZeƒ Zd$dd„Zd%dd„Zd&dd„Zd dlmZ dd„ Zd'eeedœdd„Zd(eedœdd„Zd)d d!„Zd*d"d#„ZdS )+é    )ÚMongoClient)Úpprint)Údefaultdict)Úpformat)Ú	timedeltaé   )Úget_latest_comap_data)Úgenerator_is_onzmongodb://localhost:27017Z	NANOOX_TSc                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚSimpleLoggerc                 C   s   t d|› �ƒ d S )Nz[INFO] ©Úprint©ÚselfÚmsg© r   ú1/var/www/itgmanager/itgmanager/nanoox/get_data.pyÚinfo   s    zSimpleLogger.infoc                 C   s   t d|› �ƒ d S )Nz
[WARNING] r   r   r   r   r   Úwarning   s    zSimpleLogger.warningc                 C   s   t d|› �ƒ d S )Nz[ERROR] r   r   r   r   r   Úerror   s    zSimpleLogger.errorc                 C   s   d S ©Nr   r   r   r   r   Údebug   s    zSimpleLogger.debugN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r
      s   r
   é   c           	         s&  t |ƒ}dd|iiddiddddd	d
didgiddddddœiddddddœidddœidddddœidœddddd gid!gid"œiiid#d$d$d%œid&d'd(ddd)igiiig}t| d* j|d+d,�ƒ}tƒ }g }d-}|D ]J‰ t‡ fd.d/„|D ƒƒ}||krúqÖ| |¡ | ˆ ¡ t|ƒ|krÖ �q"qÖ|S )0u`  
    VersiÃ³n con eliminaciÃ³n de duplicados que respeta EXACTAMENTE el mismo orden
    que `original_get_tail_historial_control`:
    - Primero se ordenan todos los logs por _log_ts desc, _id desc (en Mongo).
    - Luego se recorre en Python y se van tomando solo los logs Ãºnicos
      segÃºn (ubicacion, fecha, accion), hasta tener n elementos.
    ú$matchÚ	centro_idú$unwindú$logsú$setÚ_log_tsú$letú$logs.timestampú$eqú$typeÚdateú$convertN©ÚinputÚtoÚonErrorÚonNullú$dateFromStringú$replaceAllú$trimú$logs.fechaú[]©r(   Úcharsú - Ú ©r(   ÚfindÚreplacementú%Y/%m/%d %H:%M:%SúAmerica/Santiago©Z
dateStringÚformatÚtimezoner*   r+   ©ÚtsZ
ts_is_dateZ
ts_to_dateZparsed_fechaú$ifNullú$condú$$ts_is_dateú$$tsú$$ts_to_dateú$$parsed_fecha©ÚvarsÚinú$sortéÿÿÿÿ©r    Ú_idú$replaceRootÚnewRootú$mergeObjectsú$_log_tsÚhistorial_controlT©ÚallowDiskUse)Z	ubicacionÚfechaZaccionc                 3   s   | ]}ˆ   |¡V  qd S r   ©Úget)Ú.0Úf©Úlogr   r   Ú	<genexpr>j   s     z-get_tail_historial_control.<locals>.<genexpr>)ÚintÚlistÚ	aggregateÚsetÚtupleÚaddÚappendÚlen)	ÚdbÚ	center_idÚnÚpipelineZall_logsÚseenÚresultZfields_for_keyÚkeyr   rX   r   Úget_tail_historial_control$   sj    
üþ
ýÿõÿôþÿãÿÿ(Ó1

rj   Nc           
      C   s¢   |si S t  ¡ tdd� }|d|idd|ii}|r:||d< d|iddd	iid
d|› �ddidœig}i }| j|dd�D ]&}|d }	d|	kr�|	d= |	||d < qv|S )Né   ©Údaysú$inÚ	timestampú$gter   r   rH   rI   ú$groupú$z$firstz$$ROOT)rK   Ú
latest_docTrQ   rs   rK   )ÚdatetimeÚnowr   r]   )
Ú
collectionZid_field_nameZid_listr   Úfecha_limiteZmatch_stagerf   ÚresultsÚdocÚdatar   r   r   Úget_last_state_bulkx   s0      ý
þý	 r{   c           2   
      s&  |  d¡\}}}t| |ƒ‰ g ‰g ‰‡ ‡‡fdd„}�zžzt| |ƒ‰W n tk
r\   g ‰Y nX | |› d� }| |› d� }| |› d� }| |› d� }	t|rª| d|i¡n| ¡ ƒ}
g }g }i }|
D ]H}| d	¡}|||< | d
¡dkrô| |¡ qÄ| d
¡dkrÄ| |¡ qÄt|d||ƒ}t|	d||ƒ}i }|�rFt	| ||ddd�}| |› d� }| |› d� }t| d|i¡ƒ}dd„ |D ƒ}t|d|ƒ}g ‰i }i }|D ]n}| d¡}| dg ¡}| |¡}|�röˆ |¡ t
|ƒ}|d k�rî| d¡}|||< |D ]}|||< �qú�qž| d	di¡} | �s0| ddi¡} | �sftˆ  d¡ƒ}!|!�rV|ddƒW S |dd d!d"�W S i }"|  dg ¡D ]¶}#|# d¡}$| |$¡}%|%�s˜�qv|% ¡ }&|& dd#¡}'|' d$d%¡}(| |(¡})| |)¡|&d&< g |&d'< |# d'g ¡D ]<}*| |*¡}+|+�rä|+ ¡ },| |*i ¡|,d(< |&d'  |,¡ �qä|&|"|$< �qvtd)d*„ ƒ}-|" ¡ D ]b\}$}.|. d+¡}/|/d k�r„zt|. d+¡ƒ}/W n   Y �qBY nX |/|-|/ d< |-|/ d  |.¡ �qBt|- ¡ ƒ}0|0�sÄ|d,d-ƒW S |d.d/|0d0�W S  tk
�r  }1 z.td1|1jj› d2|1› �ƒ |d3d4d5d"� W Y ¢S d }1~1X Y nX d S )6NÚ-c                    s    g ˆˆˆ | |dœ}|  |¡ |S )N)ÚmodulosÚgeneradoresrP   Úgenerators_comapÚdata_statusÚdata_status_detail)Úupdate)r€   r�   ÚextraÚresponse©r   Úgenerators_latest_snaprP   r   r   Úbuild_response¤   s    ú
z*get_latest_data_ts.<locals>.build_responseÚ	_metadataÚ_estructura_logicaÚ	_sensoresÚ_cansr   rK   ÚtipoÚbombaÚcanÚbomba_idÚcan_idéh  r   ©Úsensores_collÚNÚstepÚ_metadata_generadoresÚ_generador_timeseriesc                 S   s   g | ]}|  d ¡‘qS )Úgenerator_namerT   )rV   Úgr   r   r   Ú
<listcomp>â   s     z&get_latest_data_ts.<locals>.<listcomp>Úgenerador_namer˜   Ú	quadrantsÚSTATEÚcansÚidÚ
generatorsZ
comap_onlyuR   El centro reporta generadores COMAP, pero no tiene estructura lÃ³gica de mÃ³dulos.Zsin_estructurau!   Estructura lÃ³gica no encontrada.u    Estructura lÃ³gica no encontrada)r   Ú ÚHFÚ	quadrant_Ú	generatorÚbombasÚlatest_measurementsc                   S   s   dg iS ©Nrž   r   r   r   r   r   Ú<lambda>:  ó    z$get_latest_data_ts.<locals>.<lambda>ÚmoduloZsin_datos_recientesuT   La estructura lÃ³gica existe, pero no hay datos recientes de mÃ³dulos, CAN o jaulas.ÚokzDatos del centro disponibles.)r}   z"Error en get_latest_data_ts linea z: r   u2   OcurriÃ³ un error al obtener los datos del centro.z%Error al obtener los datos del centro)Úsplitr   rj   Ú	Exceptionr\   r6   rU   ra   r{   Ú#obtener_ultimas_medidas_multisensorr	   Úfind_oneÚboolÚcopyÚreplacer   Úitemsr[   Úvaluesr   Ú__traceback__Ú	tb_lineno)2rc   r   ÚregionÚareaÚcentror‡   Úmetadata_colÚestructura_colÚsensores_ts_colÚ
can_ts_colZall_metadataÚ	bomba_idsÚcan_idsZmetadata_mapry   Údoc_idZlatest_bombas_tsZlatest_cans_tsÚmediciones_por_bombaZmetadata_gen_colZ
ts_gen_colZgeneradores_metaZ	gen_namesZlatest_gen_tsÚgenerators_by_quadrantÚgenerators_stateÚgenÚnamerœ   Úultimo_datoÚcurrent_stateÚqZestructura_cans_docZhas_comap_dataZcans_final_dataZcan_noder�   Zcan_ts_dataZ	can_finalÚhf_nameÚquadrant_nameÚgen_namer�   Zbomba_tsZbomba_finalÚmodulos_mapZcan_dataÚ	modulo_idr}   Úer   r…   r   Úget_latest_data_tsž   sì    


    ÿ




þý





 þýýrÏ   )rt   c                 C   s>   t | tƒr|  ¡ S t | tƒr | S td| › dt| ƒ› d�ƒ‚dS )ud  
    @brief Verifica si un timestamp es un objeto datetime y lo convierte a ISO 8601.

    @param timestamp Puede ser un objeto datetime o una cadena.
    @return string con el timestamp en formato ISO 8601 si es datetime.
            Si ya es string, se devuelve sin cambios.
    @throws ValueError si el timestamp no es un datetime o string vÃ¡lido.
    u    Formato de timestamp invÃ¡lido: z (ú)N)Ú
isinstancert   Ú	isoformatÚstrÚ
ValueErrorÚtype©ro   r   r   r   Úserialize_timestamp]  s
    	

r×   éd   é
   )r�   r”   r•   c                 C   sÀ   d|i}|r|  d|i¡ |  |dddddœ¡ dd¡ |¡}t|ƒ}| ¡  dd	„ |D ƒ}d
d	„ |D ƒ}	dd	„ |D ƒ}
|| d … d d |… |	| d … d d |… |
| d … d d |… dœS )Nr�   r   r   r   )rK   ÚO2ÚSO2ro   ro   rI   c                 S   s   g | ]}|  d d¡‘qS )rÚ   NrT   ©rV   ry   r   r   r   rš   �  s     z2obtener_ultimas_medidas_sensor.<locals>.<listcomp>c                 S   s   g | ]}|  d d¡‘qS )rÛ   NrT   rÜ   r   r   r   rš   ‚  s     c                 S   s   g | ]}t | d ¡ƒ‘qS rÖ   ©r×   rU   rÜ   r   r   r   rš   ƒ  s     )rÚ   rÛ   ÚTS)r‚   r6   ÚsortÚlimitr\   Úreverse)Úsensores_tsr�   r”   r•   r   ÚqueryÚcursorÚdocsÚ	O2_valuesÚ
SO2_valuesrÞ   r   r   r   Úobtener_ultimas_medidas_sensorm  s*     þ ýýýrè   )r”   r•   c           "         s®  �z`t  d¡ |}t ¡ }|jddddd�}|tdd� }	dt|ƒi||	dœdœ|d	k	r`d
|ini –}
d|
idddiidddddddd	giddd	giddd	giddd	giddd	giddd	giddd	giddd	giddœidœid d!d"d#|giiig}t| |¡ƒ}td$ƒ i }|D �]H}|d% }|d! }g }g }d	}d	}tt	|ƒƒ}|d	d	|… }d&‰ |D ]v}t
|d ƒ}| d'¡}| d(¡}|d	k	�r¦||k�r¦| ||d)œ¡ |}|d	k	�rZ||k�rZ| ||d)œ¡ |}�qZ‡ fd*d+„|D ƒ}‡ fd,d+„|D ƒ}d-d+„ |D ƒ}‡ fd.d+„|D ƒ}d/d+„ |D ƒ}d0d+„ |D ƒ} d1d+„ |D ƒ}|||||||| d2œ||< �q|W S  tk
�r¨ }! z&t  d3|!› d4|!jj› �¡ i  W Y ¢S d	}!~!X Y nX d	S )5uÄ   
    Devuelve un dict con key=bomba_id y value={
        "O2": [...], "SO2": [...], "TS": [...]
    },
    todas las arrays ya ordenadas de mÃ¡s antiguo a mÃ¡s nuevo y muestreadas con `step`.
    z&en obtener_ultimas_medidas_multisensorr   )ÚhourÚminuteÚsecondÚmicrosecondr   rl   rn   )rp   z$lt)r�   ro   Nr   r   rH   ro   rI   rq   z	$bomba_idz$pushz$O2z$SO2r?   z$O2_bckpz	$SO2_bckpz$Inyecting_O2z$TEMPz
$TEMP_bckpz	$SetPointz$SetPointOFFz$alarmsz
$timestamp)rÚ   rÛ   Ú	O2_backupÚ
SO2_backupÚInyecting_O2ÚTempÚTemp_backupÚSetPointÚSetPointOFFÚalarmsro   )rK   rå   z$projectrå   z$slicez$docsZRAWrK   Frò   ró   )ÚvalueÚtimec                    s(   g | ] }|rˆ r|  d ¡n|  d¡‘qS )rí   rÚ   rT   ©rV   Úd©Z
use_backupr   r   rš   ú  s      z7obtener_ultimas_medidas_multisensor.<locals>.<listcomp>c                    s(   g | ] }|rˆ r|  d ¡n|  d¡‘qS )rî   rÛ   rT   r÷   rù   r   r   rš   û  s      c                 S   s   g | ]}|rt | d ¡ƒ‘qS rÖ   rÝ   r÷   r   r   r   rš   ü  s      c                    s(   g | ] }|rˆ r|  d ¡n|  d¡‘qS )rñ   rð   rT   r÷   rù   r   r   rš   ý  s      c                 S   s   g | ]}|r|  d ¡‘qS ©rï   rT   r÷   r   r   r   rš   þ  s      c                 S   s   g | ]}|r|  d ¡‘qS )rô   rT   r÷   r   r   r   rš      s      c                 S   s   g | ]}|d  ‘qS rú   r   r÷   r   r   r   rš     s     )rÚ   rÛ   rð   rÞ   rï   ZDataSetPointZDataSetPointOFFrô   úError ú en )Úloggerr   rt   ru   r²   r   r\   r]   r   Úreversedr×   rU   ra   r­   r   rµ   r¶   )"rc   r¾   r“   r”   r•   r   râ   ÚahoraÚ
inicio_hoyÚinicio_mananaÚmatchrf   ÚrawÚ	resultadoÚgrupor�   rå   Zsetpoint_valuesZsetpointoff_valuesZ
last_sp_onZlast_sp_offÚdocs_ascZdocs_asc_stepry   r>   Zsp_onZsp_offZO2_valsZSO2_valsZTS_valsZ	temp_valsZinyect_valsrô   rÎ   r   rù   r   r®   �  sš    

üû	








òþ 
þê


ør®   c           4   
   C   sü  |  d¡\}}}�z zt| |ƒ}tdƒ W n> tk
rh } z td|› d|jj› �ƒ g }W 5 d }~X Y nX |› d�}|› d�}|› d�}	|› d�}
| | }| | }| |	 }	| |
 }
i }i }d	d
„ | ddiddi¡D ƒ}td|›�ƒ t| ||	ddd�}| ¡ D ]Ö}d|k�r�q | d¡}| d¡}|dk�r�| |i ¡}d|i}|�rX| 	d|i¡ |	j
|dgd�}| 	d|i¡ | d¡ |�rÔ|||< nD|dk�r d|i}|�r¶| 	d|i¡ |
j
|dgd�}|�r |||< �q �z&|› d�}|› d�}| | }| | }g }i }i }t| d|i¡ƒ}g }|D ]Ö}| d¡}| dg ¡} |j
d|idgd�}!|!d= | |!¡ | ||| |!dœ¡ | D ]}"|||"< �q||!�r&|! d¡}#d |!k�rî|! d d!¡}$td"|$›�ƒ |$�rÚtd#d$„ |$D ƒƒ}%nd }%td%|%›�ƒ n|#}%|%||< �q&W n< tk
�r< } ztd|› d&|jj› �ƒ W 5 d }~X Y nX | 
dd'i¡}&|&�sXW d(S |& d'g ¡D ]Æ}'|' d¡}(|(|k�r€�qd| ¡ d)k�r¨td*d+d,›d*�ƒ t|ƒ ||( })|) d¡}*|* d-d.¡}+| |+¡},| |,¡}-|-||( d/< g ||( d0< |' d0g ¡D ](}.| |.¡}/|/�rþ||( d0  |/¡ �qþ�qdtd1d2„ ƒ}0| ¡ D ]X\}(}'t|' d3¡ƒ}1|1d k�rd�q@|' ¡ }2|2 dd ¡ |1|0|1 d4< |0|1 d'  |2¡ �q@t|0 ¡ ƒ||d5œ}3|3W S  tk
�rö } z$td6|jj› d7|› �ƒ g  W Y ¢S d }~X Y nX d S )8Nr|   zHistorial de control obtenidorû   z% obteniendo histiorial de control en rˆ   r‰   rŠ   r‹   c                 S   s   g | ]}|d  ‘qS )rK   r   rÜ   r   r   r   rš   =  s     z-legacy_get_latest_data_ts.<locals>.<listcomp>rŒ   r�   rK   r   zbombas_ids=r‘   r’   r�   r   )ro   rI   )rß   r¦   rŽ   r�   r–   r—   r˜   rœ   r›   )r   r˜   rœ   Zultimo_estador�   Údigital_outputs_stater¡   zdigital_outputs_state=c                 s   s   | ]}|d kV  qdS )Ú1Nr   )rV   Úcr   r   r   rZ   µ  s     z,legacy_get_latest_data_ts.<locals>.<genexpr>zcurrent_state=rü   rž   u4   No se encontrÃ³ la estructura lÃ³gica con _id='cans'Z	puntacolaÚ
z generators_state z*^60r¢   r£   r¤   r¥   c                   S   s   dg iS r§   r   r   r   r   r   r¨     r©   z+legacy_get_latest_data_ts.<locals>.<lambda>rª   rŸ   )r}   r~   rP   zError en linea r4   )r¬   rj   r   r­   rµ   r¶   r6   r®   rU   r‚   r¯   Úpopr\   ra   ÚallÚlowerr   r²   r   r³   r[   r±   r´   )4rc   r   r·   r¸   r¹   rP   rÎ   rº   r»   râ   Zcan_tsZbombas_dataZ	cans_dataZ
bombas_idsrÁ   ry   rŒ   rK   Zlatest_measurementrã   Zlast_bomb_datar>   Úmetadata_col_nameZts_col_nameZts_colr  rÂ   rÃ   r~   r†   rÄ   r˜   rœ   rÆ   ZquadrantZ	state_rawr  rÇ   Zestructura_cansrŽ   r�   Zcorresponding_can_datarÉ   rÊ   Zcorresponding_generatorZcorresponding_generator_stater�   r�   rÌ   rÍ   Zcan_objZlatest_data_dictr   r   r   Úlegacy_get_latest_data_ts  sþ    




ú



 


 


þ
ü

*








ýr  c                 C   sÊ   t |ƒ}dd|iiddiddddd	d
didgidddd d dœiddddddœidddœiddd d dœidœdddddgid gid!œiiid"d#d#d$œid%|id&d'd(ddd)igiiig}t| d* j|d+d,�ƒS )-Nr   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r,   r-   r.   r/   r0   r1   r3   r4   r5   r8   r9   r:   r=   r?   r@   rA   rB   rC   rD   rE   rH   rI   rJ   z$limitrL   rM   rN   rO   rP   TrQ   )r[   r\   r]   )rc   rd   re   rf   r   r   r   Ú"legacy__get_tail_historial_control0  sT    
üþ
ýÿõÿôþÿãÿÿ(Ó0r  )r   )N)N)rØ   rÙ   N)rØ   rÙ   N)N)r   )Úpymongor   r   Úcollectionsr   r   rt   r   Ú
comap_datar   Úgenerator_outputsr	   Úclientrc   r
   rý   rj   r{   rÏ   r×   r[   rè   r®   r  r  r   r   r   r   Ú<module>   s:   
T
&
 >%   ùú 
  