Ejemplo n.º 1
0
        private void OnAnalogAddedEvent(object sender, EventArgs e)
        {
            Console.WriteLine("OnAnalogEventAdded started");
            Analog         analog = (Analog)e;
            IORequestBlock iorb   = new IORequestBlock()
            {
                RequestType           = RequestType.SEND,
                ProcessControllerName = analog.ProcContrName
            };

            DBContext dbContext = new DBContext();
            RTU       rtu;

            if ((rtu = dbContext.GetRTUByName(analog.ProcContrName)) != null)
            {
                iorb.ReqAddress = (ushort)rtu.GetCommandAddress(analog);
                bool shouldCommand = false;

                switch (rtu.Protocol)
                {
                case IndustryProtocols.ModbusTCP:

                    ModbusHandler mdbHandler = new ModbusHandler();
                    mdbHandler.Header = new ModbusApplicationHeader()
                    {
                        TransactionId = 0,
                        Length        = 5,
                        ProtocolId    = (ushort)IndustryProtocols.ModbusTCP,
                        DeviceAddress = rtu.Address
                    };

                    mdbHandler.Request = new WriteRequest()
                    {
                        StartAddr = (ushort)rtu.GetCommandAddress(analog)
                    };

                    if (shouldCommand = AnalogProcessor.InitialWorkPointAnalog(analog))
                    {
                        mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister;
                        AnalogProcessor.EGUToRawValue(analog);
                        ((WriteRequest)mdbHandler.Request).Value = analog.RawCommValue;
                        iorb.SendBuff      = mdbHandler.PackData();
                        iorb.SendMsgLength = iorb.SendBuff.Length;
                        Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12));
                        IORequests.EnqueueRequest(iorb);

                        analog.IsInit = true;
                    }

                    break;
                }
            }
            Console.WriteLine("OnAnalogEventAdded finished");
        }
