コード例 #1
0
        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            AcquisitionCycle acquisitionCycle;
            IScadaConfigData configData;

            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                acquisitionCycle = new AcquisitionCycle();
                var readAccessClient = ScadaModelReadAccessClient.CreateClient();
                configData = await readAccessClient.GetScadaConfigData();

                string message = $"{baseLogString} RunAsync => AcquisitionCycle initialized.";
                Logger.LogInformation(message);
            }
            catch (Exception e)
            {
                string errMessage = $"{baseLogString} RunAsync => Exception caught: {e.Message}.";
                Logger.LogError(errMessage, e);
                throw e;
            }

            int acquisitionCycleCount = 0;

            while (true)
            {
                string message = $"{baseLogString} RunAsync => AcquisitionCycleCount: {acquisitionCycleCount}";

                if (acquisitionCycleCount % 100 == 0)
                {
                    Logger.LogInformation(message);
                }
                else if (acquisitionCycleCount % 10 == 0)
                {
                    Logger.LogDebug(message);
                }
                else
                {
                    Logger.LogVerbose(message);
                }

                try
                {
                    await acquisitionCycle.Start();

                    message = $"{baseLogString} RunAsync => AcquisitionCycle executed.";
                    Logger.LogVerbose(message);
                }
                catch (Exception e)
                {
                    string errMessage = $"{baseLogString} RunAsync => Exception caught: {e.Message}";
                    Logger.LogError(errMessage, e);
                }

                await Task.Delay(TimeSpan.FromMilliseconds(configData.AcquisitionInterval), cancellationToken);

                acquisitionCycleCount++;
            }
        }
コード例 #2
0
        /// <summary>
        /// This is the main entry point for your service instance.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            IScadaConfigData configData;

            try
            {
                InitializeReliableCollections();
                string debugMessage = $"{baseLogString} RunAsync => ReliableDictionaries initialized.";
                Logger.LogDebug(debugMessage);

                IScadaModelReadAccessContract readAccessClient = ScadaModelReadAccessClient.CreateClient();
                configData = await readAccessClient.GetScadaConfigData();

                string infoMessage = $"{baseLogString} RunAsync => FunctionExecutorCycle initialized.";
                Logger.LogInformation(infoMessage);
            }
            catch (Exception e)
            {
                string errorMessage = $"{baseLogString} RunAsync => exception {e.Message}";
                Logger.LogError(errorMessage, e);
                throw e;
            }

            var functionExecutionCycleCount = 0;

            while (true)
            {
                string message = $"{baseLogString} RunAsync => FunctionExecutionCycleCount: {functionExecutionCycleCount}";

                if (functionExecutionCycleCount % 100 == 0)
                {
                    Logger.LogInformation(message);
                }
                else if (functionExecutionCycleCount % 10 == 0)
                {
                    Logger.LogDebug(message);
                }
                else
                {
                    Logger.LogVerbose(message);
                }

                try
                {
                    await functionExecutorCycle.Start();

                    string verboseMessage = $"{baseLogString} RunAsync => FunctionExecutorCycle executed.";
                    Logger.LogVerbose(verboseMessage);
                }
                catch (Exception e)
                {
                    string errorMessage = $"{baseLogString} RunAsync => exception {e.Message}";
                    Logger.LogError(errorMessage, e);
                }

                await Task.Delay(TimeSpan.FromMilliseconds(configData.FunctionExecutionInterval), cancellationToken);

                functionExecutionCycleCount++;
            }
        }
