public void GetEnumeratedReferenceTypes(DataType dataType, List <DataType> dataTypes, UDTCompiler compiler) { IEnumerable <DataType> referencingTypes = compiler.EnumerateReferencingTypes(compiler.GetType(dataType.Category, dataType.Identifier)); foreach (DataType referencingType in referencingTypes) { dataTypes.Add(referencingType); GetEnumeratedReferenceTypes(referencingType, dataTypes, compiler); } }
public static void CheckPhasorTypesAndMappings() { string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string ecaClientDataPath = Path.Combine(appData, "Grid Protection Alliance", "openECAClient"); string udtDirectory = Path.Combine(ecaClientDataPath, "UserDefinedTypes"); string udmDirectory = Path.Combine(ecaClientDataPath, "UserDefinedInputMappings"); UDTCompiler udtCompiler = new UDTCompiler(); if (Directory.Exists(udtDirectory)) { udtCompiler.Scan(udtDirectory); } if (!udtCompiler.DefinedTypes.Where(x => x.IsUserDefined).ToList().Any(x => x.Category == "ECA" && x.Identifier == "Phasor")) { UserDefinedType udt = new UserDefinedType(); udt.Identifier = "Phasor"; udt.Category = "ECA"; udt.Fields = new List <UDTField>(); UDTField magnitude = new UDTField(); magnitude.Type = new DataType { Category = "FloatingPoint", Identifier = "Double" }; magnitude.Identifier = "Magnitude"; udt.Fields.Add(magnitude); UDTField angle = new UDTField(); angle.Type = new DataType { Category = "FloatingPoint", Identifier = "Double" }; angle.Identifier = "Angle"; udt.Fields.Add(angle); UDTWriter udtWriter = new UDTWriter(); udtWriter.Types.Add(udt); udtWriter.WriteFiles(udtDirectory); } if (!udtCompiler.DefinedTypes.Where(x => x.IsUserDefined).ToList().Any(x => x.Category == "ECA" && x.Identifier == "VIPair")) { UserDefinedType udt = new UserDefinedType(); udt.Identifier = "VIPair"; udt.Category = "ECA"; udt.Fields = new List <UDTField>(); UDTField voltage = new UDTField(); voltage.Type = new DataType { Category = "ECA", Identifier = "Phasor" }; voltage.Identifier = "Voltage"; udt.Fields.Add(voltage); UDTField current = new UDTField(); current.Type = new DataType { Category = "ECA", Identifier = "Phasor" }; current.Identifier = "Current"; udt.Fields.Add(current); UDTWriter udtWriter = new UDTWriter(); udtWriter.Types.Add(udt); udtWriter.WriteFiles(udtDirectory); } udtCompiler = new UDTCompiler(); if (Directory.Exists(udtDirectory)) { udtCompiler.Scan(udtDirectory); } MappingCompiler mappingCompiler = new MappingCompiler(udtCompiler); if (Directory.Exists(udmDirectory)) { mappingCompiler.Scan(udmDirectory); } DataHub dataHub = new DataHub(); dataHub.Context = new HubCallerContext(null, Guid.NewGuid().ToString()); dataHub.RegisterMetadataReceivedHandler(() => { try { Program.LogStatus("Synchronizing ECA.Phasor mappings with accessible phasor meta-data..."); Dictionary <Guid, string> mappingLookup = new Dictionary <Guid, string>(); IEnumerable <PhasorDetail> phasorDetails = dataHub.GetPhasorDetails() ?? new PhasorDetail[0]; IEnumerable <PowerCalculation> powerCalculations = dataHub.GetPowerCalculation() ?? new PowerCalculation[0]; IEnumerable <MeasurementDetail> measurementDetails = dataHub.GetMeasurementDetails() ?? new MeasurementDetail[0]; MappingWriter mappingWriter = new MappingWriter(); foreach (PhasorDetail detail in phasorDetails) { Guid magnitudeID = measurementDetails.FirstOrDefault(measurement => measurement.DeviceAcronym == detail.DeviceAcronym && measurement.PhasorSourceIndex == detail.SourceIndex && (measurement.SignalAcronym?.Contains("PHM") ?? false))?.SignalID ?? Guid.Empty; Guid angleID = measurementDetails.FirstOrDefault(measurement => measurement.DeviceAcronym == detail.DeviceAcronym && measurement.PhasorSourceIndex == detail.SourceIndex && (measurement.SignalAcronym?.Contains("PHA") ?? false))?.SignalID ?? Guid.Empty; if (magnitudeID == Guid.Empty || angleID == Guid.Empty) { continue; } string identifier = (detail.DeviceAcronym + '_' + detail.Label + '_' + detail.Phase?.Replace(" ", "_").Replace("+", "pos").Replace("-", "neg") + '_' + detail.Type) .Replace("\\", "_").Replace("#", "").Replace("'", "").Replace("(", "").Replace(")", "").ReplaceCharacters('_', x => !char.IsLetterOrDigit(x)); if (mappingCompiler.DefinedMappings.All(typeMapping => typeMapping.Identifier != identifier)) { TypeMapping mapping = new TypeMapping { Identifier = identifier, Type = (UserDefinedType)udtCompiler.GetType("ECA", "Phasor") }; if (mapping.Type.Fields.Count > 1) { mapping.FieldMappings.Add(new FieldMapping { Field = mapping.Type.Fields[0], Expression = magnitudeID.ToString() }); mapping.FieldMappings.Add(new FieldMapping { Field = mapping.Type.Fields[1], Expression = angleID.ToString() }); mappingWriter.Mappings.Add(mapping); } } mappingLookup.Add(angleID, identifier); } foreach (PowerCalculation calculation in powerCalculations) { Guid voltageAngleID = calculation.VoltageAngleID; Guid currentAngleID = calculation.CurrentAngleID; string voltageMappingIdentifier; string currentMappingIdentifier; if (mappingLookup.TryGetValue(voltageAngleID, out voltageMappingIdentifier) && mappingLookup.TryGetValue(currentAngleID, out currentMappingIdentifier) && !string.IsNullOrEmpty(voltageMappingIdentifier) && !string.IsNullOrEmpty(currentMappingIdentifier)) { TypeMapping mapping = new TypeMapping { Identifier = $"{voltageMappingIdentifier}__{currentMappingIdentifier}" }; mapping.Identifier = mapping.Identifier.Replace("+", "pos").Replace("-", "neg").Replace("\\", "_").Replace("#", "").Replace("'", "").Replace("(", "").Replace(")", "").ReplaceCharacters('_', x => !char.IsLetterOrDigit(x)); mapping.Type = (UserDefinedType)udtCompiler.GetType("ECA", "VIPair"); if (mapping.Type.Fields.Count > 1) { mapping.FieldMappings.Add(new FieldMapping { Field = mapping.Type.Fields[0], Expression = voltageMappingIdentifier }); mapping.FieldMappings.Add(new FieldMapping { Field = mapping.Type.Fields[1], Expression = currentMappingIdentifier }); mappingWriter.Mappings.Add(mapping); } } } mappingWriter.WriteFiles(udmDirectory); Program.LogStatus("Completed synchronization of mappings with accessible phasor meta-data.", true); } catch (Exception ex) { Program.LogException(new InvalidOperationException($"Failed while synchronizing ECA.Phasor mappings with accessible phasor meta-data: {ex.Message}", ex), true); } finally { dataHub.OnDisconnected(true); } }); dataHub.InitializeSubscriptions(); }