Exemplo n.º 1
0
        public CommandingAcquisitionEngine()
        {
            Console.WriteLine("AcqEngine Instancing()");

            IORequests = IORequestsQueue.GetQueue();
            dbContext  = new DBContext();
            timerMsc   = 5000;

            dMSProxy = new DMSSCADAProxy();
        }
Exemplo n.º 2
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;
        }