コード例 #3
0
        public async Task <bool> SendMultipleAnalogCommand(Dictionary <long, float> commandingValues, CommandOriginType commandOriginType)
        {
            if (commandingValues.Count == 0)
            {
                string warnMessage = $"{baseLogString} SendMultipleAnalogCommand => commandingValues is empty and thus aborting the call.";
                Logger.LogWarning(warnMessage);
                return(false);
            }

            #region Log commanding values
            var sb = new StringBuilder();

            foreach (var kvp in commandingValues)
            {
                sb.AppendLine($"Gid: 0x{kvp.Key:X16} | Value: {kvp.Value}");
            }

            Logger.LogInformation($"{baseLogString} SendMultipleAnalogCommand => Origin: {commandOriginType} Values {Environment.NewLine}{sb}");
            #endregion Log commanding values

            ushort startAddress = 1; //EasyModbus spec
            IScadaModelReadAccessContract           scadaModelReadAccessClient = ScadaModelReadAccessClient.CreateClient();
            Dictionary <long, IScadaModelPointItem> gidToPointItemMap          = await scadaModelReadAccessClient.GetGidToPointItemMap();

            Dictionary <short, Dictionary <ushort, long> > addressToGidMap = await scadaModelReadAccessClient.GetAddressToGidMap();

            if (gidToPointItemMap == null)
            {
                string message = $"{baseLogString} SendMultipleAnalogCommand => SCADA model is null.";
                Logger.LogError(message);
                return(false);
            }

            int   analogOutputCount        = addressToGidMap[(short)PointType.ANALOG_OUTPUT].Count;
            int[] multipleCommandingValues = new int[addressToGidMap[(short)PointType.ANALOG_OUTPUT].Count];

            foreach (ushort address in addressToGidMap[(short)PointType.ANALOG_OUTPUT].Keys)
            {
                long gid = addressToGidMap[(short)PointType.ANALOG_OUTPUT][address];

                if (!gidToPointItemMap.ContainsKey(gid))
                {
                    string message = $"{baseLogString} SendMultipleAnalogCommand => Entity with gid: 0x{gid:X16} does not exist in current SCADA model.";
                    Logger.LogError(message);
                    return(false);
                }
                else if (!(gidToPointItemMap[gid] is IAnalogPointItem analogPointItem))
                {
                    string message = $"{baseLogString} SendMultipleAnalogCommand => Entity with gid: 0x{gid:X16} does not implement IAnalogPointItem interface.";
                    Logger.LogError(message);
                    return(false);
                }
コード例 #4
0
        public async Task Start()
        {
            string verboseMessage = $"{baseLogString} entering Start method.";

            Logger.LogVerbose(verboseMessage);

            try
            {
                var commandEnqueuerClient = ReadCommandEnqueuerClient.CreateClient();
                var readAccessClient      = ScadaModelReadAccessClient.CreateClient();

                verboseMessage = $"{baseLogString} Start => Trying to get AddressToGidMap.";
                Logger.LogVerbose(verboseMessage);

                //LOGIC
                addressToGidMap.Clear();
                addressToGidMap = await readAccessClient.GetAddressToGidMap();

                verboseMessage = $"{baseLogString} Start => AddressToGidMap received, Count: {addressToGidMap.Count}.";
                Logger.LogVerbose(verboseMessage);

                foreach (var kvp in addressToGidMap)
                {
                    if ((PointType)kvp.Key == PointType.HR_LONG)
                    {
                        continue;
                    }

                    verboseMessage = $"{baseLogString} Start => AddressToGidMap value for key {kvp.Key} is dictionary with Count: {kvp.Value.Count}.";
                    Logger.LogVerbose(verboseMessage);

                    if (TryCreateModbusFunction(kvp, out IReadModbusFunction modbusFunction))
                    {
                        //KEY LOGIC
                        await commandEnqueuerClient.EnqueueReadCommand(modbusFunction);

                        verboseMessage = $"{baseLogString} Start => Modbus function enquided. Point type is {kvp.Key}, FunctionCode: {modbusFunction.FunctionCode}, StartAddress: {modbusFunction.StartAddress}, Quantity: {modbusFunction.Quantity}.";
                        Logger.LogVerbose(verboseMessage);
                    }
                }
            }
            catch (Exception e)
            {
                string message = $"{baseLogString} Start => Exception caught.";
                Logger.LogError(message, e);
                throw e;
            }
        }
コード例 #5
0
        public async Task <bool> SendMultipleAnalogCommand(Dictionary <long, float> commandingValues, CommandOriginType commandOriginType)
        {
            if (commandingValues.Count == 0)
            {
                string warnMessage = $"{baseLogString} SendMultipleAnalogCommand => commandingValues is empty and thus aborting the call.";
                Logger.LogWarning(warnMessage);
                return(false);
            }

            ushort startAddress = 1; //EasyModbus spec
            IScadaModelReadAccessContract           scadaModelReadAccessClient = ScadaModelReadAccessClient.CreateClient();
            Dictionary <long, IScadaModelPointItem> gidToPointItemMap          = await scadaModelReadAccessClient.GetGidToPointItemMap();

            Dictionary <short, Dictionary <ushort, long> > addressToGidMap = await scadaModelReadAccessClient.GetAddressToGidMap();

            if (gidToPointItemMap == null)
            {
                string message = $"{baseLogString} SendMultipleAnalogCommand => SCADA model is null.";
                Logger.LogError(message);
                //throw new InternalSCADAServiceException(message);
                return(false);
            }

            int analogOutputCount = addressToGidMap[(short)PointType.ANALOG_OUTPUT].Count;

            int[] multipleCommandingValues = new int[addressToGidMap[(short)PointType.ANALOG_OUTPUT].Count];

            //for (ushort address = 1; address <= analogOutputCount; address++)
            //{
            foreach (ushort address in addressToGidMap[(short)PointType.ANALOG_OUTPUT].Keys)
            {
                long gid = addressToGidMap[(short)PointType.ANALOG_OUTPUT][address];

                if (!gidToPointItemMap.ContainsKey(gid))
                {
                    string message = $"{baseLogString} SendMultipleAnalogCommand => Entity with gid: 0x{gid:X16} does not exist in current SCADA model.";
                    Logger.LogError(message);
                    //throw new ArgumentException(message);
                    return(false);
                }
                else if (!(gidToPointItemMap[gid] is IAnalogPointItem analogPointItem))
                {
                    string message = $"{baseLogString} SendMultipleAnalogCommand => Entity with gid: 0x{gid:X16} does not implement IAnalogPointItem interface.";
                    Logger.LogError(message);
                    //throw new InternalSCADAServiceException(message);
                    return(false);
                }
コード例 #6
0
        private async Task InitializeModbusClient()
        {
            try
            {
                var modelReadAccessClient = ScadaModelReadAccessClient.CreateClient();
                this.configData = await modelReadAccessClient.GetScadaConfigData();

                this.modbusClient = new ModbusClient(configData.IpAddress.ToString(), configData.TcpPort);
            }
            catch (Exception e)
            {
                string message = $"{baseLogString} InitializeModbusClient => Exception: {e.Message}.";
                Logger.LogError(message, e);
            }

            if (modbusClient == null)
            {
                string message = $"{baseLogString} InitializeModbusClient => ModbusClient is null";
                Logger.LogError(message);
                throw new Exception(message);
            }
        }
コード例 #7
0
        private async Task ExecuteWriteMultipleAnalogCommand(ushort startAddress, int[] commandValues, CommandOriginType commandOrigin)
        {
            StringBuilder commandValuesSB = new StringBuilder();

            commandValuesSB.Append("[ ");
            foreach (int value in commandValues)
            {
                commandValuesSB.Append(value);
                commandValuesSB.Append(" ");
            }
            commandValuesSB.Append("]");

            string verboseMessage = $"{baseLogString} entering ExecuteWriteMultipleAnalogCommand method, command's startAddress: {startAddress}, commandValues: {commandValuesSB}, commandOrigin: {commandOrigin}.";

            Logger.LogVerbose(verboseMessage);

            //LOGIC
            var modelReadAccessClient   = ScadaModelReadAccessClient.CreateClient();
            var modelUpdateAccessClient = ScadaModelUpdateAccessClient.CreateClient();

            int quantity        = commandValues.Length;
            var addressToGidMap = await modelReadAccessClient.GetAddressToGidMap();

            //this.commandDescriptions = new Dictionary<long, CommandDescription>();
            this.commandDescriptions.Clear();

            //LOGIC
            for (ushort index = 0; index < quantity; index++)
            {
                ushort address = (ushort)(startAddress + index);

                var pointType = (short)PointType.ANALOG_OUTPUT;

                if (!addressToGidMap.ContainsKey(pointType))
                {
                    Logger.LogWarning($"{baseLogString} ExecuteWriteMultipleAnalogCommand => Point type: {pointType} is not in the current addressToGidMap.");
                    continue;
                }

                if (addressToGidMap[pointType].ContainsKey(address))
                {
                    long gid = addressToGidMap[pointType][address];

                    CommandDescription commandDescription = new CommandDescription()
                    {
                        Gid           = gid,
                        Address       = address,
                        Value         = commandValues[index],
                        CommandOrigin = commandOrigin,
                    };

                    //LOGIC
                    this.commandDescriptions.Add(gid, commandDescription);

                    string message = $"{baseLogString} ExecuteWriteMultipleAnalogCommand => CommandDescription added to the collection of commandDescriptions. Gid: {commandDescription.Gid:X16}, Address: {commandDescription.Address}, Value: {commandDescription.Value}, CommandOrigin: {commandDescription.CommandOrigin}";
                    Logger.LogInformation(message);
                }
            }

            string debugMessage = $"{baseLogString} ExecuteWriteMultipleAnalogCommand => About to send collection of CommandDescriptions to CommandDescriptionCache. collection count: {commandDescriptions.Count}";

            Logger.LogDebug(debugMessage);

            //LOGIC
            await modelUpdateAccessClient.AddOrUpdateMultipleCommandDescriptions(this.commandDescriptions);

            debugMessage = $"{baseLogString} ExecuteWriteMultipleAnalogCommand => about to call ModbusClient.WriteMultipleRegisters({startAddress - 1}, {commandValuesSB}) method. StartAddress: {startAddress}, Quantity: {quantity}";
            Logger.LogDebug(debugMessage);

            //KEY LOGIC
            modbusClient.WriteMultipleRegisters(startAddress - 1, commandValues);

            string infoMessage = $"{baseLogString} ExecuteWriteMultipleAnalogCommand => ModbusClient.WriteMultipleRegisters() method SUCCESSFULLY executed. StartAddress: {startAddress}, Quantity: {quantity}";

            Logger.LogInformation(infoMessage);
        }
コード例 #8
0
        private async Task ExecuteWriteSingleCommand(IWriteSingleFunction writeCommand)
        {
            string verboseMessage = $"{baseLogString} entering ExecuteWriteSingleCommand method, command's FunctionCode: {writeCommand.FunctionCode}.";

            Logger.LogVerbose(verboseMessage);

            ushort outputAddress = writeCommand.OutputAddress;
            int    commandValue  = writeCommand.CommandValue;

            if (outputAddress >= ushort.MaxValue || outputAddress == ushort.MinValue)
            {
                string message = $"{baseLogString} ExecuteWriteSingleCommand => Address is out of bound. Output address: {outputAddress}.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            if (writeCommand.FunctionCode != ModbusFunctionCode.WRITE_SINGLE_COIL && writeCommand.FunctionCode != ModbusFunctionCode.WRITE_SINGLE_REGISTER)
            {
                string errorMessage = $"{baseLogString} ExecuteWriteSingleCommand => function code is neither ModbusFunctionCode.READ_HOLDING_REGISTERS nor ModbusFunctionCode.READ_INPUT_REGISTERS";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }

            var modelReadAccessClient   = ScadaModelReadAccessClient.CreateClient();
            var modelUpdateAccessClient = ScadaModelUpdateAccessClient.CreateClient();

            //LOGIC
            var addressToGidMap = await modelReadAccessClient.GetAddressToGidMap();

            var pointType = writeCommand.FunctionCode == ModbusFunctionCode.WRITE_SINGLE_COIL ? PointType.DIGITAL_OUTPUT : PointType.ANALOG_OUTPUT;

            if (!addressToGidMap.ContainsKey((short)pointType))
            {
                Logger.LogWarning($"{baseLogString} ExecuteAnalogReadCommand => Point type: {pointType} is not in the current addressToGidMap.");
                return;
            }

            if (addressToGidMap[(short)pointType].ContainsKey(outputAddress))
            {
                long gid = addressToGidMap[(short)pointType][outputAddress];

                CommandDescription commandDescription = new CommandDescription()
                {
                    Gid           = gid,
                    Address       = outputAddress,
                    Value         = commandValue,
                    CommandOrigin = writeCommand.CommandOrigin,
                };

                string debugMessage = $"{baseLogString} ExecuteWriteSingleCommand => About to send CommandDescription to CommandDescriptionCache. Gid: {commandDescription.Gid:X16}, Address: {commandDescription.Address}, Value: {commandDescription.Value}, CommandOrigin: {commandDescription.CommandOrigin}";
                Logger.LogDebug(debugMessage);

                //LOGIC
                await modelUpdateAccessClient.AddOrUpdateCommandDescription(gid, commandDescription);

                string infoMessage = $"{baseLogString} ExecuteWriteSingleCommand => CommandDescription sent successfuly to CommandDescriptionCache. Gid: {commandDescription.Gid:X16}, Address: {commandDescription.Address}, Value: {commandDescription.Value}, CommandOrigin: {commandDescription.CommandOrigin}";
                Logger.LogInformation(infoMessage);
            }

            if (writeCommand.FunctionCode == ModbusFunctionCode.WRITE_SINGLE_COIL)
            {
                bool booleanCommand;
                if (commandValue == 0)
                {
                    booleanCommand = false;
                }
                else if (commandValue == 1)
                {
                    booleanCommand = true;
                }
                else
                {
                    string errorMessage = $"{baseLogString} ExecuteWriteSingleCommand => Non-boolean value in write single coil command parameter.";
                    Logger.LogError(errorMessage);
                    throw new ArgumentException(errorMessage);
                }

                string debugMessage = $"{baseLogString} ExecuteWriteSingleCommand => about to call ModbusClient.WriteSingleCoil({outputAddress - 1}, {booleanCommand}) method. OutputAddress: {outputAddress}";
                Logger.LogDebug(debugMessage);

                //KEY LOGIC
                modbusClient.WriteSingleCoil(outputAddress - 1, booleanCommand);

                string infoMessage = $"{baseLogString} ExecuteWriteSingleCommand => ModbusClient.WriteSingleCoil({outputAddress - 1}, {booleanCommand}) method SUCCESSFULLY executed. OutputAddress: {outputAddress}";
                Logger.LogInformation(infoMessage);
            }
            else if (writeCommand.FunctionCode == ModbusFunctionCode.WRITE_SINGLE_REGISTER)
            {
                string debugMessage = $"{baseLogString} ExecuteWriteSingleCommand => about to call ModbusClient.WriteSingleRegister({outputAddress - 1}, {commandValue}) method. OutputAddress: {outputAddress}";
                Logger.LogDebug(debugMessage);

                //KEY LOGIC
                modbusClient.WriteSingleRegister(outputAddress - 1, commandValue);

                string infoMessage = $"{baseLogString} ExecuteWriteSingleCommand => ModbusClient.WriteSingleRegister({outputAddress - 1}, {commandValue}) method SUCCESSFULLY executed. OutputAddress: {outputAddress}";
                Logger.LogInformation(infoMessage);
            }
        }
コード例 #9
0
        private async Task ExecuteAnalogReadCommand(ModbusFunctionCode functionCode, ushort startAddress, ushort quantity)
        {
            string verboseMessage = $"{baseLogString} entering ExecuteAnalogReadCommand method, command's functionCode: {functionCode}, startAddress: {startAddress}, quantity:{quantity}.";

            Logger.LogVerbose(verboseMessage);

            int[]     data;
            PointType pointType;

            if (functionCode == ModbusFunctionCode.READ_HOLDING_REGISTERS)
            {
                verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => about to call ModbusClient.ReadHoldingRegisters({startAddress - 1}, {quantity}) method.";
                Logger.LogVerbose(verboseMessage);

                //KEY LOGIC
                pointType = PointType.ANALOG_OUTPUT;
                data      = modbusClient.ReadHoldingRegisters(startAddress - 1, quantity);

                verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => ModbusClient.ReadHoldingRegisters({startAddress - 1}, {quantity}) method SUCCESSFULLY executed. Resulting data count: {data.Length}.";
                Logger.LogVerbose(verboseMessage);
            }
            else if (functionCode == ModbusFunctionCode.READ_INPUT_REGISTERS)
            {
                verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => about to call ModbusClient.ReadInputRegisters({startAddress - 1}, {quantity}) method.";
                Logger.LogVerbose(verboseMessage);

                //KEY LOGIC
                pointType = PointType.ANALOG_INPUT;
                data      = modbusClient.ReadInputRegisters(startAddress - 1, quantity);

                verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => ModbusClient.ReadInputRegisters({startAddress - 1}, {quantity}) method SUCCESSFULLY executed. Resulting data count: {data.Length}.";
                Logger.LogVerbose(verboseMessage);
            }
            else
            {
                string message = $"{baseLogString} ExecuteAnalogReadCommand => function code is neither ModbusFunctionCode.READ_HOLDING_REGISTERS nor ModbusFunctionCode.READ_INPUT_REGISTERS";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            //this.analogMeasurementCache = new Dictionary<long, AnalogModbusData>(data.Length);
            this.analogMeasurementCache.Clear();

            var modelReadAccessClient   = ScadaModelReadAccessClient.CreateClient();
            var modelUpdateAccessClient = ScadaModelUpdateAccessClient.CreateClient();

            var gidToPointItemMap = await modelReadAccessClient.GetGidToPointItemMap();

            var addressToGidMap = await modelReadAccessClient.GetAddressToGidMap();

            var commandDescriptionCache = await modelReadAccessClient.GetCommandDescriptionCache();

            for (ushort i = 0; i < data.Length; i++)
            {
                ushort address  = (ushort)(startAddress + i);
                int    rawValue = data[i];

                if (!addressToGidMap.ContainsKey((short)pointType))
                {
                    Logger.LogWarning($"{baseLogString} ExecuteAnalogReadCommand => Point type: {pointType} is not in the current addressToGidMap.");
                    continue;
                }

                //for commands enqueued during model update, that are not valid
                if (!addressToGidMap[(short)pointType].ContainsKey(address))
                {
                    Logger.LogWarning($"{baseLogString} ExecuteAnalogReadCommand => trying to read value on address {address}, Point type: {pointType}, which is not in the current addressToGidMap.");
                    continue;
                }

                long gid = addressToGidMap[(short)pointType][address];

                //for commands enqueued during model update, that are not valid
                if (!gidToPointItemMap.ContainsKey(gid))
                {
                    Logger.LogWarning($"{baseLogString} ExecuteAnalogReadCommand => trying to read value for measurement with gid: 0x{gid:X16}, which is not in the current SCADA Model.");
                    continue;
                }

                if (!(gidToPointItemMap[gid] is IAnalogPointItem pointItem))
                {
                    string message = $"{baseLogString} ExecuteAnalogReadCommand => PointItem [Gid: 0x{gid:X16}] does not implement {typeof(IAnalogPointItem)}.";
                    Logger.LogError(message);
                    throw new Exception(message);
                }

                //KEY LOGIC
                if (pointItem.CurrentRawValue != rawValue)
                {
                    pointItem = (IAnalogPointItem)(await modelUpdateAccessClient.UpdatePointItemRawValue(pointItem.Gid, rawValue));
                    Logger.LogInformation($"{baseLogString} ExecuteAnalogReadCommand => Alarm for Point [Gid: 0x{pointItem.Gid:X16}, Address: {pointItem.Address}] set to {pointItem.Alarm}.");
                }

                //LOGIC
                CommandOriginType commandOrigin = CommandOriginType.UNKNOWN_ORIGIN;

                if (commandDescriptionCache.ContainsKey(gid) && commandDescriptionCache[gid].Value == pointItem.CurrentRawValue)
                {
                    commandOrigin = commandDescriptionCache[gid].CommandOrigin;
                    await modelUpdateAccessClient.RemoveCommandDescription(gid);

                    Logger.LogDebug($"{baseLogString} ExecuteAnalogReadCommand => Command origin of command address: {pointItem.Address} is set to {commandOrigin}.");

                    //LOGIC
                    AnalogModbusData analogData = new AnalogModbusData(pointItem.CurrentEguValue, pointItem.Alarm, gid, commandOrigin);
                    this.analogMeasurementCache.Add(gid, analogData);

                    verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => AnalogModbusData added to measurementCache. MeasurementGid: {analogData.MeasurementGid:X16}, Value: {analogData.Value}, Alarm: {analogData.Alarm}, CommandOrigin: {analogData.CommandOrigin} .";
                    Logger.LogVerbose(verboseMessage);
                }
            }

            //LOGIC
            await modelUpdateAccessClient.MakeAnalogEntryToMeasurementCache(this.analogMeasurementCache, true);

            verboseMessage = $"{baseLogString} ExecuteAnalogReadCommand => MakeAnalogEntryToMeasurementCache method called. measurementCache count: {this.analogMeasurementCache.Count}.";
            Logger.LogVerbose(verboseMessage);
        }
コード例 #10
0
        public async Task <bool> SendSingleAnalogCommand(long gid, float commandingValue, CommandOriginType commandOriginType)
        {
            string verboseMessage = $"{baseLogString} SendSingleAnalogCommand method called. gid: {gid:X16}, commandingValue: {commandingValue}, commandOriginType: {commandOriginType}";

            Logger.LogVerbose(verboseMessage);

            IScadaModelReadAccessContract           scadaModelReadAccessClient = ScadaModelReadAccessClient.CreateClient();
            Dictionary <long, IScadaModelPointItem> gidToPointItemMap          = await scadaModelReadAccessClient.GetGidToPointItemMap();

            if (gidToPointItemMap == null)
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => SendSingleAnalogCommand => SCADA model is null.";
                Logger.LogError(message);
                //throw new InternalSCADAServiceException(message);
                return(false);
            }

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

            IScadaModelPointItem pointItem = gidToPointItemMap[gid];

            if (!(pointItem is IAnalogPointItem analogPointItem && pointItem.RegisterType == PointType.ANALOG_OUTPUT))
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => Either RegistarType of entity with gid: 0x{gid:X16} is not ANALOG_OUTPUT or entity does not implement IAnalogPointItem interface.";
                Logger.LogError(message);
                //throw new ArgumentException(message);
                return(false);
            }

            try
            {
                if (!analogPointItem.Initialized)
                {
                    string errorMessage = $"{baseLogString} SendSingleAnalogCommand => PointItem was initialized. Gid: 0x{analogPointItem.Gid:X16}, Addres: {analogPointItem.Address}, Name: {analogPointItem.Name}, RegisterType: {analogPointItem.RegisterType}, Initialized: {analogPointItem.Initialized}";
                    Logger.LogError(errorMessage);
                }

                //LOGIC
                int modbusValue = analogPointItem.EguToRawValueConversion(commandingValue);

                string debugMessage = $"{baseLogString} SendSingleAnalogCommand => Calling SendSingleCommand({pointItem}, {modbusValue}, {commandOriginType})";
                Logger.LogDebug(verboseMessage);

                //KEY LOGIC
                await SendSingleCommand(pointItem, modbusValue, commandOriginType);

                debugMessage = $"{baseLogString} SendSingleAnalogCommand => SendSingleCommand() executed SUCCESSFULLY";
                Logger.LogDebug(debugMessage);

                return(true);
            }
            catch (Exception e)
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => Exception in SendAnalogCommand() method.";
                Logger.LogError(message, e);
                //throw new InternalSCADAServiceException(message, e);
                return(false);
            }
        }