Ejemplo n.º 1
0
        public List <KeyValuePair <long, float> > ReadAnalog(List <long> gids)
        {
            List <KeyValuePair <long, float> > result = new List <KeyValuePair <long, float> >(gids.Count);

            foreach (long gid in gids)
            {
                Analog a = model.GetAnalog(gid);

                if (a == null || a.BaseAddress < 0 || a.BaseAddress > ushort.MaxValue / 2)
                {
                    continue;
                }

                ushort address = (ushort)(a.BaseAddress * 2);
                ushort high, low;

                if (!inputRegisters.TryGetValue(address, out high) || !inputRegisters.TryGetValue((ushort)(address + 1), out low))
                {
                    continue;
                }

                float value;
                GetValues(high, low, out value, out _);

                result.Add(new KeyValuePair <long, float>(gid, value));
            }

            return(result);
        }
Ejemplo n.º 2
0
        public void UpdateModel()
        {
            SCADAModel model = SCADAModel.Instance;

            if (model == null)
            {
                return;
            }

            Dictionary <int, List <long> > byAddress = new Dictionary <int, List <long> >();
            List <ushort> inputAddresses             = new List <ushort>();

            foreach (Analog a in model.GetAllAnalogs())
            {
                if (a == null || !IsValidAddress(a.BaseAddress))
                {
                    continue;
                }

                List <long> gids;
                if (byAddress.TryGetValue(a.BaseAddress, out gids))
                {
                    gids.Add(a.GID);
                }
                else
                {
                    byAddress[a.BaseAddress] = new List <long>(1)
                    {
                        a.GID
                    };
                }

                if (a.Direction == SignalDirection.Write)
                {
                    continue;
                }

                ushort address = GetAddress(a.BaseAddress);
                inputAddresses.Add(address);
            }

            foreach (Discrete d in model.GetAllDiscretes())
            {
                if (d == null || !IsValidAddress(d.BaseAddress))
                {
                    continue;
                }

                List <long> gids;
                if (byAddress.TryGetValue(d.BaseAddress, out gids))
                {
                    gids.Add(d.GID);
                }
                else
                {
                    byAddress[d.BaseAddress] = new List <long>(1)
                    {
                        d.GID
                    };
                }

                if (d.Direction == SignalDirection.Write)
                {
                    continue;
                }

                ushort address = GetAddress(d.BaseAddress);
                inputAddresses.Add(address);
            }

            List <IModbusFunction> acquisitionFunctions = new List <IModbusFunction>();

            if (inputAddresses.Count <= 0)
            {
                return;
            }

            inputAddresses.Sort();

            int runStart = inputAddresses[0];
            int runCount = 0;

            for (int i = 0; i < inputAddresses.Count; ++i)
            {
                int address = inputAddresses[i];

                if (runCount < 124 && address == runStart + runCount)
                {
                    runCount += 2;
                }
                else if (runCount > 0)
                {
                    acquisitionFunctions.Add(new ReadInputRegistersFunction(new ModbusReadCommandParameters(6, (byte)EModbusFunctionCode.READ_INPUT_REGISTERS, (ushort)runStart, (ushort)runCount, 0, 1)));
                    runCount = 2;
                    runStart = address;
                }
            }

            if (runCount > 0)
            {
                acquisitionFunctions.Add(new ReadInputRegistersFunction(new ModbusReadCommandParameters(6, (byte)EModbusFunctionCode.READ_INPUT_REGISTERS, (ushort)runStart, (ushort)runCount, 0, 1)));
            }

            modelLock.EnterWriteLock();
            {
                this.model = model;
                this.acquisitionFunctions = acquisitionFunctions;
                this.byAddress            = byAddress;
            }
            modelLock.ExitWriteLock();

            List <KeyValuePair <long, float> > analogInputs    = new List <KeyValuePair <long, float> >();
            List <KeyValuePair <long, float> > analogOutputs   = new List <KeyValuePair <long, float> >();
            List <KeyValuePair <long, int> >   discreteInputs  = new List <KeyValuePair <long, int> >();
            List <KeyValuePair <long, int> >   discreteOutputs = new List <KeyValuePair <long, int> >();

            foreach (KeyValuePair <int, List <long> > addressEntry in byAddress)
            {
                ushort address = GetAddress(addressEntry.Key);
                ushort high, low;
                float  analogIn;
                int    discreteIn;
                float  analogOut;
                int    discreteOut;

                inputRegisters.TryGetValue(address, out high);
                inputRegisters.TryGetValue((ushort)(address + 1), out low);
                GetValues(high, low, out analogIn, out discreteIn);

                holdingRegisters.TryGetValue(address, out high);
                holdingRegisters.TryGetValue((ushort)(address + 1), out low);
                GetValues(high, low, out analogOut, out discreteOut);

                for (int i = 0; i < addressEntry.Value.Count; ++i)
                {
                    long gid = addressEntry.Value[i];

                    switch (ModelCodeHelper.GetTypeFromGID(gid))
                    {
                    case DMSType.Analog:
                        Analog a = model.GetAnalog(gid);

                        if (a == null)
                        {
                            continue;
                        }

                        switch (a.Direction)
                        {
                        case SignalDirection.Read:
                            analogInputs.Add(new KeyValuePair <long, float>(gid, analogIn));
                            break;

                        case SignalDirection.Write:
                            analogOutputs.Add(new KeyValuePair <long, float>(gid, analogOut));
                            break;

                        case SignalDirection.ReadWrite:
                            analogInputs.Add(new KeyValuePair <long, float>(gid, analogIn));
                            analogOutputs.Add(new KeyValuePair <long, float>(gid, analogOut));
                            break;

                        default:
                            continue;
                        }

                        break;

                    case DMSType.Discrete:
                        Discrete d = model.GetDiscrete(gid);

                        if (d == null)
                        {
                            continue;
                        }

                        switch (d.Direction)
                        {
                        case SignalDirection.Read:
                            discreteInputs.Add(new KeyValuePair <long, int>(gid, discreteIn));
                            break;

                        case SignalDirection.Write:
                            discreteOutputs.Add(new KeyValuePair <long, int>(gid, discreteOut));
                            break;

                        case SignalDirection.ReadWrite:
                            discreteInputs.Add(new KeyValuePair <long, int>(gid, discreteIn));
                            discreteOutputs.Add(new KeyValuePair <long, int>(gid, discreteOut));
                            break;

                        default:
                            continue;
                        }

                        break;

                    default:
                        continue;
                    }
                }
            }

            PublishMeasurementValues(analogInputs, analogOutputs, discreteInputs, discreteOutputs);
        }