예제 #1
0
 public ReadDiscreteInputsFunction(ModbusCommandParameters commandParameters, SCADAModel scadaModel)
     : base(commandParameters)
 {
     CheckArguments(MethodBase.GetCurrentMethod(), typeof(ModbusReadCommandParameters));
     SCADAModel = scadaModel;
     ModbusReadCommandParameters = commandParameters as IModbusReadCommandParameters;
     Data = new Dictionary <long, DiscreteModbusData>();
 }
예제 #2
0
        public Acquisition(IReadCommandEnqueuer readCommandEnqueuer, SCADAModel scadaModel)
        {
            this.readCommandEnqueuer = readCommandEnqueuer;
            this.scadaModel          = scadaModel;
            this.scadaConfig         = SCADAConfigData.Instance;

            InitializeAcquisitionThread();
        }
예제 #3
0
        public void Rollback()
        {
            lock (updateLock)
            {
                if (transactionModel != null)
                {
                    transactionModel.RollbackUpdate();
                    transactionModel = null;
                }

                inserted = null;
                updated  = null;
                deleted  = null;
            }
        }
        public FunctionExecutor(SCADAModel scadaModel)
        {
            this.modelUpdateQueue            = new ConcurrentQueue <IWriteModbusFunction>();
            this.writeCommandQueue           = new ConcurrentQueue <IWriteModbusFunction>();
            this.readCommandQueue            = new ConcurrentQueue <IReadModbusFunction>();
            this.commandEvent                = new AutoResetEvent(true);
            this.modelUpdateQueueEmptyEvent  = new AutoResetEvent(false);
            this.writeCommandQueueEmptyEvent = new AutoResetEvent(false);
            this.proxyFactory                = new ProxyFactory();

            SCADAModel = scadaModel;
            SCADAModel.SignalIncomingModelConfirmation += EnqueueModelUpdateCommands;

            ConfigData   = SCADAConfigData.Instance;
            ModbusClient = new ModbusClient(ConfigData.IpAddress.ToString(), ConfigData.TcpPort);
        }
예제 #5
0
        public void Commit()
        {
            lock (updateLock)
            {
                if (transactionModel == null)
                {
                    return;
                }

                transactionModel.CommitUpdate();
                SCADAModel.Instance = transactionModel;
                FieldProxy.Instance.UpdateModel();

                transactionModel = null;
            }
        }
        public SCADAService()
        {
            modelResourcesDesc = new ModelResourcesDesc();
            enumDescs          = new EnumDescs();
            scadaModel         = new SCADAModel(modelResourcesDesc, enumDescs);
            functionExecutor   = new FunctionExecutor(scadaModel);

            FunctionFactory.SCADAModel = scadaModel;
            SCADAModelUpdateNotification.SCADAModel = scadaModel;
            SCADATransactionActor.SCADAModel        = scadaModel;
            CommandService.SCADAModel         = scadaModel;
            IntegrityUpdateService.SCADAModel = scadaModel;

            CommandService.WriteCommandEnqueuer = functionExecutor;

            scadaModel.ImportModel();

            InitializeHosts();
        }
예제 #7
0
        public bool Prepare()
        {
            lock (updateLock)
            {
                if (inserted == null)
                {
                    return(false);
                }

                SCADAModelDownload download = new SCADAModelDownload(inserted, updated, deleted);

                if (!download.Download())
                {
                    return(false);
                }

                SCADAModel tModel = new SCADAModel(SCADAModel.Instance);

                if (!tModel.ApplyUpdate(download))
                {
                    return(false);
                }

                if (!tModel.PersistUpdate())
                {
                    return(false);
                }

                transactionModel = tModel;
                inserted         = null;
                updated          = null;
                deleted          = null;

                return(true);
            }
        }
예제 #8
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);
        }