private void UpdateConfigurationData(MeterDataSet meterDataSet) { using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, GetTransactionOptions())) { if (meterDataSet.Meter.MeterLines.Count != 1) { return; } Line line = meterDataSet.Meter.MeterLines .Select(meterLine => meterLine.Line) .Single(); if (meterDataSet.Configuration.LineLength.HasValue) { line.Length = meterDataSet.Configuration.LineLength.GetValueOrDefault(); m_meterInfo.SubmitChanges(); } if (meterDataSet.Configuration.R1.HasValue && meterDataSet.Configuration.X1.HasValue && meterDataSet.Configuration.R0.HasValue && meterDataSet.Configuration.X0.HasValue) { DataContextLookup <int, LineImpedance> lookup = new DataContextLookup <int, LineImpedance>(m_faultLocationInfo, impedance => impedance.LineID); LineImpedance lineImpedance = lookup.GetOrAdd(line.ID, id => new LineImpedance() { LineID = id }); if (meterDataSet.Configuration.R1.HasValue) { lineImpedance.R1 = meterDataSet.Configuration.R1.GetValueOrDefault(); } if (meterDataSet.Configuration.X1.HasValue) { lineImpedance.X1 = meterDataSet.Configuration.X1.GetValueOrDefault(); } if (meterDataSet.Configuration.R0.HasValue) { lineImpedance.R0 = meterDataSet.Configuration.R0.GetValueOrDefault(); } if (meterDataSet.Configuration.X0.HasValue) { lineImpedance.X0 = meterDataSet.Configuration.X0.GetValueOrDefault(); } m_faultLocationInfo.SubmitChanges(); } transaction.Complete(); } }
private static void Migrate(string connectionString, string deviceDefinitionsFile) { LookupTables lookupTables; MeterLocation meterLocation; MeterLocation remoteMeterLocation; MeterLocationLine localLink; MeterLocationLine remoteLink; Meter meter; Line line; Series series; Channel channel; OutputChannel outputChannel; Dictionary <string, Tuple <Series, OutputChannel> > channelLookup; Tuple <Series, OutputChannel> tuple; string channelKey; int outputChannelIndex; LineImpedance lineImpedance; SourceImpedance localSourceImpedance; SourceImpedance remoteSourceImpedance; XDocument document = XDocument.Load(deviceDefinitionsFile); List <XElement> deviceElements = document.Elements().Elements("device").ToList(); XElement deviceAttributes; XElement impedancesElement; List <Tuple <Line, LineImpedance> > lineImpedances = new List <Tuple <Line, LineImpedance> >(); List <Tuple <MeterLocationLine, SourceImpedance> > sourceImpedances = new List <Tuple <MeterLocationLine, SourceImpedance> >(); List <Tuple <Series, OutputChannel> > outputChannels = new List <Tuple <Series, OutputChannel> >(); ProgressTracker progressTracker = new ProgressTracker(deviceElements.Count); using (MeterInfoDataContext meterInfo = new MeterInfoDataContext(connectionString)) using (FaultLocationInfoDataContext faultLocationInfo = new FaultLocationInfoDataContext(connectionString)) { // Load existing fault location configuration from the database progressTracker.StartPendingMessage("Loading existing fault location configuration from database..."); lookupTables = new LookupTables(meterInfo, faultLocationInfo); lookupTables.CreateLookups(document); progressTracker.EndPendingMessage(); // Load updates to fault location algorithms into the database progressTracker.StartPendingMessage("Loading updates to fault location algorithms into the database..."); foreach (XElement analyticsElement in document.Elements().Elements("analytics")) { LoadFaultLocationAlgorithms(analyticsElement, faultLocationInfo); } faultLocationInfo.SubmitChanges(); progressTracker.EndPendingMessage(); // Load updates to device configuration into the database progressTracker.WriteMessage(string.Format("Beginning migration of {0} device configurations...", deviceElements.Count)); foreach (XElement deviceElement in deviceElements) { lineImpedances.Clear(); sourceImpedances.Clear(); outputChannels.Clear(); // Get the element representing a device's attributes deviceAttributes = deviceElement.Element("attributes") ?? new XElement("attributes"); // Attempt to find existing configuration for this device and update the meter with any changes to the device's attributes meter = lookupTables.MeterLookup.GetOrAdd((string)deviceElement.Attribute("id"), assetKey => new Meter() { AssetKey = assetKey }); LoadMeterAttributes(meter, deviceAttributes); // Now that we know what meter we are processing, display a message to indicate that we are parsing this meter's configuration progressTracker.StartPendingMessage(string.Format("Loading configuration for meter {0} ({1})...", meter.Name, meter.AssetKey)); // Attempt to find existing configuration for the location of the meter and update with configuration changes meterLocation = lookupTables.MeterLocationLookup.GetOrAdd((string)deviceAttributes.Element("stationID"), assetKey => new MeterLocation() { AssetKey = assetKey }); LoadMeterLocationAttributes(meterLocation, deviceAttributes); // Link the meter location to the meter meter.MeterLocation = meterLocation; // Load updates to line configuration into the database foreach (XElement lineElement in deviceElement.Elements("lines").Elements("line")) { // Attempt to find existing configuration for the line and update with configuration changes line = lookupTables.LineLookup.GetOrAdd((string)lineElement.Attribute("id"), assetKey => new Line() { AssetKey = assetKey }); LoadLineAttributes(line, lineElement); // Provide a link between this line and the location housing the meter Link(meter, line, lineElement, lookupTables.MeterLineLookup); localLink = Link(meterLocation, line, lookupTables.MeterLocationLineLookup); if ((string)lineElement.Element("endStationID") != null) { // Attempt to find existing configuration for the location of the other end of the line and update with configuration changes remoteMeterLocation = lookupTables.MeterLocationLookup.GetOrAdd((string)lineElement.Element("endStationID"), assetKey => new MeterLocation() { AssetKey = assetKey }); LoadRemoteMeterLocationAttributes(remoteMeterLocation, lineElement); // Provide a link between this line and the remote location remoteLink = Link(remoteMeterLocation, line, lookupTables.MeterLocationLineLookup); } else { // Set remote meter location to null so we // know later that there isn't one defined remoteMeterLocation = null; remoteLink = null; } // Get a lookup table for the channels monitoring this line channelLookup = lookupTables.GetChannelLookup(meter, line); outputChannelIndex = 0; foreach (XElement channelElement in lineElement.Elements("channels").Elements()) { channelKey = channelElement.Name.LocalName; // Attempt to find an existing channel corresponding to this element if (channelLookup.TryGetValue(channelKey, out tuple)) { series = tuple.Item1; channel = series.Channel; outputChannel = tuple.Item2; } else { channel = new Channel(); series = new Series(); outputChannel = new OutputChannel(); channelLookup.Add(channelKey, Tuple.Create(series, outputChannel)); } // Load updates to channel configuration into the database LoadChannelAttributes(meter, line, remoteMeterLocation, channel, channelKey, lookupTables); LoadSeriesAttributes(channel, series, channelElement, lookupTables); outputChannel.ChannelKey = channelKey; outputChannel.LoadOrder = outputChannelIndex; outputChannels.Add(Tuple.Create(series, outputChannel)); outputChannelIndex++; } impedancesElement = lineElement.Element("impedances") ?? new XElement("impedances"); // Attempt to find existing impedance configuration for the line and update with configuration changes lineImpedance = lookupTables.LineImpedanceLookup.GetOrAdd(line, ln => new LineImpedance()); LoadLineImpedanceAttributes(lineImpedance, impedancesElement); lineImpedances.Add(Tuple.Create(line, lineImpedance)); // Attempt to find existing impedance configuration for the meter's location and update with configuration changes localSourceImpedance = lookupTables.SourceImpedanceLookup.GetOrAdd(localLink, location => new SourceImpedance()); LoadLocalSourceImpedanceAttributes(localSourceImpedance, impedancesElement); sourceImpedances.Add(Tuple.Create(localLink, localSourceImpedance)); if ((object)remoteLink != null) { // Attempt to find existing impedance configuration for the remote location and update with configuration changes remoteSourceImpedance = lookupTables.SourceImpedanceLookup.GetOrAdd(remoteLink, location => new SourceImpedance()); LoadRemoteSourceImpedanceAttributes(remoteSourceImpedance, impedancesElement); sourceImpedances.Add(Tuple.Create(remoteLink, remoteSourceImpedance)); } } if (meter.ID == 0) { meterInfo.Meters.InsertOnSubmit(meter); } meterInfo.SubmitChanges(); // Load updates to line impedance configuration into the database foreach (Tuple <Line, LineImpedance> mapping in lineImpedances) { line = mapping.Item1; lineImpedance = mapping.Item2; lineImpedance.LineID = line.ID; if (lineImpedance.ID == 0) { faultLocationInfo.LineImpedances.InsertOnSubmit(lineImpedance); } } // Load updates to source impedance configuration into the database foreach (Tuple <MeterLocationLine, SourceImpedance> mapping in sourceImpedances) { localLink = mapping.Item1; localSourceImpedance = mapping.Item2; localSourceImpedance.MeterLocationLineID = localLink.ID; if (localSourceImpedance.ID == 0 && (localSourceImpedance.RSrc != 0.0D || localSourceImpedance.XSrc != 0.0D)) { faultLocationInfo.SourceImpedances.InsertOnSubmit(localSourceImpedance); } } // Load updates to source impedance configuration into the database foreach (Tuple <Series, OutputChannel> mapping in outputChannels) { series = mapping.Item1; outputChannel = mapping.Item2; outputChannel.SeriesID = series.ID; if (outputChannel.ID == 0) { faultLocationInfo.OutputChannels.InsertOnSubmit(outputChannel); } } faultLocationInfo.SubmitChanges(); progressTracker.EndPendingMessage(); // Increment the progress counter progressTracker.MakeProgress(); } } }