Lo stato del monitoraggio cambia in base alla durata del tempo in stato

5

Ho creato un sistema di monitoraggio che controlla se un dispositivo è allarmato o meno e, in caso affermativo, invia notifiche agli utenti pertinenti in base a quanto tempo un dispositivo si trova in uno stato particolare. Ecco un esempio dei criteri che sto costruendo intorno:

1.) Se un dispositivo ha precedentemente operato in uno stato non in allarme per più di un'ora in precedenza

  • a.) Se il dispositivo è stato allarmato per più di 15 minuti, comunica agli utenti del livello 1

  • b) Se il dispositivo è stato allarmato per più di 24 ore, notifica agli utenti di livello 2

2.) Se un dispositivo ha raggiunto uno stato di allarme di livello uno

  • a.) Se un dispositivo ha funzionato attualmente in uno stato non in allarme per più di un'ora, notifica a tutti gli utenti pertinenti

Per costruire questo sistema ho dovuto creare un sacco di logica condizionale nidificata e tenere traccia delle modifiche di stato in una cache che ho impostato. Il mio server ottiene continuamente nuovi dati su un gruppo di dispositivi e gestisce i loro stati attraverso la logica di allarme. Il problema è che questo sistema è molto fragile e ogni cambiamento che faccio alla logica di uno stato influenza gli altri perché sono intrecciati. Per esempio:.

var deviceState = {...}; // cachedData

if (deviceState.hasOperatedWithoutAlarmForHour === true) {
    if (currentStatus === 'ALARMED') {
        if (deviceState.previousStatus !== 'ALARMED') {
            deviceState.hasSentLevelOneNotice = false;
            deviceState.hasSentLevelTwoNotice = false;
            deviceState.alarmStateStartTime = new Date();
        }
        else if (
            deviceState.hasSentLevelOneNotice === false
            && (currentTime - deviceState.alarmStateStartTime) > 15_MINUTES_CONSTANT)
        ) {
            sendLevelOneNotice();
            deviceState.hasSentLevelOneNotice = true;
        }
        ...
    }
}
else {
    if (deviceState.previousStatus === 'ALARMED') {
        deviceState.hasOperatedWithoutAlarmForHour = false;
        deviceState.noAlarmStartTime = new Date();
        deviceState.hasSentAllClearNotice = false;
    }
    else {
        if (
            deviceState.hasSentAllClearNotice === false
            && (currentTime - deviceState.noAlarmStartTime) > ONE_HOUR_CONSTANT
            && deviceState.hasSentLevelOneNotice === true
        ) {
            sendAllClearNotice();
            deviceState.hasSentAllClearNotice = true;
        }
        ...
    }
}

Esiste un modo migliore per costruire un sistema di monitoraggio basato sullo stato che tenga traccia della durata in un determinato stato?

    
posta Copernicus 07.02.2017 - 22:47
fonte

2 risposte

2

Potrei progettare questo sistema per trarre vantaggio da una sorta di stato persistente, visto come funziona nel corso di molte ore, se non giorni. Ciò consentirebbe l'uscita e il rientro dell'applicazione senza influire sul suo modo di agire.

Per abilitare tale funzionalità, potrebbe essere sufficiente quanto segue:

  • Stato dispositivo (al momento del controllo), insieme alla data / ora UTC
  • Azione intrapresa (utente notificato, insieme al motivo: errore / recupero), insieme al timestamp UTC

Quindi scriverò più query per determinare quale azione futura dovrei prendere per ogni dato dispositivo, prendere quell'azione e registrare l'azione di conseguenza. La registrazione dell'azione modifica il risultato della query e indica che l'azione non è più necessaria.

Le tue query e l'azione determinata si associano come segue:

  • Per determinare required notifications for level 1 users trovare tutti i dispositivi in cui latest alarm time è maggiore di latest level 1 notification time e maggiore di latest non-alarmed time + 15 minutes .

  • Per determinare required notifications for level 2 users trovare tutti i dispositivi in cui latest alarm time è maggiore di latest level 2 notification time e maggiore di latest non-alarmed time + 24 hours .

  • Per determinare required notifications for non-alarm status trovare tutti i dispositivi in cui l'ultimo non-alarm time è maggiore dell'ultimo non-alarm notification + 1 hour

