예제 #1
0
파일: VriState.cs 프로젝트: VCDH/vve
        public VriState Clone()
        {
            VriState result = new VriState()
            {
                Valid = this.Valid, TimeRef = this.TimeRef, Delta = this.Delta, Info = this.Info
            };

            if (this.Detectors == null)
            {
                result.Detectors = null;
            }
            else
            {
                result.Detectors = new int[this.Detectors.Length];
                for (int i = 0; i < this.Detectors.Length; i++)
                {
                    result.Detectors[i] = this.Detectors[i];
                }
            }

            if (this.FcExtern == null)
            {
                result.FcExtern = null;
            }
            else
            {
                result.FcExtern = new int[this.FcExtern.Length];
                for (int i = 0; i < this.FcExtern.Length; i++)
                {
                    result.FcExtern[i] = this.FcExtern[i];
                }
            }

            if (this.Wps == null)
            {
                result.Wps = null;
            }
            else
            {
                result.Wps = new int[this.Wps.Length];
                for (int i = 0; i < this.Wps.Length; i++)
                {
                    result.Wps[i] = this.Wps[i];
                }
            }

            if (this.OverigeIs == null)
            {
                result.OverigeIs = null;
            }
            else
            {
                result.OverigeIs = new bool[this.OverigeIs.Length];
                for (int i = 0; i < this.OverigeIs.Length; i++)
                {
                    result.OverigeIs[i] = this.OverigeIs[i];
                }
            }

            if (this.OverigeUsGus == null)
            {
                result.OverigeUsGus = null;
            }
            else
            {
                result.OverigeUsGus = new bool[this.OverigeUsGus.Length];
                for (int i = 0; i < this.OverigeUsGus.Length; i++)
                {
                    result.OverigeUsGus[i] = this.OverigeUsGus[i];
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Parsed de V-Log data en indien alle benodigde informatie ontvangen is en vrij van fouten, wordt de analyse uitgevoerd.
        /// </summary>
        /// <param name="vlogBericht"></param>
        public void Process(string vlogBericht)
        {
            if (vlogBericht.Length < 2)
            {
                return;
            }

            string berichttype = vlogBericht.Substring(0, 2);

            bool error = false;
            bool errorToWaitForStatus = false;
            bool process           = false;
            bool checkDataVsConfig = false;

            if (_state == State.WaitForTimeRef &&
                berichttype == "01")
            {
                //tijdreferentie
                DateTime tijdref = VLog.Parser.DecodeTijdRef(vlogBericht);
                bool     okMsg   = (tijdref.Ticks > 0);
                if (okMsg)
                {
                    //OK
                    waitForStatusTimeRef = tijdref;
                    _state = State.WaitForStatus;
                }
                else
                {
                    //error
                    error = true;

                    addError(string.Format("Incorrect timeref message {0}", vlogBericht));
                }
            }
            else if (_state == State.WaitForStatus)
            {
                //wachten op statusbericht
                switch (berichttype)
                {
                case "01":
                {
                    //tijdreferentie ontvangen: de huidige overschrijven
                    DateTime tijdref = VLog.Parser.DecodeTijdRef(vlogBericht);
                    bool     okMsg   = (tijdref.Ticks > 0);
                    if (okMsg)
                    {
                        //OK
                        waitForStatusTimeRef = tijdref;
                        _state = State.WaitForStatus;         //in state blijven
                    }
                    else
                    {
                        //error
                        error = true;

                        addError(string.Format("Incorrect timeref message {0}", vlogBericht));
                    }
                    break;
                }

                case "04":
                {
                    VLogInfo info = VLog.Parser.DecodeInfo(vlogBericht);

                    bool okMsg = (info != null);
                    if (okMsg)
                    {
                        //OK
                        waitForStatusInfo = info;
                    }
                    else
                    {
                        //error
                        error = true;

                        addError(string.Format("Incorrect info message {0}", vlogBericht));
                    }
                    break;
                }

                case "05":
                {
                    //status detectoren ontvangen
                    int[] detectors = VLog.Parser.DecodeStatusDet(vlogBericht);
                    int   delta     = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg      = (detectors != null);   //geldig bericht
                    bool okDeltaMsg = (delta != -1);         //delta in bericht correct

                    if (okMsg &&
                        okDeltaMsg)
                    {
                        //OK
                        stateNew.TimeRef   = waitForStatusTimeRef;
                        stateNew.Delta     = delta;
                        stateNew.Info      = waitForStatusInfo;
                        waitForStatusInfo  = null;
                        stateNew.Detectors = detectors;

                        _state  = State.Active;
                        process = true;

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        addError(string.Format("Incorrect status detector message {0}", vlogBericht));
                    }
                    break;
                }

                default:
                {
                    //ander berichttype: alleen controleren op hex ascii data
                    if (!VLog.Parser.IsHexAscii(vlogBericht))
                    {
                        error = true;
                        addError(string.Format("Incorrect message {0}, geen Hex Ascii", vlogBericht));
                    }
                }
                break;
                }
            }
            else if (_state == State.Active)
            {
                switch (berichttype)
                {
                case "01":
                {
                    //tijdreferentie
                    DateTime tijdref = VLog.Parser.DecodeTijdRef(vlogBericht);

                    bool okMsg        = (tijdref.Ticks > 0);
                    bool okMsgCorrect = (tijdref.TimeOfDay.TotalSeconds % (60 * 5) == 0 &&
                                         (tijdref - stateNew.TimeRef).TotalSeconds <= 5 * 60);       //controleren of het tijdstip op de hele 5 minuten ligt en binnen 5 minuten na de voorgaande
                    if (okMsg &&
                        okMsgCorrect)
                    {
                        //OK
                        stateNew.TimeRef = tijdref;
                        stateNew.Delta   = 0;
                        process          = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect timeref message {0}", vlogBericht));
                        }
                        else if (!okMsgCorrect)
                        {
                            //gat in de data of tijd gewijzigd. Deze tijdref wel als nieuwe start zien.
                            waitForStatusTimeRef = tijdref;
                            errorToWaitForStatus = true;

                            addError(string.Format("Unexpected timeref {0} received after last timeref {1} (time changed or data gap), time difference: {2}", tijdref.ToString("yyyy-MM-dd HH:mm:ss.f"), stateNew.TimeRef.ToString("yyyy-MM-dd HH:mm:ss.f"), (tijdref - stateCurrent.Time).TotalSeconds.ToString("F1")));
                        }
                    }
                    break;
                }

                case "04":
                {
                    VLogInfo info = VLog.Parser.DecodeInfo(vlogBericht);

                    bool okMsg      = (info != null);
                    bool okNoChange = (stateNew.Info == null || info == null || (stateNew.Info.VLogVersie == info.VLogVersie && stateNew.Info.VriId == info.VriId));
                    if (okMsg && okNoChange)
                    {
                        //OK
                        if (stateNew.Info == null)
                        {
                            stateNew.Info = info;
                        }

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect info message {0}", vlogBericht));
                        }
                        else if (!okNoChange)
                        {
                            addError(string.Format("Content of info message changed {0}", vlogBericht));
                        }
                    }
                    break;
                }

                case "05":
                {
                    //status detectie
                    int[] detectors = VLog.Parser.DecodeStatusDet(vlogBericht);
                    int   delta     = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg          = (detectors != null);                                                                                //geldig bericht
                    bool okLength       = (stateNew.Detectors == null || detectors == null || detectors.Length == stateNew.Detectors.Length); //aantal detectoren gelijk
                    bool okDeltaMsg     = (delta != -1);                                                                                      //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta);                                                                          //delta gelijk aan of groter dan voorgaande

                    if (okMsg &&
                        okLength &&
                        okDeltaMsg &&
                        okDeltaCorrect)
                    {
                        //OK
                        stateNew.Delta     = delta;
                        stateNew.Detectors = detectors;
                        process            = true;

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect status detector message {0} (format incorrect)", vlogBericht));
                        }
                        else if (!okLength)
                        {
                            addError(string.Format("Incorrect status detector message {0} (amount of detector {1} instead of {2})", vlogBericht, detectors.Length, stateNew.Detectors.Length));
                        }
                        else if (!okDeltaMsg)
                        {
                            addError(string.Format("Incorrect status detector message {0} (delta incorrect)", vlogBericht));
                        }
                        else if (!okDeltaCorrect)
                        {
                            addError(string.Format("Incorrect status detector message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                        }
                    }
                    break;
                }

                case "06":
                {
                    //wijziging detectie
                    Change[] changes = VLog.Parser.DecodeWijzigingDet(vlogBericht);
                    int      delta   = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg          = (changes != null);         //geldig bericht
                    bool okDeltaMsg     = (delta != -1);             //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta); //delta gelijk aan of groter dan voorgaande

                    if (okMsg &&
                        okDeltaMsg &&
                        okDeltaCorrect)
                    {
                        //OK
                        stateNew.Delta = delta;
                        for (int i = 0; i < changes.Length; i++)
                        {
                            Change dc = changes[i];
                            if (dc.index >= stateNew.Detectors.Length)
                            {
                                //error: index te hoog, detector niet aanwezig in eerder ontvangen statusbericht
                                error = true;

                                addError(string.Format("Incorrect detector changed message {0} (index {1} higher than available {2} detectors)", vlogBericht, dc.index, stateNew.Detectors.Length));
                                break;
                            }
                            else
                            {
                                stateNew.Detectors[dc.index] = dc.value;
                            }
                        }
                        process = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect change detector message {0} (format incorrect)", vlogBericht));
                        }
                        else if (!okDeltaMsg)
                        {
                            addError(string.Format("Incorrect change detector message {0} (delta incorrect)", vlogBericht));
                        }
                        else if (!okDeltaCorrect)
                        {
                            addError(string.Format("Incorrect change detector message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                        }
                    }
                    break;
                }

                case "07":
                {
                    //status ingangssignalen
                    bool[] overigeIs = VLog.Parser.DecodeStatusIs(vlogBericht);
                    int    delta     = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg          = (overigeIs != null);                                                                                //geldig bericht
                    bool okLength       = (stateNew.OverigeIs == null || overigeIs == null || overigeIs.Length == stateNew.OverigeIs.Length); //aantal detectoren gelijk
                    bool okDeltaMsg     = (delta != -1);                                                                                      //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta);                                                                          //delta gelijk aan of groter dan voorgaande

                    if (okMsg &&
                        okLength &&
                        okDeltaMsg &&
                        okDeltaCorrect)
                    {
                        //OK
                        stateNew.Delta     = delta;
                        stateNew.OverigeIs = overigeIs;

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect status inputsignals message {0} (format incorrect)", vlogBericht));
                        }
                        else if (!okLength)
                        {
                            addError(string.Format("Incorrect status inputsignals message {0} (amount of inputsignals {1} instead of {2})", vlogBericht, overigeIs.Length, stateNew.OverigeIs.Length));
                        }
                        else if (!okDeltaMsg)
                        {
                            addError(string.Format("Incorrect status inputsignals message {0} (delta incorrect)", vlogBericht));
                        }
                        else if (!okDeltaCorrect)
                        {
                            addError(string.Format("Incorrect status inputsignals message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                        }
                    }
                    break;
                }

                case "0D":
                {
                    //status fc extern
                    int[] fcs   = VLog.Parser.DecodeStatusFcExt(vlogBericht);
                    int   delta = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg          = (fcs != null);                                                                        //geldig bericht
                    bool okLength       = (stateNew.FcExtern == null || fcs == null || fcs.Length == stateNew.FcExtern.Length); //aantal signaalgroepen gelijk
                    bool okDeltaMsg     = (delta != -1);                                                                        //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta);                                                            //delta gelijk aan of groter dan voorgaande

                    if (okMsg &&
                        okLength &&
                        okDeltaMsg &&
                        okDeltaCorrect)

                    {
                        //OK
                        stateNew.Delta    = delta;
                        stateNew.FcExtern = fcs;

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect status internal signalgroup message {0} (format incorrect)", vlogBericht));
                        }
                        else if (!okLength)
                        {
                            addError(string.Format("Incorrect status internal signalgroup message {0} (amount of signalgroups {1} instead of {2})", vlogBericht, fcs.Length, stateNew.FcExtern.Length));
                        }
                        else if (!okDeltaMsg)
                        {
                            addError(string.Format("Incorrect status internal signalgroup message {0} (delta incorrect)", vlogBericht));
                        }
                        else if (!okDeltaCorrect)
                        {
                            addError(string.Format("Incorrect status internal signalgroup message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                        }
                    }
                    break;
                }

                case "0B":
                {
                    //status uitgangssignalen GUS
                    bool[] overigeUsGus = VLog.Parser.DecodeStatusUsGus(vlogBericht);
                    int    delta        = VLog.Parser.DecodeDelta(vlogBericht);

                    bool okMsg          = (overigeUsGus != null);                                                                                         //geldig bericht
                    bool okLength       = (stateNew.OverigeUsGus == null || overigeUsGus == null || overigeUsGus.Length == stateNew.OverigeUsGus.Length); //aantal detectoren gelijk
                    bool okDeltaMsg     = (delta != -1);                                                                                                  //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta);                                                                                      //delta gelijk aan of groter dan voorgaande

                    if (okMsg &&
                        okLength &&
                        okDeltaMsg &&
                        okDeltaCorrect)
                    {
                        //OK
                        stateNew.Delta        = delta;
                        stateNew.OverigeUsGus = overigeUsGus;

                        checkDataVsConfig = true;
                    }
                    else
                    {
                        //error
                        error = true;

                        if (!okMsg)
                        {
                            addError(string.Format("Incorrect status outputsignals GUS message {0} (format incorrect)", vlogBericht));
                        }
                        else if (!okLength)
                        {
                            addError(string.Format("Incorrect status outputsignals GUS message {0} (amount of outputsignals {1} instead of {2})", vlogBericht, overigeUsGus.Length, stateNew.OverigeUsGus.Length));
                        }
                        else if (!okDeltaMsg)
                        {
                            addError(string.Format("Incorrect status outputsignals GUS message {0} (delta incorrect)", vlogBericht));
                        }
                        else if (!okDeltaCorrect)
                        {
                            addError(string.Format("Incorrect status outputsignals GUS message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                        }
                    }
                    break;
                }

                default:
                {
                    //ander berichttype: alleen controleren op hex ascii data
                    if (!VLog.Parser.IsHexAscii(vlogBericht))
                    {
                        error = true;
                        addError(string.Format("Incorrect message {0}, geen Hex Ascii", vlogBericht));
                    }

                    //delta extraheren
                    int  delta          = VLog.Parser.DecodeDelta(vlogBericht);
                    bool okDeltaMsg     = (delta != -1);             //delta in bericht correct
                    bool okDeltaCorrect = (delta >= stateNew.Delta); //delta gelijk aan of groter dan voorgaande
                    if (!okDeltaMsg)
                    {
                        break;                      //niet kunnen bepalen van delta kan voorkomen doordat niet alle berichten zijn geimplementeerd
                    }
                    if (okDeltaCorrect)
                    {
                        //OK
                        stateNew.Delta = delta;
                    }
                    else
                    {
                        //error
                        error = true;
                        addError(string.Format("Incorrect message {0} (new delta {1} is lower than last delta {2})", vlogBericht, delta, stateNew.Delta));
                    }
                }
                break;
                }
            }

            //analyse uitvoeren
            if (_state == State.WaitForStatus)
            {
                matchPeriods.UpdateLastKnowTime(waitForStatusTimeRef);
            }
            if (_state == State.Active)
            {
                matchPeriods.UpdateLastKnowTime(stateNew.Time);

                if (checkDataVsConfig)
                {
                    //check op correctheid data t.o.v. configuratie
                    DataInfo vdi       = stateNew.DataInfo;
                    bool     compareOk = vdi.EqualTo(vlogConfig.Sys, vlogConfig.VLogVersie, vlogConfig.Dp.Length, vlogConfig.Fc.Length, vlogConfig.Is.Length, vlogConfig.Us.Length);
                    if (!compareOk)
                    {
                        //error
                        error = true;

                        addError(string.Format("V-Log data doesn't fit configuration. Data: {1}, Config: {2}.", vlogBericht, vdi, vlogConfig));
                    }
                    matchPeriods.StartPeriod(compareOk, stateNew.Time);
                }

                if (!error && process)
                {
                    analyse();
                    stateCurrent = stateNew.Clone();
                }

                if (!error && !process)
                {
                    //alleen delta kopieren
                    stateCurrent.Delta = stateNew.Delta;
                }
            }

            if (error)
            {
                //resetten
                if (errorToWaitForStatus)
                {
                    _state = State.WaitForStatus;
                }
                else
                {
                    _state = State.WaitForTimeRef;
                }
                errorInData();
                stateNew     = new VLog.VriState();
                stateCurrent = new VLog.VriState();
            }
        }