コード例 #1
0
        public bool SendAnalogCommand(long gid, float commandingValue, CommandOriginType commandOriginType)
        {
            bool success;

            if (CommandService.scadaModel == null)
            {
                string message = $"SendAnalogCommand => SCADA model is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            var currentScadaModel = CommandService.scadaModel.CurrentScadaModel;

            if (!currentScadaModel.ContainsKey(gid))
            {
                string message = $"Entity with gid: 0x{gid:X16} does not exist in current SCADA model.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            ISCADAModelPointItem pointItem = currentScadaModel[gid];

            if (pointItem is IAnalogSCADAModelPointItem analogPointItem && pointItem.RegisterType == PointType.ANALOG_OUTPUT)
            {
                try
                {
                    int modbusValue = analogPointItem.EguToRawValueConversion(commandingValue);
                    success = SendCommand(pointItem, modbusValue, commandOriginType);
                }
                catch (Exception e)
                {
                    string message = $"Exception in SendAnalogCommand() method.";
                    Logger.LogError(message, e);
                    throw new InternalSCADAServiceException(message, e);
                }
            }
コード例 #2
0
        public async Task <bool> Prepare()
        {
            bool success;

            try
            {
                //INIT INCOMING SCADA MODEL with current model values
                //can not go with just 'incomingScadaModel = new Dictionary<long, ISCADAModelPointItem>(CurrentScadaModel)' because IncomingAddressToGidMap must also be initialized
                incomingScadaModel = new Dictionary <long, ISCADAModelPointItem>(CurrentScadaModel.Count);

                foreach (long gid in CurrentScadaModel.Keys)
                {
                    ModelCode            type      = modelResourceDesc.GetModelCodeFromId(gid);
                    ISCADAModelPointItem pointItem = CurrentScadaModel[gid].Clone();

                    IncomingScadaModel.Add(gid, pointItem);

                    if (!IncomingAddressToGidMap[pointItem.RegisterType].ContainsKey(pointItem.Address))
                    {
                        IncomingAddressToGidMap[pointItem.RegisterType].Add(pointItem.Address, gid);
                    }
                }

                //IMPORT ALL measurements from NMS and create PointItems for them
                Dictionary <long, ISCADAModelPointItem> incomingPointItems = await CreatePointItemsFromNetworkModelMeasurements();

                //ORDER IS IMPORTANT due to IncomingAddressToGidMap validity: DELETE => UPDATE => INSERT

                foreach (long gid in modelChanges[DeltaOpType.Delete])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (!IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Deleting entity with gid: {gid}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem oldPointItem = IncomingScadaModel[gid];
                        IncomingScadaModel.Remove(gid);

                        IncomingAddressToGidMap[oldPointItem.RegisterType].Remove(oldPointItem.Address);
                    }
                }

                foreach (long gid in modelChanges[DeltaOpType.Update])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (!IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Updating entity with gid: 0x{gid:X16}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem incomingPointItem = incomingPointItems[gid];
                        ISCADAModelPointItem oldPointItem      = IncomingScadaModel[gid];

                        if (!IncomingAddressToGidMap[oldPointItem.RegisterType].ContainsKey(oldPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Updating point with address: {oldPointItem.Address}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        if (oldPointItem.Address != incomingPointItem.Address && IncomingAddressToGidMap[incomingPointItem.RegisterType].ContainsKey(incomingPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Trying to add point with address: {incomingPointItem.Address}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        IncomingScadaModel[gid] = incomingPointItem;

                        if (oldPointItem.Address != incomingPointItem.Address)
                        {
                            IncomingAddressToGidMap[oldPointItem.RegisterType].Remove(oldPointItem.Address);
                            IncomingAddressToGidMap[incomingPointItem.RegisterType].Add(incomingPointItem.Address, gid);
                        }
                    }
                }

                foreach (long gid in modelChanges[DeltaOpType.Insert])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Inserting gid: {gid}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem incomingPointItem = incomingPointItems[gid];

                        if (IncomingAddressToGidMap[incomingPointItem.RegisterType].ContainsKey(incomingPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Trying to add point with address: {incomingPointItem.Address}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        IncomingScadaModel.Add(gid, incomingPointItem);
                        IncomingAddressToGidMap[incomingPointItem.RegisterType].Add(incomingPointItem.Address, gid);
                    }
                }

                success = true;
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught in Prepare method on SCADAModel.", e);
                success = false;
            }

            return(success);
        }
コード例 #3
0
        public bool EnqueueModelUpdateCommands(List <long> measurementGids)
        {
            bool   success;
            ushort length = 6;

            Dictionary <long, AnalogModbusData>   analogData   = new Dictionary <long, AnalogModbusData>();
            Dictionary <long, DiscreteModbusData> discreteData = new Dictionary <long, DiscreteModbusData>();

            MeasurementsCache.Clear();

            try
            {
                Dictionary <long, ISCADAModelPointItem> currentScadaModel = SCADAModel.CurrentScadaModel;

                foreach (long measurementGID in measurementGids)
                {
                    ISCADAModelPointItem scadaPointItem = currentScadaModel[measurementGID];
                    IWriteModbusFunction modbusFunction;

                    if (scadaPointItem is IAnalogSCADAModelPointItem analogSCADAModelPointItem)
                    {
                        modbusFunction = FunctionFactory.CreateWriteModbusFunction(new ModbusWriteCommandParameters(length,
                                                                                                                    (byte)ModbusFunctionCode.WRITE_SINGLE_REGISTER,
                                                                                                                    analogSCADAModelPointItem.Address,
                                                                                                                    analogSCADAModelPointItem.CurrentRawValue),
                                                                                   CommandOriginType.MODEL_UPDATE_COMMAND);

                        AnalogModbusData analogModbusData = new AnalogModbusData(analogSCADAModelPointItem.CurrentEguValue,
                                                                                 analogSCADAModelPointItem.Alarm,
                                                                                 measurementGID,
                                                                                 CommandOriginType.MODEL_UPDATE_COMMAND);
                        analogData.Add(measurementGID, analogModbusData);
                    }
                    else if (scadaPointItem is IDiscreteSCADAModelPointItem discreteSCADAModelPointItem)
                    {
                        modbusFunction = FunctionFactory.CreateWriteModbusFunction(new ModbusWriteCommandParameters(length,
                                                                                                                    (byte)ModbusFunctionCode.WRITE_SINGLE_COIL,
                                                                                                                    discreteSCADAModelPointItem.Address,
                                                                                                                    discreteSCADAModelPointItem.CurrentValue),
                                                                                   CommandOriginType.MODEL_UPDATE_COMMAND);

                        DiscreteModbusData discreteModbusData = new DiscreteModbusData(discreteSCADAModelPointItem.CurrentValue,
                                                                                       discreteSCADAModelPointItem.Alarm,
                                                                                       measurementGID,
                                                                                       CommandOriginType.MODEL_UPDATE_COMMAND);
                        discreteData.Add(measurementGID, discreteModbusData);
                    }
                    else
                    {
                        Logger.LogWarn("Unknown type of ISCADAModelPointItem.");
                        continue;
                    }

                    this.modelUpdateQueue.Enqueue(modbusFunction);
                }

                MakeAnalogEntryToMeasurementCache(analogData, true);
                MakeDiscreteEntryToMeasurementCache(discreteData, false);

                success = true;
                this.writeCommandQueue = new ConcurrentQueue <IWriteModbusFunction>();
                this.readCommandQueue  = new ConcurrentQueue <IReadModbusFunction>();
                this.commandEvent.Set();
            }
            catch (Exception e)
            {
                success = false;
                string message = "Exception caught in EnqueueModelUpdateCommands() method.";
                Logger.LogError(message, e);
            }

            return(success);
        }