Ejemplo n.º 1
0
        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();
                    }
                }
        }
Ejemplo n.º 2
0
        private static void Migrate(string connectionString, string deviceDefinitionsFile)
        {
            LookupTables lookupTables;

            MeterLocation remoteMeterLocation;

            Meter   meter;
            Line    line;
            Series  series;
            Channel channel;

            XDocument document = XDocument.Load(deviceDefinitionsFile);
            Dictionary <string, XElement> deviceLookup = document.Elements().Elements("device").ToDictionary(device => (string)device.Attribute("id"));
            List <XElement> deviceElements;
            XElement        deviceAttributes;

            Dictionary <string, Channel> channelLookup;

            ProgressTracker progressTracker = new ProgressTracker(deviceLookup.Count * 2);

            deviceElements = deviceLookup.Values.OrderBy(device =>
            {
                int count = 0;

                while (deviceLookup.TryGetValue((string)device.Element("parent") ?? string.Empty, out device))
                {
                    count++;
                }

                return(count);
            }).ToList();

            using (AdoDataConnection connection = new AdoDataConnection(connectionString, "AssemblyName={System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}; ConnectionType=System.Data.SqlClient.SqlConnection; AdapterType=System.Data.SqlClient.SqlDataAdapter"))
            {
                // Load existing configuration from the database
                progressTracker.StartPendingMessage("Loading existing configuration from database...");
                lookupTables = new LookupTables();
                lookupTables.CreateLookups(document, connection);
                progressTracker.EndPendingMessage();

                // Load updates to device configuration into the database
                progressTracker.WriteMessage($"Beginning migration of {deviceElements.Count} device configurations...");

                foreach (XElement deviceElement in deviceElements)
                {
                    // 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 = LoadMeterAttributes(lookupTables, deviceElement, deviceAttributes, connection);

                    // Now that we know what meter we are processing, display a message to indicate that we are parsing this meter's configuration
                    progressTracker.StartPendingMessage($"Loading configuration for meter {meter.Name} ({meter.AssetKey})...");

                    // 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 = LoadLineAttributes(lookupTables, lineElement, connection);

                        // Provide a link between this line and the location housing the meter
                        Link(meter.ID, line.ID, lineElement, connection);
                        Link(lookupTables.MeterLocationLookup.GetOrDefault((string)deviceAttributes.Element("stationID")).ID, line.ID, connection);

                        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 = LoadRemoteMeterLocationAttributes(lookupTables, lineElement, connection);

                            // Provide a link between this line and the remote location
                            Link(remoteMeterLocation.ID, line.ID, connection);
                        }

                        // Get a lookup table for the channels monitoring this line
                        channelLookup = lookupTables.GetChannelLookup(meter, line, connection);

                        foreach (string channelName in new[] { "VX1", "VX2", "VX3", "VY1", "VY2", "VY3", "I1", "I2", "I3" })
                        {
                            if (channelLookup.ContainsKey(channelName))
                            {
                                continue;
                            }

                            channel = new Channel();
                            series  = new Series();
                            channelLookup.Add(channelName, channel);

                            // Load updates to channel configuration into the database
                            LoadChannelAttributes(meter, line, channel, channelName, lookupTables, connection);
                            LoadSeriesAttributes(channel, series, lookupTables, connection);
                        }
                    }

                    progressTracker.EndPendingMessage();

                    // Increment the progress counter
                    progressTracker.MakeProgress();
                }

                foreach (XElement deviceElement in deviceElements)
                {
                    // Get the element representing a device's attributes
                    deviceAttributes = deviceElement.Element("attributes") ?? new XElement("attributes");

                    meter = lookupTables.MeterLookup.GetOrDefault((string)deviceElement.Attribute("id"));

                    if ((string)deviceAttributes.Element("parentNormal") != null && lookupTables.MeterLookup.ContainsKey((string)deviceAttributes.Element("parentNormal")))
                    {
                        meter.ParentNormalID = lookupTables.MeterLookup.GetOrDefault((string)deviceAttributes.Element("parentNormal")).ID;
                    }

                    if ((string)deviceAttributes.Element("parentAlternate") != null && (string)deviceAttributes.Element("parentAlternate") != "none" && lookupTables.MeterLookup.ContainsKey((string)deviceAttributes.Element("parentAlternate")))
                    {
                        meter.ParentAlternateID = lookupTables.MeterLookup.GetOrDefault((string)deviceAttributes.Element("parentAlternate")).ID;
                    }

                    (new TableOperations <Meter>(connection)).UpdateRecord(meter);

                    // Now that we know what meter we are processing, display a message to indicate that we are parsing this meter's configuration
                    progressTracker.StartPendingMessage($"Loading parent configuration for meter {meter.Name} ({meter.AssetKey})...");


                    progressTracker.EndPendingMessage();

                    // Increment the progress counter
                    progressTracker.MakeProgress();
                }
            }
        }