public async Task Commit() { while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } try { await reliableDictionaryHelper.TryCopyToReliableDictionary <long, IScadaModelPointItem>(ReliableDictionaryNames.IncomingGidToPointItemMap, ReliableDictionaryNames.GidToPointItemMap, this.stateManager); await reliableDictionaryHelper.TryCopyToReliableDictionary <short, Dictionary <ushort, long> >(ReliableDictionaryNames.IncomingAddressToGidMap, ReliableDictionaryNames.AddressToGidMap, this.stateManager); await IncomingGidToPointItemMap.ClearAsync(); await IncomingAddressToGidMap.ClearAsync(); await ModelChanges.ClearAsync(); await CommandDescriptionCache.ClearAsync(); await MeasurementsCache.ClearAsync(); string message = $"{baseLogString} Commit => Incoming SCADA model is confirmed."; Logger.LogInformation(message); await SendModelUpdateCommands(); await LogAllReliableCollections(); } catch (Exception e) { string errorMessage = $"{baseLogString} Commit => Exception: {e.Message}"; Logger.LogError(errorMessage, e); } }
public async Task <Dictionary <long, CommandDescription> > GetCommandDescriptionCache() { string verboseMessage = $"{baseLogString} entering GetCommandDescriptionCache method."; Logger.LogVerbose(verboseMessage); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } verboseMessage = $"{baseLogString} GetCommandDescriptionCache => about to execut CommandDescriptionCache.GetDataCopy()."; Logger.LogVerbose(verboseMessage); var copy = await CommandDescriptionCache.GetDataCopyAsync(); if (copy.Count > 0) { var sb = new StringBuilder(); sb.AppendLine("GettingCommandDescriptionCache => elements:"); foreach (var element in copy.Values) { sb.AppendLine($"Gid: {element.Gid}, Address: {element.Address}, Value: {element.Value}, CommandOrigin: {element.CommandOrigin}"); } Logger.LogDebug(sb.ToString()); } verboseMessage = $"{baseLogString} GetCommandDescriptionCache => CommandDescriptionCache.GetDataCopy() SUCCESSFULLY executed. Returning the collection with {copy.Count} elements."; Logger.LogVerbose(verboseMessage); return(copy); }
public async Task AddOrUpdateMultipleCommandDescriptions(Dictionary <long, CommandDescription> commandDescriptions) { string verboseMessage = $"{baseLogString} entering AddOrUpdateMultipleCommandDescriptions method."; Logger.LogVerbose(verboseMessage); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } var tasks = new List <Task>(); foreach (var commandDescription in commandDescriptions.Values) { tasks.Add(Task.Run(async() => { await CommandDescriptionCache.SetAsync(commandDescription.Gid, commandDescription); string infoMessage = $"{baseLogString} AddOrUpdateMultipleCommandDescriptions => CommandDescription successfuly set to CommandDescriptionCache. Gid: {commandDescription.Gid:X16}, Address: {commandDescription.Address}, Value: {commandDescription.Value}, CommandOrigin: {commandDescription.CommandOrigin}"; Logger.LogInformation(infoMessage); })); } Task.WaitAll(tasks.ToArray()); string message = $"{baseLogString} AddOrUpdateMultipleCommandDescriptions => collection of CommandDescriptions SUCCESSFULLY set to CommandDescriptionCache. collection count: {commandDescriptions.Count}"; Logger.LogInformation(message); }
public async Task <bool> RemoveCommandDescription(long gid) { string verboseMessage = $"{baseLogString} entering RemoveCommandDescription method."; Logger.LogVerbose(verboseMessage); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } return((await CommandDescriptionCache.TryRemoveAsync(gid)).HasValue); }
public async Task AddOrUpdateCommandDescription(long gid, CommandDescription commandDescription) { string verboseMessage = $"{baseLogString} entering AddOrUpdateCommandDescription method."; Logger.LogVerbose(verboseMessage); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } await CommandDescriptionCache.SetAsync(gid, commandDescription); }
private async Task LogAllReliableCollections() { while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } StringBuilder sb = new StringBuilder(); sb.AppendLine("Reliable Collections"); sb.AppendLine("CurrentGidToPointItemMap =>"); var currentGidToPointItemMap = await CurrentGidToPointItemMap.GetEnumerableDictionaryAsync(); foreach (var element in currentGidToPointItemMap) { sb.AppendLine($"Key => {element.Key}, Value => Gid: 0x{element.Value.Gid:X16}, Address: {element.Value.Address}, Name: {element.Value.Name}, RegisterType: {element.Value.RegisterType}, Alarm: {element.Value.Alarm}, Initialized: {element.Value.Initialized}"); } sb.AppendLine(); sb.AppendLine("IncomingGidToPointItemMap =>"); var incomingGidToPointItemMap = await IncomingGidToPointItemMap.GetEnumerableDictionaryAsync(); foreach (var element in incomingGidToPointItemMap) { sb.AppendLine($"Key => {element.Key}, Value => Gid: 0x{element.Value.Gid:X16}, Address: {element.Value.Address}, Name: {element.Value.Name}, RegisterType: {element.Value.RegisterType}, Alarm: {element.Value.Alarm}, Initialized: {element.Value.Initialized}"); } sb.AppendLine(); sb.AppendLine("CurrentAddressToGidMap =>"); var currentAddressToGidMap = await CurrentAddressToGidMap.GetEnumerableDictionaryAsync(); foreach (var element in currentAddressToGidMap) { sb.AppendLine($"Key => {element.Key}, Value => Dictionary Count: {element.Value.Count}"); } sb.AppendLine(); sb.AppendLine("IncomingAddressToGidMap =>"); var incomingAddressToGidMap = await IncomingAddressToGidMap.GetEnumerableDictionaryAsync(); foreach (var element in incomingAddressToGidMap) { sb.AppendLine($"Key => {element.Key}, Value => Dictionary Count: {element.Value.Count}"); } sb.AppendLine(); sb.AppendLine("InfoCache =>"); var infoCache = await InfoCache.GetEnumerableDictionaryAsync(); foreach (var element in infoCache) { sb.AppendLine($"Key => {element.Key}, Value => {element.Value}"); } sb.AppendLine(); sb.AppendLine("ModelChanges =>"); var modelChanges = await ModelChanges.GetEnumerableDictionaryAsync(); foreach (var element in modelChanges) { sb.AppendLine($"Key => {element.Key}, Value => List Count: {element.Value.Count}"); } sb.AppendLine(); sb.AppendLine("MeasurementsCache =>"); var measurementsCache = await MeasurementsCache.GetEnumerableDictionaryAsync(); foreach (var element in measurementsCache) { sb.AppendLine($"Key => {element.Key}, Value => MeasurementGid: {element.Value.MeasurementGid:X16}, Alarm: {element.Value.Alarm}, CommandOrigin: {element.Value.CommandOrigin}"); } sb.AppendLine(); sb.AppendLine("CommandDescriptionCache =>"); var commandDescriptionCache = await CommandDescriptionCache.GetEnumerableDictionaryAsync(); foreach (var element in commandDescriptionCache) { sb.AppendLine($"Key => {element.Key}, Value => Gid: {element.Value.Gid:X16}, Address: {element.Value.Address}, Value: {element.Value.Value}, CommandOrigin: {element.Value.CommandOrigin}"); } sb.AppendLine(); Logger.LogDebug($"{baseLogString} LogAllReliableCollections => {sb}"); }
public async Task <ScadaPublication> GetIntegrityUpdateForSpecificTopic(Topic topic) { while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } if (GidToPointItemMap == null) { string message = $"GetIntegrityUpdate => GidToPointItemMap is null."; Logger.LogError(message); throw new InternalSCADAServiceException(message); } if (CommandDescriptionCache == null) { string message = $"GetIntegrityUpdate => CommandDescriptionCache is null."; Logger.LogError(message); throw new InternalSCADAServiceException(message); } Dictionary <long, AnalogModbusData> analogModbusData = new Dictionary <long, AnalogModbusData>(); Dictionary <long, DiscreteModbusData> discreteModbusData = new Dictionary <long, DiscreteModbusData>(); var enumerableGidToPointItemMap = await GidToPointItemMap.GetEnumerableDictionaryAsync(); foreach (long gid in enumerableGidToPointItemMap.Keys) { CommandOriginType commandOrigin = CommandOriginType.UNKNOWN_ORIGIN; if (topic == Topic.MEASUREMENT && enumerableGidToPointItemMap[gid] is IAnalogPointItem analogPointItem) { var result = await CommandDescriptionCache.TryGetValueAsync(gid); if (result.HasValue && result.Value.Value == analogPointItem.CurrentRawValue) { commandOrigin = result.Value.CommandOrigin; } AnalogModbusData analogValue = new AnalogModbusData(analogPointItem.CurrentEguValue, analogPointItem.Alarm, gid, commandOrigin); analogModbusData.Add(gid, analogValue); } else if (topic == Topic.SWITCH_STATUS && enumerableGidToPointItemMap[gid] is IDiscretePointItem discretePointItem) { var result = await CommandDescriptionCache.TryGetValueAsync(gid); if (result.HasValue && result.Value.Value == discretePointItem.CurrentValue) { commandOrigin = result.Value.CommandOrigin; } DiscreteModbusData discreteValue = new DiscreteModbusData(discretePointItem.CurrentValue, discretePointItem.Alarm, gid, commandOrigin); discreteModbusData.Add(gid, discreteValue); } } ScadaPublication scadaPublication; if (topic == Topic.MEASUREMENT) { MultipleAnalogValueSCADAMessage analogValuesMessage = new MultipleAnalogValueSCADAMessage(analogModbusData); scadaPublication = new ScadaPublication(Topic.MEASUREMENT, analogValuesMessage); } else if (topic == Topic.SWITCH_STATUS) { MultipleDiscreteValueSCADAMessage discreteValuesMessage = new MultipleDiscreteValueSCADAMessage(discreteModbusData); scadaPublication = new ScadaPublication(Topic.SWITCH_STATUS, discreteValuesMessage); } else { string message = $"GetIntegrityUpdate => argument topic is neither Topic.MEASUREMENT nor Topic.SWITCH_STATUS."; Logger.LogError(message); throw new ArgumentException(message); } return(scadaPublication); }