U
    ^¨jº  ã                   @   sT   d Z dZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )a•  
Semantica de las salidas digitales del generador (FSM NANOOX).

El controlador publica `digital_outputs_state` como un string de bits, y
`control_generator_back` como el modo de control por falla:

- False -> la misma orden de marcha va a todas las salidas configuradas
  ("00"/"11" con dos salidas, "000"/"111" con tres).
- True  -> Q1 (linea principal) y Q3 (respaldo) se reparten la orden, asi que
  aparecen patrones mixtos ("110", "011", "101", ...).
- Ausente -> se resuelve como False: el firmware antiguo no publica el campo y
  opera en modo todo-o-nada.

Reglas. Unica fuente de verdad, replicada en
SW_SERVICE_MANAGER_FE/src/services/Nanoox/utils/generatorOutputs.js:

    encendido     = algun bit en 1                    (independiente del modo)
    inconsistente = modo False EXPLICITO y bits mezclados

La inconsistencia NO se deriva del patron de bits en modo enclavado ni en modo
desconocido: la nube no puede enumerar de forma confiable los patrones validos
(p.ej. "101"), y declararlo produce alarmas criticas falsas.

OJO con GEN_FAULT: en los datos reales GEN_FAULT/GEN_FAULT_LATCHED valen True
exactamente cuando el generador corre en la linea de respaldo ("011", con
output_fault_state activo) y False cuando corre en la principal ("110"). Es la
senal que dispara el traspaso a respaldo, NO una alarma del generador. Tratarla
como alarma pinta en rojo justo la operacion normal que este contrato soporta.
Ztodo_o_nadaZ	enclavadoZfalla_generador_tekfishc                 C   sZ   t | tƒr| S t | tƒr(| dkr(t| ƒS t | tƒrV|  ¡  ¡ }|dkrJdS |dkrVdS dS )zINormaliza a True/False/None. None significa "el dato no permite decidir".)é    é   )ÚtrueÚ1T)ÚfalseÚ0FN)Ú
isinstanceÚboolÚintÚstrÚstripÚlower)ÚvalueÚtext© r   ú:/var/www/itgmanager/itgmanager/nanoox/generator_outputs.pyÚas_bool%   s    

r   c                 C   s4   t | tƒsdS |  ¡ }|r,tdd„ |D ƒƒr0dS |S )z7Devuelve el string de salidas si es utilizable, o None.Nc                 s   s   | ]}|d kV  qdS )Ú01Nr   )Ú.0Úcharr   r   r   Ú	<genexpr>9   s     z$normalize_outputs.<locals>.<genexpr>)r   r
   r   Úany)Údigital_outputs_stater   r   r   r   Únormalize_outputs4   s    
r   c                 C   s$   t | ƒ}|dkrtdfS t|dkfS )z?Devuelve (modo, reportado). Ausente -> (ALL_OR_NOTHING, False).TF)r   ÚINTERLOCKEDÚALL_OR_NOTHING)Úcontrol_generator_backÚflagr   r   r   Úresolve_control_mode>   s    r   c                 C   s   t | tƒot| kS )z<Los tekfish codifican `digital_outputs_state` de otra forma.)r   ÚdictÚ_TEKFISH_MARKER©Úsnapshotr   r   r   Ú
is_tekfishF   s    r"   c                 C   s   t | ƒ}|dkrdS d|kS )z;Encendido = algun bit en 1. None si no hay dato utilizable.Nr   )r   )r   Úoutputsr   r   r   Úoutputs_are_onK   s    r$   c                 C   s@   t |ƒdk	rdS t| ƒ}|dks,t|ƒdk r0dS tt|ƒƒdkS )z¤
    Solo se declara inconsistencia con control_generator_back = False explicito,
    donde el contrato garantiza que todas las salidas reciben la misma orden.
    FNé   r   )r   r   ÚlenÚset)r   r   r#   r   r   r   Úoutputs_are_inconsistentS   s    r(   c                 C   sH   t | tƒsdS t|  d¡ƒ}t| ƒr@|dkr0dS |dkr<dS dS t|ƒS )zT
    Encendido/apagado desde el snapshot completo. None si no se puede decidir.
    Nr   Ú10Tr   F)r   r   r   Úgetr"   r$   )r!   r#   r   r   r   Úgenerator_is_on`   s    
r+   c                 C   s4   t | tƒsdS |  d¡r&t|  d¡ƒS t|  d¡ƒS )zJOrden de marcha segun la FSM (MODE/ON o REMOTE_ON). None si no la reporta.NZMODEÚONZ	REMOTE_ON)r   r   r*   r   r    r   r   r   Úresolve_run_ordert   s
    

r-   N)Ú__doc__r   r   r   r   r   r   r"   r$   r(   r+   r-   r   r   r   r   Ú<module>   s   
