コード例 #1
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);
        }
コード例 #2
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)
                    {
                        if (rtu.Protocol == IndustryProtocols.DNP3TCP)
                        {
                            return;
                        }

                        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;
                    }
                }
            }
        }
コード例 #3
0
 public abstract bool ProcessRequest(IORequestBlock forProcess);
コード例 #4
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;
        }
コード例 #5
0
 public override bool ProcessRequest(IORequestBlock forProcess)
 {
     throw new NotImplementedException();
 }
コード例 #6
0
        public OMSSCADACommon.Responses.Response WriteSingleDigital(string id, CommandTypes command)
        {
            Console.WriteLine("WriteSingleDigital!");

            Digital digital = null;

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

            //while (!Database.IsConfigurationRunning)
            //    Thread.Sleep(100);


            // getting PV from db
            ProcessVariable pv;

            if (dbContext.GetProcessVariableByName(id, out pv))
            {
                digital = (Digital)pv;
            }

            // does this ID exist in the database
            if (digital == null)
            {
                response.ResultMessage = ResultMessage.INVALID_ID;
                return(response);
            }

            // is this a valid command for this digital device
            if (!CommandValidator.ValidateDigitalCommand(digital, command))
            {
                response.ResultMessage = ResultMessage.INVALID_DIG_COMM;
                return(response);
            }


            RTU rtu;

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

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

                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(digital),
                            Value     = (ushort)command
                        }
                    };

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

                IORequests.EnqueueRequest(iorb);
                Console.WriteLine("enqued {0}", BitConverter.ToString(iorb.SendBuff, 0, 12));

                digital.Command = command;

                response.ResultMessage = ResultMessage.OK;
            }
            else
            {
                // rtu does not exist
            }

            return(response);
        }
コード例 #7
0
        /// <summary>
        /// Send Commands to simulator, to make its state consistent with RTDB
        /// </summary>
        public void InitializeSimulator()
        {
            List <ProcessVariable> pvs = dbContext.GetAllProcessVariables();

            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;
                    }
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Processing answers from Simulator - Process Controller
        /// </summary>
        public void ProcessPCAnwers()
        {
            while (!isShutdown)
            {
                bool           isSuccessful;
                IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful);

                if (isSuccessful)
                {
                    RTU rtu;
                    // sporno
                    //while (!Database.IsConfigurationRunning)
                    //    Thread.Sleep(100);
                    if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null)
                    {
                        switch (rtu.Protocol)
                        {
                        case IndustryProtocols.ModbusTCP:

                            ModbusHandler mdbHandler = new ModbusHandler();
                            mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength);

                            switch (mdbHandler.Response.FunCode)
                            {
                            case FunctionCodes.ReadDiscreteInput:
                            {
                                BitReadResponse response = (BitReadResponse)mdbHandler.Response;
                                ProcessVariable pv;
                                Digital         target = null;

                                if (rtu.GetProcessVariableByAddress(answer.ReqAddress, out pv))
                                {
                                    target = (Digital)pv;
                                }

                                if (target != null)
                                {
                                    int[] array = new int[1];
                                    response.BitValues.CopyTo(array, 0);

                                    try
                                    {
                                        if (target.State != target.ValidStates[array[0]])
                                        {
                                            Console.WriteLine("CHANGE!");
                                            target.State = target.ValidStates[array[0]];

                                            ScadaModelParser parser = new ScadaModelParser();
                                            parser.SerializeScadaModel();

                                            DMSClient dMSClient = new DMSClient();
                                            dMSClient.ChangeOnSCADA(target.Name, target.State);
                                        }
                                    }
                                    catch
                                    {
                                        // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                    }
                                }
                            }

                            break;

                            case FunctionCodes.ReadInputRegisters:
                            {
                                RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response;
                                ProcessVariable      pv;

                                Analog target = null;

                                // i ovde se zapravo cita iz baze! preko RTUa. znaci pristupamo rtuu, a moguce je da se desava rekonfiguracija.
                                if (rtu.GetProcessVariableByAddress(answer.ReqAddress, out pv))
                                {
                                    target = (Analog)pv;
                                }

                                if (target != null)
                                {
                                    ushort newRawAcqValue = response.RegValues[0];

                                    try
                                    {
                                        float newAcqValue;
                                        AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue);

                                        // videti kad menjas kommande
                                        if (target.AcqValue != newAcqValue)
                                        {
                                            Console.WriteLine("CHANGE analog!");
                                            target.RawAcqValue = newRawAcqValue;
                                            target.AcqValue    = newAcqValue;

                                            ScadaModelParser parser = new ScadaModelParser();
                                            parser.SerializeScadaModel();

                                            DMSClient dMSClient = new DMSClient();
                                            // to do
                                            // dMSClient.ChangeOnSCADA(target.Name, target.State);
                                        }
                                    }
                                    catch
                                    {
                                        // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name);
                                    }
                                }
                            }

                            break;
                            }

                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine("Answer disposed. Process Controller with name ={0} does not exit.", answer.ProcessControllerName);
                    }
                }

                Thread.Sleep(100);
            }

            Console.WriteLine("ProcessPCAnswers.shutdown=true");
            return;
        }