Invia le notifiche e registrati di conseguenza. Ripeti tutte le volte che è utile per accordi sul livello di servizio.

    
risposta data 08.02.2017 - 00:15
fonte
1

Ecco come intendo implementare la soluzione di Christopher. Nel mio caso particolare, ho bisogno di testare lo stato di allarme di ogni dispositivo separatamente l'uno dall'altro, quindi sto creando una serie di affermazioni condizionali che testano ogni caso d'azione. Tuttavia, ho separato ogni caso e li ho disaccoppiati l'uno dall'altro.

Nei dati dello stato della cache, sto solo memorizzando lo stato precedente più recente, i tempi di cambio di stato più recenti e i tempi di occorrenza delle azioni più recenti. Ho rimosso tutti i dati sullo stato booleano che avevo in precedenza, il che ha gonfiato l'oggetto stato e ha aumentato la complessità.

Ho separato ciascuna azione in modo che possano essere attivate separatamente e disaccoppiarle il più possibile. Alcune condizioni che sto testando sono intrinsecamente collegate tra loro, ma ho minimizzato il più possibile.

In precedenza ho usato flag booleani per tracciare se si erano verificati alcuni cambiamenti di stato. L'ho eliminato completamente, e ora tutta la logica per l'attivazione di un'azione vive completamente all'interno della logica condizionale di ciascuna azione.

// DEVICE STATE
let {
    LATEST_DEVICE_STATUS,

    LATEST_NO_ALARM_TIME,

    LATEST_ALARM_TIME,

    LATEST_LEVEL_ONE_ACTION_TIME,

    LATEST_LEVEL_TWO_ACTION_TIME,

    LATEST_ALL_CLEAR_ACTION_TIME,

} = deviceState;

const NOW = Date.now();

// MANAGE ALARM STATE

// Update the alarm state start-times whenever
// a state change occurs
if (
    CURRENT_DEVICE_STATUS === 'ALARM'
    && LATEST_DEVICE_STATUS !== 'ALARM'
) {
    LATEST_DEVICE_STATUS = 'ALARM';
    LATEST_ALARM_TIME = NOW;
}
else if (
    CURRENT_DEVICE_STATUS !== 'ALARM'
    && LATEST_DEVICE_STATUS === 'ALARM'
) {
    LATEST_DEVICE_STATUS = 'ALARM';
    LATEST_ALARM_TIME = NOW;
}

// ACTION LOGIC

// If the latest alarm has lasted for 15 minutes, send
// a level 1 notice if it hasn't been sent
if (
    LATEST_ALARM_TIME > ( LATEST_ALL_CLEAR_TIME + 15MIN )
    && LATEST_ALARM_TIME > LATEST_LEVEL_ONE_ACTION_TIME
) {
    TAKE_LEVEL_ONE_ACTION();
    LATEST_LEVEL_ONE_ACTION_TIME = NOW;
}

// If the latest alarm has lasted for 24 hours, send
// a level 2 notice if it hasn't been sent
if (
    LATEST_ALARM_TIME > ( LATEST_ALL_CLEAR_TIME + 24HR )
    && LATEST_ALARM_TIME > LATEST_LEVEL_TWO_ACTION_TIME
) {
    TAKE_LEVEL_TWO_ACTION();
    LATEST_LEVEL_TWO_ACTION_TIME = NOW;
}

// If there is no alarm, a Level 1 alarm was fired, and the
// device has had no alarm for more than an hour, send a
// notice if it has not been sent
if (
    LATEST_NO_ALARM_TIME > LATEST_ALARM_TIME
    && LATEST_TIER_ONE_ACTION_TIME > LATEST_ALARM_TIME
    && LATEST_NO_ALARM_TIME > LATEST_ALL_CLEAR_ACTION_TIME
    && NOW > (LATEST_NO_ALARM_TIME + 1HR)
) {
    TAKE_ALL_CLEAR_ACTION();
    LATEST_ALL_CLEAR_ACTION_TIME = NOW;
}
    
risposta data 08.02.2017 - 17:07
fonte

Leggi altre domande sui tag