
FUNCTION_BLOCK FB60

VAR_TEMP
    // variables temporaires
    i: INT;
    temp: INT;
END_VAR
VAR
    stock: ARRAY[1..16] OF BOOL;
    stockTimer: ARRAY[1..16] OF INT;
    stockEtat: ARRAY[1..16] OF INT;
    slotLibreNum: int;
    plusVieux: INT;
    slotLibre: BOOL;
    vide: BOOL;
    decantFini: BOOL;
    preAlarme: BOOL;
    alarme: BOOL;
    reset: BOOL;
    resetNb: INT;
    resetTime: INT;
    
    tempsDecant: int := 180; //temps en seconde de décantation
    tempsPreAlarme: INT := 240; //temps en seconde pour la demande d'une palette vide
    tempsAlarme: INT:= 500; // temps en seconde limite de décantation
END_VAR

    //gestion tempo => voir FC60 via OB32
     
    //gestion slot libre
    slotLibre:= false;
    FOR i:= 1 TO 16 DO
        IF NOT stock[i] THEN
            slotLibre:= True; // renvois slot libre
            slotLibreNum:= i; // renvois le numéro le plus haut pour le slot libre
        END_IF;
    END_FOR; // renvois si il existe un slot libre et le plus haut numéro libre
    
    //gestion vide
    vide:= true;
    FOR i:= 1 TO 16 DO
        IF stock[i] THEN
            vide:= false;
        END_IF;
    END_FOR;
    
    
    //gestion decantation
    decantFini := false;
    FOR i:= 1 TO 16 DO
        IF stockTimer[i] > tempsDecant AND stockTimer[i] < tempsAlarme THEN
            decantFini:= true;
        END_IF;
    END_FOR; // indique quand le temps de décantation est terminer qque part
    
    //gestion plus vieux
    plusVieux:=16;
    FOR i:= 1 TO 16 DO
        IF stockTimer[i] > stockTimer[plusVieux] AND stockTimer[i] < tempsAlarme THEN
            plusVieux:= i;
        END_IF;
    END_FOR; // renvois qui est le plus ancien en décantation

    //gestion preAlarme
    preAlarme := false;
    FOR i:= 1 TO 16 DO
        IF stockTimer[i] > tempsPreAlarme AND stockTimer[i] < tempsAlarme THEN
            preAlarme:= true;
        END_IF;
    END_FOR; // gère la première alarme

    //gestion alarme
    alarme:= false;
    FOR i:= 1 TO 16 DO
        IF stockTimer[i] > tempsAlarme THEN
            alarme:= true;
        END_IF;
    END_FOR; // alarme ultime pour indiquer q'une zone a dépasser le délai
    
    //gestion etat pour HMI
    FOR i:= 1 TO 16 DO
        IF stockTimer[i] < 1 THEN
            stockEtat[i]:= 0;
        ELSIF stockTimer[i] < tempsDecant THEN
            stockEtat[i]:= 1;
        ELSIF stockTimer[i] < tempsPreAlarme THEN
            stockEtat[i]:= 2;
        ELSIF stockTimer[i] < tempsAlarme THEN
            stockEtat[i]:= 3;
        ELSE 
            stockEtat[i]:= 4;
        END_IF;
    END_FOR;
    
    //gestion reset
    IF reset AND resetNb < 17 AND resetNb >0 THEN
        stock[resetNb]:= false;
        reset:= false;
        resetNb:= 0;
    END_IF;
    IF resetNb < 17 AND resetNb >0 THEN
        resetTime := stockTimer[resetNb];
    END_IF;
    
    //vérifiction timer
    IF tempsAlarme < tempsPreAlarme THEN
        temp:= tempsAlarme;
        tempsAlarme:= tempsPreAlarme;
        tempsPreAlarme:= temp;
    END_IF;
    IF tempsPreAlarme < tempsDecant THEN
        temp:= tempsDecant;
        tempsDecant:= tempsPreAlarme;
        tempsPreAlarme:= temp;
    END_IF;

    
END_FUNCTION_BLOCK