コード例 #9
0
        /// <summary>
        /// Producing IORB requests for automatic data acquistion
        /// </summary>
        public void StartAcquisition()
        {
            DBContext.OnAnalogAdded += OnAnalogAddedEvent;

            List <ProcessVariable> pvs;

            while (!isShutdown)
            {
                // sporno to do:
                //while (!Database.IsConfigurationRunning)
                //    Thread.Sleep(100);

                pvs = dbContext.GetAllProcessVariables();
                foreach (ProcessVariable pv in pvs)
                {
                    IORequestBlock iorb = new IORequestBlock()
                    {
                        RequestType           = RequestType.SEND_RECV,
                        ProcessControllerName = pv.ProcContrName
                    };

                    RTU rtu;
                    if ((rtu = dbContext.GetRTUByName(pv.ProcContrName)) != null)
                    {
                        iorb.ReqAddress = (ushort)rtu.GetAcqAddress(pv);

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

                            ModbusHandler mdbHandler = new ModbusHandler();

                            // header is same for all read - acquistion requests
                            mdbHandler.Header = new ModbusApplicationHeader()
                            {
                                TransactionId = 0,
                                Length        = 5,
                                ProtocolId    = (ushort)IndustryProtocols.ModbusTCP,
                                DeviceAddress = rtu.Address
                            };

                            mdbHandler.Request = new ReadRequest()
                            {
                                StartAddr = iorb.ReqAddress
                            };

                            switch (pv.Type)
                            {
                            case VariableTypes.DIGITAL:

                                Digital digital = (Digital)pv;

                                mdbHandler.Request.FunCode = FunctionCodes.ReadDiscreteInput;
                                ((ReadRequest)mdbHandler.Request).Quantity = (ushort)(Math.Floor((Math.Log(digital.ValidStates.Count, 2))));

                                break;

                            case VariableTypes.ANALOG:
                                Analog analog = (Analog)pv;
                                if (!analog.IsInit)
                                {
                                    continue;         // dok se ne setuje inicijalna vrednost
                                }
                                mdbHandler.Request.FunCode = FunctionCodes.ReadInputRegisters;
                                ((ReadRequest)mdbHandler.Request).Quantity = analog.NumOfRegisters;

                                break;

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

                                break;
                            }

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

                        iorb.SendMsgLength = iorb.SendBuff.Length;
                        //if (pv.Name == "MEAS_AN_1")
                        //  Console.WriteLine(BitConverter.ToString(iorb.SendBuff, 0, 12));
                        IORequests.EnqueueRequest(iorb);
                    }
                    else
                    {
                        // ne postoji taj rtu sa tim imenom. izbrisati te procesne varijable sa rtu-om tog imena
                        Console.WriteLine("Invalid config: ProcContrName = {0} does not exists.", pv.ProcContrName);
                        continue;
                    }
                }
                Thread.Sleep(millisecondsTimeout: timerMsc);
            }

            Console.WriteLine("StartAcq.shutdown=true");
            return;
        }