Ejemplo n.º 2
0
        // napravila, ali nisam testirala do kraja, to je nekad za buducnost, svakako ne treba sad :)
        public OMSSCADACommon.Responses.Response WriteSingleAnalog(string id, float value)
        {
            Console.WriteLine("WriteSingleAnalog!");

            Analog analog = null;

            OMSSCADACommon.Responses.Response response = new OMSSCADACommon.Responses.Response();

            // to do:
            //while (!Database.IsConfigurationRunning)


            // getting PV from db
            ProcessVariable pv;

            if (dbContext.GetProcessVariableByName(id, out pv))
            {
                analog = (Analog)pv;
            }
            // does this ID exist in the database
            if (analog == null)
            {
                response.ResultMessage = ResultMessage.INVALID_ID;
                return(response);
            }

            // to do:
            // ovde analogProcessor provera opsega, alarma...bla, bla



            RTU rtu;

            if ((rtu = dbContext.GetRTUByName(analog.ProcContrName)) != null)
            {
                IORequestBlock iorb = new IORequestBlock()
                {
                    RequestType           = RequestType.SEND,
                    ProcessControllerName = analog.ProcContrName
                };

                iorb.ReqAddress = (ushort)rtu.GetCommandAddress(analog);

                bool shouldCommand = false;
                switch (rtu.Protocol)
                {
                case IndustryProtocols.ModbusTCP:

                    ModbusHandler mdbHandler = new ModbusHandler
                    {
                        Header = new ModbusApplicationHeader()
                        {
                            TransactionId = 0,
                            Length        = 5,
                            ProtocolId    = (ushort)IndustryProtocols.ModbusTCP,
                            DeviceAddress = rtu.Address
                        },

                        Request = new WriteRequest()
                        {
                            FunCode   = FunctionCodes.WriteSingleCoil,
                            StartAddr = (ushort)rtu.GetCommandAddress(analog)
                        }
                    };

                    if (shouldCommand = AnalogProcessor.SetNewWorkPoint(analog, value))
                    {
                        mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister;
                        ((WriteRequest)mdbHandler.Request).Value = (ushort)analog.RawCommValue;
                    }

                    iorb.SendBuff      = mdbHandler.PackData();
                    iorb.SendMsgLength = iorb.SendBuff.Length;
                    break;
                }

                IORequests.EnqueueRequest(iorb);
                Console.WriteLine("enqued {0}", BitConverter.ToString(iorb.SendBuff, 0, 12));
                response.ResultMessage = ResultMessage.OK;
            }
            else
            {
                // rtu does not exist
            }

            return(response);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Send Commands to simulator, to make its state consistent with RTDB
        /// </summary>
        public void InitializeSimulator()
        {
            // ovo probati sa taskovima, za svaki od rtu-ova. ipak ne, jer nekim promenljivim komandujes, nekim ne
            // var rtus = dbContext.GettAllRTUs();

            //Parallel.ForEach(rtus, (currentRtu, state) =>
            //{
            //    Console.WriteLine("InitSim Parallel.foreach RTU name = {0}, Therad id = {1} started", currentRtu.Key, Thread.CurrentThread.ManagedThreadId);
            //    IIndustryProtocolHandler IProtHandler = null;
            //    RTU rtu = dbContext.GetRTUByName(currentRtu.Key);
            //    if (currentRtu.Value != null)
            //    {
            //        IORequestBlock iorb = new IORequestBlock()
            //        {
            //            RequestType = RequestType.SEND,
            //            ProcessControllerName = currentRtu.Key
            //        };

            //        switch (rtu.Protocol)
            //        {
            //            case IndustryProtocols.ModbusTCP:
            //                IProtHandler = new ModbusHandler()
            //                {
            //                    Header = new ModbusApplicationHeader
            //                    {
            //                        TransactionId = 0,
            //                        ProtocolId = (ushort)IndustryProtocols.ModbusTCP,
            //                        DeviceAddress = rtu.Address,
            //                        Length = 5
            //                    },
            //                    Request = new WriteRequest()
            //                };
            //                break;
            //        }

            //        //to do. praviti nove iorbove
            //        // za svaku varijablu trebas imati should command ili ne i u zavisnosti od toga puniti data, racunati length  zahtvea i ostalo
            //        //-------------analogs---------------
            //        var analogs = dbContext.GetProcessVariable().Where(pv => pv.Type == VariableTypes.ANALOG && pv.IsInit == false &&
            //                                                            pv.ProcContrName.Equals(currentRtu.Key)).OrderBy(pv => pv.RelativeAddress);
            //        int requestCount = analogs.ToList().Count();
            //        if (requestCount != 0)
            //        {
            //            ProcessVariable firstPV = analogs.FirstOrDefault();
            //            iorb.ReqAddress = (ushort)rtu.GetAcqAddress(firstPV);

            //            if (IProtHandler != null)
            //            {
            //                switch (rtu.Protocol)
            //                {
            //                    case IndustryProtocols.ModbusTCP:


            //                        for(int i = 0; i < requestCount; i++)
            //                        {

            //                        }
            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).FunCode = FunctionCodes.ReadInputRegisters;
            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).Quantity = (ushort)requestCount;
            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).StartAddr = iorb.ReqAddress;
            //                        break;
            //                }

            //                iorb.Flags = requestCount;
            //                iorb.SendBuff = IProtHandler.PackData();
            //                iorb.SendMsgLength = iorb.SendBuff.Length;
            //                IORequests.EnqueueRequest(iorb);
            //            }
            //        }

            //        //-------------digitals---------------(to do: add init flag...)
            //        var digitals = dbContext.GetProcessVariable().Where(pv => pv.Type == VariableTypes.DIGITAL &&
            //                                                            pv.ProcContrName.Equals(currentRtu.Key)).OrderBy(pv => pv.RelativeAddress);
            //        requestCount = digitals.ToList().Count();
            //        if (requestCount != 0)
            //        {
            //            ProcessVariable firstPV = digitals.FirstOrDefault();
            //            iorb.ReqAddress = (ushort)rtu.GetAcqAddress(firstPV);

            //            if (IProtHandler != null)
            //            {
            //                switch (rtu.Protocol)
            //                {
            //                    case IndustryProtocols.ModbusTCP:

            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).FunCode = FunctionCodes.ReadDiscreteInput;
            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).Quantity = (ushort)requestCount;
            //                        ((ReadRequest)((ModbusHandler)IProtHandler).Request).StartAddr = iorb.ReqAddress;
            //                        break;
            //                }

            //                iorb.Flags = requestCount;
            //                iorb.SendBuff = IProtHandler.PackData();
            //                iorb.SendMsgLength = iorb.SendBuff.Length;
            //                IORequests.EnqueueRequest(iorb);
            //            }
            //        }
            //    }
            //});

            List <ProcessVariable> pvs = dbContext.GetProcessVariable().ToList();

            if (pvs.Count != 0)
            {
                foreach (ProcessVariable pv in pvs)
                {
                    IORequestBlock iorb = new IORequestBlock()
                    {
                        RequestType           = RequestType.SEND,
                        ProcessControllerName = pv.ProcContrName
                    };

                    RTU rtu;
                    if ((rtu = dbContext.GetRTUByName(pv.ProcContrName)) != null)
                    {
                        iorb.ReqAddress = (ushort)rtu.GetCommandAddress(pv);
                        bool shouldCommand = false;

                        switch (rtu.Protocol)
                        {
                        case IndustryProtocols.ModbusTCP:

                            ModbusHandler mdbHandler = new ModbusHandler();
                            mdbHandler.Header = new ModbusApplicationHeader()
                            {
                                TransactionId = 0,
                                Length        = 5,
                                ProtocolId    = (ushort)IndustryProtocols.ModbusTCP,
                                DeviceAddress = rtu.Address
                            };

                            mdbHandler.Request = new WriteRequest()
                            {
                                StartAddr = (ushort)rtu.GetCommandAddress(pv)
                            };

                            switch (pv.Type)
                            {
                            // initialy, on simulator all digitals are set to 0 -> closed state
                            case VariableTypes.DIGITAL:
                                Digital digital = (Digital)pv;

                                CommandTypes comm;
                                if (shouldCommand = CommandValidator.InitialCommandingForDigital(digital, out comm))
                                {
                                    mdbHandler.Request.FunCode = FunctionCodes.WriteSingleCoil;
                                    ((WriteRequest)mdbHandler.Request).Value = (ushort)comm;
                                }
                                break;

                            case VariableTypes.ANALOG:
                                Analog analog = (Analog)pv;

                                if (shouldCommand = AnalogProcessor.InitialWorkPointAnalog(analog))
                                {
                                    mdbHandler.Request.FunCode = FunctionCodes.WriteSingleRegister;
                                    ((WriteRequest)mdbHandler.Request).Value = (ushort)analog.RawCommValue;
                                }
                                analog.IsInit = true;
                                break;

                            case VariableTypes.COUNTER:
                                Counter counter = (Counter)pv;

                                break;
                            }

                            if (shouldCommand)
                            {
                                iorb.SendBuff      = mdbHandler.PackData();
                                iorb.SendMsgLength = iorb.SendBuff.Length;
                                //if (pv.Name == "MEAS_AN_1")
                                //    Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12));
                            }

                            break;
                        }

                        if (shouldCommand)
                        {
                            IORequests.EnqueueRequest(iorb);
                        }
                    }
                    else
                    {
                        // izbrisati omdah te procesne varijable sa rtu-om tog imena?
                        Console.WriteLine("Invalid config: ProcContrName = {0} does not exists.", pv.ProcContrName);
                        continue;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Processing answers from Simulator - Process Controller
        /// </summary>
        public void ProcessPCAnwers(TimeSpan timeout, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                bool           isSuccessful;
                IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful, timeout);

                if (isSuccessful)
                {
                    bool isChange = false;
                    RTU  rtu;
                    // sporno
                    //while (!Database.IsConfigurationRunning)

                    if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null)
                    {
                        switch (rtu.Protocol)
                        {
                        case IndustryProtocols.ModbusTCP:

                            ModbusHandler mdbHandler = new ModbusHandler();
                            try
                            {
                                mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength);
                                switch (mdbHandler.Response.FunCode)
                                {
                                case FunctionCodes.ReadDiscreteInput:
                                {
                                    BitReadResponse response        = (BitReadResponse)mdbHandler.Response;
                                    var             responsePVCount = answer.Flags;

                                    ushort varAddr = answer.ReqAddress;
                                    for (int i = 0; i < responsePVCount; i++, varAddr++)
                                    {
                                        ProcessVariable pv;

                                        if (rtu.GetProcessVariableByAddress(varAddr, out pv))
                                        {
                                            Digital target = (Digital)pv;

                                            try
                                            {
                                                bool isOpened = response.BitValues[i];
                                                if (target.State != target.ValidStates[isOpened ? 1 : 0])
                                                {
                                                    isChange     = true;
                                                    target.State = target.ValidStates[isOpened ? 1 : 0];
                                                    Console.WriteLine(" CHANGE! Digital variable {0}, state: {1}", target.Name, target.State);

                                                    DMSClient dMSClient = new DMSClient();
                                                    dMSClient.ChangeOnSCADADigital(target.Name, target.State);
                                                }
                                            }
                                            catch
                                            {
                                                Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                            }
                                        }
                                    }
                                    if (isChange)
                                    {
                                        ScadaModelParser parser = new ScadaModelParser();
                                        parser.SerializeScadaModel();
                                    }
                                }

                                break;

                                // analog input
                                case FunctionCodes.ReadInputRegisters:
                                {
                                    RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response;
                                    var responsePVCount           = answer.Flags;

                                    ushort varAddr = answer.ReqAddress;
                                    for (int i = 0; i < responsePVCount; i++, varAddr++)
                                    {
                                        ProcessVariable pv;

                                        if (rtu.GetProcessVariableByAddress(varAddr, out pv))
                                        {
                                            Analog target = (Analog)pv;

                                            try
                                            {
                                                ushort newRawAcqValue = response.RegValues[target.RelativeAddress];
                                                float  newAcqValue;
                                                AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue);

                                                if (target.AcqValue != newAcqValue)
                                                {
                                                    isChange = true;

                                                    target.RawAcqValue = newRawAcqValue;
                                                    target.AcqValue    = newAcqValue;
                                                    Console.WriteLine(" CHANGE! Analog variable {0}, AcqValue: {1}", target.Name, target.AcqValue);

                                                    //to do: propagacija analogih promena(ako se secate Pavlica je prvo rekao da nam to ne treba da samo jednom zakucamo vrednost na pocetku) xD
                                                    DMSClient dMSClient = new DMSClient();
                                                    dMSClient.ChangeOnSCADAAnalog(target.Name, target.AcqValue);
                                                }
                                            }
                                            catch
                                            {
                                                // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                            }
                                        }
                                    }
                                    if (isChange)
                                    {
                                        ScadaModelParser parser = new ScadaModelParser();
                                        parser.SerializeScadaModel();
                                    }
                                }

                                break;
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                            }
                            break;
                        }
                    }
                }
            }

            Console.WriteLine("ProcessPCAnswers.shutdown=true");
            return;
        }
Ejemplo n.º 5
0
        public bool DeserializeScadaModel(string deserializationSource = "ScadaModel.xml")
        {
            // to do
            Database.IsConfigurationFinished = false;

            string message           = string.Empty;
            string configurationName = deserializationSource;
            string source            = Path.Combine(basePath, configurationName);

            if (Database.Instance.RTUs.Count != 0)
            {
                Database.Instance.RTUs.Clear();
            }

            if (Database.Instance.ProcessVariablesName.Count != 0)
            {
                Database.Instance.ProcessVariablesName.Clear();
            }

            try
            {
                XElement xdocument = XElement.Load(source);

                // access RTUS, DIGITALS, ANALOGS, COUNTERS from ScadaModel root
                IEnumerable <XElement> elements = xdocument.Elements();

                var rtus     = xdocument.Element("RTUS").Elements("RTU").ToList();
                var digitals = (from dig in xdocument.Element("Digitals").Elements("Digital")
                                orderby(int) dig.Element("RelativeAddress")
                                select dig).ToList();

                var analogs = (from dig in xdocument.Element("Analogs").Elements("Analog")
                               orderby(int) dig.Element("RelativeAddress")
                               select dig).ToList();

                var counters = (from dig in xdocument.Element("Counters").Elements("Counter")
                                orderby(int) dig.Element("RelativeAddress")
                                select dig).ToList();
                // parsing RTUS
                if (rtus.Count != 0)
                {
                    foreach (var rtu in rtus)
                    {
                        RTU    newRtu;
                        string uniqueName = (string)rtu.Element("Name");

                        // if RTU with that name does not already exist?
                        if (!dbContext.Database.RTUs.ContainsKey(uniqueName))
                        {
                            byte address = (byte)(int)rtu.Element("Address");

                            bool freeSpaceForDigitals = (bool)rtu.Element("FreeSpaceForDigitals");
                            bool freeSpaceForAnalogs  = (bool)rtu.Element("FreeSpaceForAnalogs");

                            string            stringProtocol = (string)rtu.Element("Protocol");
                            IndustryProtocols protocol       = (IndustryProtocols)Enum.Parse(typeof(IndustryProtocols), stringProtocol);

                            int digOutStartAddr  = (int)rtu.Element("DigOutStartAddr");
                            int digInStartAddr   = (int)rtu.Element("DigInStartAddr");
                            int anaInStartAddr   = (int)rtu.Element("AnaInStartAddr");
                            int anaOutStartAddr  = (int)rtu.Element("AnaOutStartAddr");
                            int counterStartAddr = (int)rtu.Element("CounterStartAddr");

                            int digOutCount  = (int)rtu.Element("NoDigOut");
                            int digInCount   = (int)rtu.Element("NoDigIn");
                            int anaInCount   = (int)rtu.Element("NoAnaIn");
                            int anaOutCount  = (int)rtu.Element("NoAnaOut");
                            int counterCount = (int)rtu.Element("NoCnt");

                            ushort anaInRawMin  = (ushort)(int)rtu.Element("AnaInRawMin");
                            ushort anaInRawMax  = (ushort)(int)rtu.Element("AnaInRawMax");
                            ushort anaOutRawMin = (ushort)(int)rtu.Element("AnaOutRawMin");
                            ushort anaOutRawMax = (ushort)(int)rtu.Element("AnaOutRawMax");

                            if (digOutCount != digInCount)
                            {
                                message = string.Format("Invalid config: RTU - {0}: Value of DigOutCount must be the same as Value of DigInCount", uniqueName);
                                Console.WriteLine(message);
                                return(false);
                            }

                            newRtu = new RTU()
                            {
                                Name    = uniqueName,
                                Address = address,
                                FreeSpaceForDigitals = freeSpaceForDigitals,
                                FreeSpaceForAnalogs  = freeSpaceForAnalogs,
                                Protocol             = protocol,

                                DigOutStartAddr  = digOutStartAddr,
                                DigInStartAddr   = digInStartAddr,
                                AnaInStartAddr   = anaInStartAddr,
                                AnaOutStartAddr  = anaOutStartAddr,
                                CounterStartAddr = counterStartAddr,

                                NoDigOut = digOutCount,
                                NoDigIn  = digInCount,
                                NoAnaIn  = anaInCount,
                                NoAnaOut = anaOutCount,
                                NoCnt    = counterCount,

                                AnaInRawMin  = anaInRawMin,
                                AnaInRawMax  = anaInRawMax,
                                AnaOutRawMin = anaOutRawMin,
                                AnaOutRawMax = anaOutRawMax
                            };

                            dbContext.AddRTU(newRtu);
                        }
                        else
                        {
                            // to do: bacati exception mozda
                            message = string.Format("Invalid config: There is multiple RTUs with Name={0}!", uniqueName);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }
                else
                {
                    message = string.Format("Invalid config: file must contain at least 1 RTU!");
                    Console.WriteLine(message);
                    return(false);
                }

                //parsing DIGITALS. ORDER OF RELATIVE ADDRESSES IS IMPORTANT
                if (digitals.Count != 0)
                {
                    foreach (var d in digitals)
                    {
                        string procContr = (string)d.Element("ProcContrName");

                        // does RTU exists?
                        RTU associatedRtu;
                        if ((associatedRtu = dbContext.GetRTUByName(procContr)) != null)
                        {
                            Digital newDigital = new Digital();

                            // SETTING ProcContrName
                            newDigital.ProcContrName = procContr;

                            string uniqueName = (string)d.Element("Name");

                            // variable with that name does not exists in db?
                            if (!dbContext.Database.ProcessVariablesName.ContainsKey(uniqueName))
                            {
                                // SETTING Name
                                newDigital.Name = uniqueName;

                                // SETTING State
                                string stringCurrentState = (string)d.Element("State");
                                States stateValue         = (States)Enum.Parse(typeof(States), stringCurrentState);
                                newDigital.State = stateValue;

                                // SETTING Command parameter - for initializing Simulator with last command
                                string       lastCommandString = (string)d.Element("Command");
                                CommandTypes command           = (CommandTypes)Enum.Parse(typeof(CommandTypes), lastCommandString);

                                // SETTING Class
                                string digDevClass            = (string)d.Element("Class");
                                DigitalDeviceClasses devClass = (DigitalDeviceClasses)Enum.Parse(typeof(DigitalDeviceClasses), digDevClass);
                                newDigital.Class = devClass;

                                // SETTING RelativeAddress
                                ushort relativeAddress = (ushort)(int)d.Element("RelativeAddress");
                                newDigital.RelativeAddress = relativeAddress;

                                var hasCommands = d.Element("ValidCommands");
                                if (hasCommands.HasElements)
                                {
                                    var validCommands = hasCommands.Elements("Command").ToList();

                                    // SETTING ValidCommands
                                    foreach (var xElementCommand in validCommands)
                                    {
                                        string       stringCommand = (string)xElementCommand;
                                        CommandTypes validCommand  = (CommandTypes)Enum.Parse(typeof(CommandTypes), stringCommand);
                                        newDigital.ValidCommands.Add(validCommand);
                                    }
                                }
                                else
                                {
                                    message = string.Format("Invalid config: Variable = {0} does not contain commands.", uniqueName);
                                    Console.WriteLine(message);
                                    return(false);
                                }

                                var hasStates = d.Element("ValidStates");
                                if (hasStates.HasElements)
                                {
                                    var validStates = hasStates.Elements("State").ToList();

                                    // SETTING ValidStates
                                    foreach (var xElementState in validStates)
                                    {
                                        string stringState = (string)xElementState;
                                        States state       = (States)Enum.Parse(typeof(States), stringState);
                                        newDigital.ValidStates.Add(state);
                                    }
                                }
                                else
                                {
                                    message = string.Format("Invalid config: Variable = {0} does not contain states.", uniqueName);
                                    Console.WriteLine(message);
                                    return(false);
                                }

                                ushort calculatedRelativeAddres;
                                if (associatedRtu.TryMap(newDigital, out calculatedRelativeAddres))
                                {
                                    if (relativeAddress == calculatedRelativeAddres)
                                    {
                                        if (associatedRtu.MapProcessVariable(newDigital))
                                        {
                                            dbContext.AddProcessVariable(newDigital);
                                        }
                                    }
                                    else
                                    {
                                        message = string.Format("Invalid config: Variable = {0} RelativeAddress = {1} is not valid.", uniqueName, relativeAddress);
                                        Console.WriteLine(message);
                                        return(false);
                                    }
                                }
                            }
                            else
                            {
                                message = string.Format("Invalid config: Name = {0} is not unique. Variable already exists", uniqueName);
                                Console.WriteLine(message);
                                return(false);
                            }
                        }
                        else
                        {
                            message = string.Format("Invalid config: Parsing Digitals, ProcContrName = {0} does not exists.", procContr);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }

                // parsing ANALOGS. ORDER OF RELATIVE ADDRESSES IS IMPORTANT
                if (analogs.Count != 0)
                {
                    foreach (var a in analogs)
                    {
                        string procContr = (string)a.Element("ProcContrName");

                        // does RTU exists?
                        RTU associatedRtu;
                        if ((associatedRtu = dbContext.GetRTUByName(procContr)) != null)
                        {
                            Analog newAnalog = new Analog();

                            // SETTING ProcContrName
                            newAnalog.ProcContrName = procContr;

                            string uniqueName = (string)a.Element("Name");

                            // variable with that name does not exists in db?
                            if (!dbContext.Database.ProcessVariablesName.ContainsKey(uniqueName))
                            {
                                // SETTING Name
                                newAnalog.Name = uniqueName;

                                // SETTING NumOfRegisters
                                ushort numOfReg = (ushort)(int)a.Element("NumOfRegisters");
                                newAnalog.NumOfRegisters = numOfReg;

                                // SETTING AcqValue
                                ushort acqValue = (ushort)(float)a.Element("AcqValue");
                                newAnalog.AcqValue = acqValue;

                                // SETTING CommValue
                                ushort commValue = (ushort)(float)a.Element("CommValue");
                                newAnalog.CommValue = commValue;

                                // SETTING MinValue
                                float minValue = (float)a.Element("MinValue");
                                newAnalog.MinValue = minValue;

                                // SETTING MaxValue
                                float maxValue = (float)a.Element("MaxValue");
                                newAnalog.MaxValue = maxValue;

                                // SETTING UnitSymbol
                                string     stringUnitSymbol = (string)a.Element("UnitSymbol");
                                UnitSymbol unitSymbolValue  = (UnitSymbol)Enum.Parse(typeof(UnitSymbol), stringUnitSymbol, true);
                                newAnalog.UnitSymbol = unitSymbolValue;

                                // SETTING RelativeAddress
                                ushort relativeAddress = (ushort)(int)a.Element("RelativeAddress");
                                newAnalog.RelativeAddress = relativeAddress;

                                // svejedno je uzeli AnaInRawMin ili AnaOutRawMin -> isti su trenutni,
                                // sve dok imamo samo Analog.cs a ne AnaIn.cs + AnaOut.cs (dok je kao za digital)
                                newAnalog.RawBandLow  = associatedRtu.AnaInRawMin;
                                newAnalog.RawBandHigh = associatedRtu.AnaInRawMax;

                                // SETTING RawAcqValue and RawCommValue
                                AnalogProcessor.EGUToRawValue(newAnalog);

                                ushort calculatedRelativeAddres;
                                if (associatedRtu.TryMap(newAnalog, out calculatedRelativeAddres))
                                {
                                    if (relativeAddress == calculatedRelativeAddres)
                                    {
                                        if (associatedRtu.MapProcessVariable(newAnalog))
                                        {
                                            dbContext.AddProcessVariable(newAnalog);
                                        }
                                    }
                                    else
                                    {
                                        message = string.Format("Invalid config: Analog Variable = {0} RelativeAddress = {1} is not valid.", uniqueName, relativeAddress);
                                        Console.WriteLine(message);
                                        return(false);
                                    }
                                }
                            }
                            else
                            {
                                message = string.Format("Invalid config: Name = {0} is not unique. Analog Variable already exists", uniqueName);
                                Console.WriteLine(message);
                                return(false);
                            }
                        }
                        else
                        {
                            message = string.Format("Invalid config: Parsing Analogs, ProcContrName = {0} does not exists.", procContr);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }

                // to do:
                if (counters.Count != 0)
                {
                }

                Console.WriteLine("Configuration passed successfully.");
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
            catch (XmlException e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                return(false);
            }

            Database.IsConfigurationFinished = true;
            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Processing answers from Simulator - Process Controller
        /// </summary>
        public void ProcessPCAnwers(TimeSpan timeout, CancellationToken token)
        {
            DataLinkHandler dataLinkHandler = new DataLinkHandler();

            while (!token.IsCancellationRequested)
            {
                bool           isSuccessful;
                IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful, timeout);

                if (isSuccessful)
                {
                    bool isChange = false;
                    RTU  rtu;

                    if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null)
                    {
                        switch (rtu.Protocol)
                        {
                        case IndustryProtocols.ModbusTCP:

                            ModbusHandler mdbHandler = new ModbusHandler();
                            try
                            {
                                mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength);
                                switch (mdbHandler.Response.FunCode)
                                {
                                case FunctionCodes.ReadDiscreteInput:
                                {
                                    BitReadResponse response        = (BitReadResponse)mdbHandler.Response;
                                    var             responsePVCount = answer.Flags;

                                    ushort varAddr = answer.ReqAddress;
                                    for (int i = 0; i < responsePVCount; i++, varAddr++)
                                    {
                                        ProcessVariable pv;

                                        if (rtu.GetProcessVariableByAddress(varAddr, out pv))
                                        {
                                            Digital target = (Digital)pv;

                                            try
                                            {
                                                bool isOpened = response.BitValues[i];
                                                if (target.State != target.ValidStates[isOpened ? 1 : 0])
                                                {
                                                    isChange     = true;
                                                    target.State = target.ValidStates[isOpened ? 1 : 0];
                                                    Console.WriteLine(" CHANGE! Digital variable {0}, state: {1}", target.Name, target.State);

                                                    dMSProxy.ChangeOnSCADADigital(target.Name, target.State);
                                                }
                                            }
                                            catch
                                            {
                                                Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                            }
                                        }
                                    }
                                    if (isChange)
                                    {
                                        ScadaModelParser parser = new ScadaModelParser();
                                        parser.SerializeScadaModel();
                                    }
                                }

                                break;

                                // analog input
                                case FunctionCodes.ReadInputRegisters:
                                {
                                    RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response;
                                    var responsePVCount           = answer.Flags;

                                    ushort varAddr = answer.ReqAddress;
                                    for (int i = 0; i < responsePVCount; i++, varAddr++)
                                    {
                                        ProcessVariable pv;

                                        if (rtu.GetProcessVariableByAddress(varAddr, out pv))
                                        {
                                            Analog target = (Analog)pv;

                                            try
                                            {
                                                ushort newRawAcqValue = response.RegValues[target.RelativeAddress];
                                                float  newAcqValue;
                                                AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue);

                                                if (target.AcqValue != newAcqValue)
                                                {
                                                    isChange = true;

                                                    target.RawAcqValue = newRawAcqValue;
                                                    target.AcqValue    = newAcqValue;
                                                    Console.WriteLine(" CHANGE! Analog variable {0}, AcqValue: {1}", target.Name, target.AcqValue);

                                                    //to do: propagacija analogih promena(ako se secate Pavlica je prvo rekao da nam to ne treba da samo jednom zakucamo vrednost na pocetku) xD

                                                    dMSProxy.ChangeOnSCADAAnalog(target.Name, target.AcqValue);
                                                }
                                            }
                                            catch
                                            {
                                                // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                            }
                                        }
                                    }
                                    if (isChange)
                                    {
                                        ScadaModelParser parser = new ScadaModelParser();
                                        parser.SerializeScadaModel();
                                    }
                                }

                                break;
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                            }
                            break;

                        case IndustryProtocols.DNP3TCP:

                            byte len = answer.RcvBuff[2];

                            byte actualLen = (byte)(2 + 1 + 5 + 2); // start + len + ctrl + dest + source + crc

                            len -= 5;                               // minus header

                            while (len > 0)
                            {
                                if (len < 16)
                                {
                                    // last chunk
                                    actualLen += (byte)(len + 2);
                                    break;
                                }

                                actualLen += (byte)(16 + 2);
                                len       -= 16;
                            }

                            byte[] message = new byte[actualLen];

                            for (int i = 0; i < actualLen; i++)
                            {
                                message[i] = answer.RcvBuff[i];
                            }

                            List <UserLevelObject> userLevelObjects = dataLinkHandler.PackUp(message);

                            if (userLevelObjects == null)
                            {
                                continue;
                            }

                            DNP3UserLayerHandler          dNP3UserLayerHandler = new DNP3UserLayerHandler(new DNP3Handler(), dbContext);
                            List <Tuple <string, float> > tuples = dNP3UserLayerHandler.ReadAllAnalogInputPointsReadResponse(userLevelObjects, rtu.Name);

                            foreach (Tuple <string, float> tuple in tuples)
                            {
                                try
                                {
                                    dMSProxy.ChangeOnSCADAAnalog(tuple.Item1, tuple.Item2);
                                }
                                catch
                                {
                                    dMSProxy = new DMSSCADAProxy();
                                }
                            }

                            break;
                        }
                    }
                }
            }

            Console.WriteLine("ProcessPCAnswers.shutdown=true");
            return;
        }
Ejemplo n.º 7
0
        public bool DeserializeScadaModel(string deserializationSource = "ScadaModel.xml")
        {
            // to do
            Database.IsConfigurationFinished = false;

            string message           = string.Empty;
            string configurationName = deserializationSource;

            //  string source = Path.Combine(basePath, configurationName);

            if (Database.Instance.RTUs.Count != 0)
            {
                Database.Instance.RTUs.Clear();
            }

            if (Database.Instance.ProcessVariablesName.Count != 0)
            {
                Database.Instance.ProcessVariablesName.Clear();
            }

            try
            {
                //  XElement xdocument = XElement.Load(source);

                // access RTUS, DIGITALS, ANALOGS, COUNTERS from ScadaModel root
                //   IEnumerable<XElement> elements = xdocument.Elements();

                //var rtus = xdocument.Element("RTUS").Elements("RTU").ToList();
                //var digitals = (from dig in xdocument.Element("Digitals").Elements("Digital")
                //                orderby (int)dig.Element("RelativeAddress")
                //                select dig).ToList();

                //var analogs = (from dig in xdocument.Element("Analogs").Elements("Analog")
                //               orderby (int)dig.Element("RelativeAddress")
                //               select dig).ToList();

                //var counters = (from dig in xdocument.Element("Counters").Elements("Counter")
                //                orderby (int)dig.Element("RelativeAddress")
                //                select dig).ToList();

                List <ScadaDBClassLib.ModelData.RTU>     rtus     = new List <ScadaDBClassLib.ModelData.RTU>();
                List <ScadaDBClassLib.ModelData.Digital> digitals = new List <ScadaDBClassLib.ModelData.Digital>();
                List <ScadaDBClassLib.ModelData.Analog>  analogs  = new List <ScadaDBClassLib.ModelData.Analog>();

                using (ScadaDBClassLib.ScadaCtxcs ctx = new ScadaDBClassLib.ScadaCtxcs())
                {
                    rtus     = ctx.RTUs.ToList();
                    digitals = ctx.Digitals.ToList();
                    analogs  = ctx.Analogs.ToList();
                }

                // parsing RTUS
                if (rtus.Count != 0)
                {
                    foreach (var rtu in rtus)
                    {
                        RTU    newRtu;
                        string uniqueName = (string)rtu.Name;

                        // if RTU with that name does not already exist?
                        if (!dbContext.Database.RTUs.ContainsKey(uniqueName))
                        {
                            byte address = (byte)(int)rtu.Address;

                            bool freeSpaceForDigitals = (bool)rtu.FreeSpaceForDigitals;
                            bool freeSpaceForAnalogs  = (bool)rtu.FreeSpaceForAnalogs;


                            IndustryProtocols protocol = IndustryProtocols.ModbusTCP;

                            int digOutStartAddr  = (int)rtu.DigOutStartAddr;
                            int digInStartAddr   = (int)rtu.DigInStartAddr;
                            int anaInStartAddr   = (int)rtu.AnaInStartAddr;
                            int anaOutStartAddr  = (int)rtu.AnaOutStartAddr;
                            int counterStartAddr = (int)rtu.CounterStartAddr;

                            int digOutCount  = (int)rtu.NoDigOut;
                            int digInCount   = (int)rtu.NoDigIn;
                            int anaInCount   = (int)rtu.NoAnaIn;
                            int anaOutCount  = (int)rtu.NoAnaOut;
                            int counterCount = (int)rtu.NoCnt;

                            ushort anaInRawMin  = (ushort)(int)rtu.AnaInRawMin;
                            ushort anaInRawMax  = (ushort)(int)rtu.AnaInRawMax;
                            ushort anaOutRawMin = (ushort)(int)rtu.AnaOutRawMin;
                            ushort anaOutRawMax = (ushort)(int)rtu.AnaOutRawMax;

                            if (digOutCount != digInCount)
                            {
                                message = string.Format("Invalid config: RTU - {0}: Value of DigOutCount must be the same as Value of DigInCount", uniqueName);
                                Console.WriteLine(message);
                                return(false);
                            }

                            newRtu = new RTU()
                            {
                                Name    = uniqueName,
                                Address = address,
                                FreeSpaceForDigitals = freeSpaceForDigitals,
                                FreeSpaceForAnalogs  = freeSpaceForAnalogs,
                                Protocol             = protocol,

                                DigOutStartAddr  = digOutStartAddr,
                                DigInStartAddr   = digInStartAddr,
                                AnaInStartAddr   = anaInStartAddr,
                                AnaOutStartAddr  = anaOutStartAddr,
                                CounterStartAddr = counterStartAddr,

                                NoDigOut = digOutCount,
                                NoDigIn  = digInCount,
                                NoAnaIn  = anaInCount,
                                NoAnaOut = anaOutCount,
                                NoCnt    = counterCount,

                                AnaInRawMin  = anaInRawMin,
                                AnaInRawMax  = anaInRawMax,
                                AnaOutRawMin = anaOutRawMin,
                                AnaOutRawMax = anaOutRawMax
                            };

                            //using (ScadaContextDB ctx = new ScadaContextDB())
                            //{
                            //    ctx.RTUs.Add(new ScadaCloud.Model.RTU
                            //    {
                            //        Name = uniqueName,
                            //        Address = address,
                            //        FreeSpaceForDigitals = freeSpaceForDigitals,
                            //        FreeSpaceForAnalogs = freeSpaceForAnalogs,
                            //        Protocol = protocol,

                            //        DigOutStartAddr = digOutStartAddr,
                            //        DigInStartAddr = digInStartAddr,
                            //        AnaInStartAddr = anaInStartAddr,
                            //        AnaOutStartAddr = anaOutStartAddr,
                            //        CounterStartAddr = counterStartAddr,

                            //        NoDigOut = digOutCount,
                            //        NoDigIn = digInCount,
                            //        NoAnaIn = anaInCount,
                            //        NoAnaOut = anaOutCount,
                            //        NoCnt = counterCount,

                            //        AnaInRawMin = anaInRawMin,
                            //        AnaInRawMax = anaInRawMax,
                            //        AnaOutRawMin = anaOutRawMin,
                            //        AnaOutRawMax = anaOutRawMax

                            //    });
                            //    ctx.SaveChanges();

                            //}

                            dbContext.AddRTU(newRtu);
                        }
                        else
                        {
                            // to do: bacati exception mozda
                            message = string.Format("Invalid config: There is multiple RTUs with Name={0}!", uniqueName);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }
                else
                {
                    message = string.Format("Invalid config: file must contain at least 1 RTU!");
                    Console.WriteLine(message);
                    return(false);
                }

                //parsing DIGITALS. ORDER OF RELATIVE ADDRESSES IS IMPORTANT
                if (digitals.Count != 0)
                {
                    foreach (var d in digitals)
                    {
                        string procContr = (string)d.ProcContrName;

                        // does RTU exists?
                        RTU associatedRtu;
                        if ((associatedRtu = dbContext.GetRTUByName(procContr)) != null)
                        {
                            Digital newDigital = new Digital();

                            // SETTING ProcContrName
                            newDigital.ProcContrName = procContr;

                            string uniqueName = (string)d.Name;

                            // variable with that name does not exists in db?
                            if (!dbContext.Database.ProcessVariablesName.ContainsKey(uniqueName))
                            {
                                // SETTING Name
                                newDigital.Name = uniqueName;

                                // SETTING State
                                string stringCurrentState = (string)d.State;
                                States stateValue         = (States)Enum.Parse(typeof(States), stringCurrentState);
                                newDigital.State = stateValue;

                                // SETTING Command parameter - for initializing Simulator with last command
                                string       lastCommandString = (string)d.Command;
                                CommandTypes command           = (CommandTypes)Enum.Parse(typeof(CommandTypes), lastCommandString);

                                // SETTING Class

                                DigitalDeviceClasses devClass = DigitalDeviceClasses.SWITCH;
                                newDigital.Class = devClass;

                                // SETTING RelativeAddress
                                ushort relativeAddress = (ushort)(int)d.RelativeAddress;
                                newDigital.RelativeAddress = relativeAddress;

                                // SETTING ValidCommands
                                newDigital.ValidCommands.Add(CommandTypes.OPEN);
                                newDigital.ValidCommands.Add(CommandTypes.CLOSE);


                                newDigital.ValidStates.Add(States.CLOSED);
                                newDigital.ValidStates.Add(States.OPENED);


                                //using (ScadaContextDB ctx = new ScadaContextDB())
                                //{
                                //    ctx.Digirals.Add(new ScadaCloud.Model.Digital
                                //    {
                                //        Name = uniqueName,
                                //        RelativeAddress = relativeAddress,
                                //        ProcContrName = procContr,
                                //        State = stringCurrentState,
                                //        Command = lastCommandString
                                //    });
                                //    ctx.SaveChanges();
                                //}

                                ushort calculatedRelativeAddres;
                                if (associatedRtu.TryMap(newDigital, out calculatedRelativeAddres))
                                {
                                    if (relativeAddress == calculatedRelativeAddres)
                                    {
                                        if (associatedRtu.MapProcessVariable(newDigital))
                                        {
                                            dbContext.AddProcessVariable(newDigital);
                                        }
                                    }
                                    else
                                    {
                                        message = string.Format("Invalid config: Variable = {0} RelativeAddress = {1} is not valid.", uniqueName, relativeAddress);
                                        Console.WriteLine(message);
                                        continue;
                                    }
                                }
                            }
                            else
                            {
                                message = string.Format("Invalid config: Name = {0} is not unique. Variable already exists", uniqueName);
                                Console.WriteLine(message);
                                continue;
                            }
                        }
                        else
                        {
                            message = string.Format("Invalid config: Parsing Digitals, ProcContrName = {0} does not exists.", procContr);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }

                // parsing ANALOGS. ORDER OF RELATIVE ADDRESSES IS IMPORTANT
                if (analogs.Count != 0)
                {
                    foreach (var a in analogs)
                    {
                        string procContr = (string)a.ProcContrName;

                        // does RTU exists?
                        RTU associatedRtu;
                        if ((associatedRtu = dbContext.GetRTUByName(procContr)) != null)
                        {
                            Analog newAnalog = new Analog();

                            // SETTING ProcContrName
                            newAnalog.ProcContrName = procContr;

                            string uniqueName = (string)a.Name;

                            // variable with that name does not exists in db?
                            if (!dbContext.Database.ProcessVariablesName.ContainsKey(uniqueName))
                            {
                                // SETTING Name
                                newAnalog.Name = uniqueName;

                                // SETTING NumOfRegisters
                                ushort numOfReg = (ushort)(int)a.NumOfRegisters;
                                newAnalog.NumOfRegisters = numOfReg;

                                // SETTING AcqValue
                                ushort acqValue = (ushort)(float)a.AcqValue;
                                newAnalog.AcqValue = acqValue;

                                // SETTING CommValue
                                ushort commValue = (ushort)(float)a.CommValue;
                                newAnalog.CommValue = commValue;

                                // SETTING MinValue
                                float minValue = (float)a.MinValue;
                                newAnalog.MinValue = minValue;

                                // SETTING MaxValue
                                float maxValue = (float)a.MaxValue;
                                newAnalog.MaxValue = maxValue;

                                // SETTING UnitSymbol
                                string     stringUnitSymbol = (string)a.UnitSymbol;
                                UnitSymbol unitSymbolValue  = (UnitSymbol)Enum.Parse(typeof(UnitSymbol), stringUnitSymbol, true);
                                newAnalog.UnitSymbol = unitSymbolValue;

                                // SETTING RelativeAddress
                                ushort relativeAddress = (ushort)(int)a.RelativeAddress;
                                newAnalog.RelativeAddress = relativeAddress;

                                // svejedno je uzeli AnaInRawMin ili AnaOutRawMin -> isti su trenutni,
                                // sve dok imamo samo Analog.cs a ne AnaIn.cs + AnaOut.cs (dok je kao za digital)
                                newAnalog.RawBandLow  = associatedRtu.AnaInRawMin;
                                newAnalog.RawBandHigh = associatedRtu.AnaInRawMax;

                                //using (ScadaContextDB ctx = new ScadaContextDB())
                                //{
                                //    ctx.Analogs.Add(new ScadaCloud.Model.Analog
                                //    {
                                //        Name = uniqueName,
                                //        NumOfRegisters = numOfReg,
                                //        AcqValue = acqValue,
                                //        CommValue = commValue,
                                //        MaxValue = maxValue,
                                //        MinValue = minValue,
                                //        ProcContrName = procContr,
                                //        RelativeAddress = relativeAddress,
                                //        UnitSymbol = stringUnitSymbol

                                //    });
                                //    ctx.SaveChanges();

                                //}

                                // SETTING RawAcqValue and RawCommValue
                                AnalogProcessor.EGUToRawValue(newAnalog);

                                ushort calculatedRelativeAddres;
                                if (associatedRtu.TryMap(newAnalog, out calculatedRelativeAddres))
                                {
                                    if (relativeAddress == calculatedRelativeAddres)
                                    {
                                        if (associatedRtu.MapProcessVariable(newAnalog))
                                        {
                                            dbContext.AddProcessVariable(newAnalog);
                                        }
                                    }
                                    else
                                    {
                                        message = string.Format("Invalid config: Analog Variable = {0} RelativeAddress = {1} is not valid.", uniqueName, relativeAddress);
                                        Console.WriteLine(message);
                                        return(false);
                                    }
                                }
                            }
                            else
                            {
                                message = string.Format("Invalid config: Name = {0} is not unique. Analog Variable already exists", uniqueName);
                                Console.WriteLine(message);
                                return(false);
                            }
                        }
                        else
                        {
                            message = string.Format("Invalid config: Parsing Analogs, ProcContrName = {0} does not exists.", procContr);
                            Console.WriteLine(message);
                            return(false);
                        }
                    }
                }

                // to do:
                //if (counters.Count != 0)
                //{

                //}

                Console.WriteLine("Configuration passed successfully.");
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
            catch (XmlException e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                return(false);
            }

            Database.IsConfigurationFinished = true;
            return(true);
        }