diff --git a/Dependencies/OpenXDA/FaultAlgorithms.dll b/Dependencies/OpenXDA/FaultAlgorithms.dll
new file mode 100644
index 00000000..6c0bd425
Binary files /dev/null and b/Dependencies/OpenXDA/FaultAlgorithms.dll differ
diff --git a/Dependencies/OpenXDA/FaultData.dll b/Dependencies/OpenXDA/FaultData.dll
new file mode 100644
index 00000000..d94d4e34
Binary files /dev/null and b/Dependencies/OpenXDA/FaultData.dll differ
diff --git a/Dependencies/OpenXDA/openHistorian.XDALink.dll b/Dependencies/OpenXDA/openHistorian.XDALink.dll
new file mode 100644
index 00000000..5e175351
Binary files /dev/null and b/Dependencies/OpenXDA/openHistorian.XDALink.dll differ
diff --git a/Dependencies/OpenXDA/openXDA.APIAuthentication.dll b/Dependencies/OpenXDA/openXDA.APIAuthentication.dll
new file mode 100644
index 00000000..26807e3c
Binary files /dev/null and b/Dependencies/OpenXDA/openXDA.APIAuthentication.dll differ
diff --git a/Dependencies/OpenXDA/openXDA.Configuration.dll b/Dependencies/OpenXDA/openXDA.Configuration.dll
new file mode 100644
index 00000000..af840746
Binary files /dev/null and b/Dependencies/OpenXDA/openXDA.Configuration.dll differ
diff --git a/Dependencies/OpenXDA/openXDA.Model.dll b/Dependencies/OpenXDA/openXDA.Model.dll
new file mode 100644
index 00000000..9caf0303
Binary files /dev/null and b/Dependencies/OpenXDA/openXDA.Model.dll differ
diff --git a/Dependencies/OpenXDA/openXDA.PQI.dll b/Dependencies/OpenXDA/openXDA.PQI.dll
new file mode 100644
index 00000000..0df0239e
Binary files /dev/null and b/Dependencies/OpenXDA/openXDA.PQI.dll differ
diff --git a/Dependencies/OpenXDA/openXDA.Reports.dll b/Dependencies/OpenXDA/openXDA.Reports.dll
new file mode 100644
index 00000000..63684b2d
Binary files /dev/null and b/Dependencies/OpenXDA/openXDA.Reports.dll differ
diff --git a/Libraries/FaultAlgorithms/Conductor.cs b/Libraries/FaultAlgorithms/Conductor.cs
deleted file mode 100644
index 5b5a24fe..00000000
--- a/Libraries/FaultAlgorithms/Conductor.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-//*********************************************************************************************************************
-// Conductor.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright © 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// • Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// • Neither the name of the Electric Power Research Institute, Inc. (“EPRI”) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// • TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 06/14/2012 - Stephen C. Wills, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-namespace FaultAlgorithms
-{
- ///
- /// Contains data for both the voltage
- /// and current on a conductor.
- ///
- public class Conductor
- {
- #region [ Members ]
-
- // Fields
-
- ///
- /// One cycle of voltage data.
- ///
- public Cycle V;
-
- ///
- /// One cycle of current data.
- ///
- public Cycle I;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public Conductor()
- {
- V = new Cycle();
- I = new Cycle();
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The index of the cycle to be calculated.
- /// The value to divide from the sample rate to determine the starting location of the cycle.
- /// The frequency of the sine wave during this cycle.
- /// The voltage data points.
- /// The current data points.
- public Conductor(int cycleIndex, int sampleRateDivisor, double frequency, MeasurementData voltageData, MeasurementData currentData)
- {
- int vStart = cycleIndex * (voltageData.SampleRate / sampleRateDivisor);
- int iStart = cycleIndex * (currentData.SampleRate / sampleRateDivisor);
- V = new Cycle(vStart, frequency, voltageData);
- I = new Cycle(iStart, frequency, currentData);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/FaultAlgorithms/Cycle.cs b/Libraries/FaultAlgorithms/Cycle.cs
deleted file mode 100644
index 91db47e8..00000000
--- a/Libraries/FaultAlgorithms/Cycle.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-//*********************************************************************************************************************
-// Cycle.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// Neither the name of the Electric Power Research Institute, Inc. (EPRI) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 05/23/2012 - J. Ritchie Carroll, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-using Gemstone;
-using Gemstone.Numeric;
-using Gemstone.Numeric.Analysis;
-using Gemstone.Units;
-
-namespace FaultAlgorithms
-{
- ///
- /// Represents a cycle of single phase power frequency-domain data.
- ///
- public class Cycle
- {
- #region [ Members ]
-
- // Constants
- private const double PiOverTwo = Math.PI / 2.0D;
-
- // Fields
-
- ///
- /// The actual frequency of the cycle in hertz.
- ///
- public double Frequency;
-
- ///
- /// The complex number representation of the RMS phasor.
- ///
- public ComplexNumber Complex;
-
- ///
- /// The most extreme data point in the cycle.
- ///
- public double Peak;
-
- ///
- /// The error between the sine fit and the given data values.
- ///
- public double Error;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public Cycle()
- {
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The index of the start of the cycle.
- /// The frequency of the measured system, in Hz.
- /// The time-domain data to be used to calculate frequency-domain values.
- public Cycle(int startSample, double frequency, MeasurementData waveFormData)
- {
- long timeStart;
- double[] timeInSeconds;
- double[] measurements;
- SineWave sineFit;
-
- if (startSample < 0)
- throw new ArgumentOutOfRangeException("startSample");
-
- if (startSample + waveFormData.SampleRate > waveFormData.Times.Length)
- throw new ArgumentOutOfRangeException("startSample");
-
- if (startSample + waveFormData.SampleRate > waveFormData.Measurements.Length)
- throw new ArgumentOutOfRangeException("startSample");
-
- timeStart = waveFormData.Times[startSample];
- timeInSeconds = new double[waveFormData.SampleRate];
- measurements = new double[waveFormData.SampleRate];
-
- for (int i = 0; i < waveFormData.SampleRate; i++)
- {
- timeInSeconds[i] = Ticks.ToSeconds(waveFormData.Times[i + startSample] - timeStart);
- measurements[i] = waveFormData.Measurements[i + startSample];
- }
-
- sineFit = WaveFit.SineFit(measurements, timeInSeconds, frequency);
-
- RMS = Math.Sqrt(measurements.Select(vi => vi * vi).Average());
- Phase = sineFit.Phase - PiOverTwo;
- Peak = sineFit.Amplitude;
- Frequency = frequency;
-
- Error = timeInSeconds
- .Select(time => sineFit.CalculateY(time))
- .Zip(measurements, (calc, measurement) => Math.Abs(calc - measurement))
- .Sum();
- }
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Root-mean-square of the in the cycle.
- ///
- public double RMS
- {
- get
- {
- return Complex.Magnitude;
- }
- set
- {
- Complex.Magnitude = value;
- }
- }
-
- ///
- /// Phase angle of the start of the cycle, relative to the reference angle.
- ///
- public Angle Phase
- {
- get
- {
- return Complex.Angle;
- }
- set
- {
- Complex.Angle = value;
- }
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Libraries/FaultAlgorithms/CycleData.cs b/Libraries/FaultAlgorithms/CycleData.cs
deleted file mode 100644
index 610d5960..00000000
--- a/Libraries/FaultAlgorithms/CycleData.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-//*********************************************************************************************************************
-// CycleData.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright © 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// • Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// • Neither the name of the Electric Power Research Institute, Inc. (“EPRI”) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// • TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 06/14/2012 - Stephen C. Wills, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-using Gemstone.Numeric;
-
-namespace FaultAlgorithms
-{
- ///
- /// Contains data for a single cycle over all three line-to-neutral conductors.
- ///
- public class CycleData
- {
- #region [ Members ]
-
- // Constants
-
- ///
- /// 2 * pi
- ///
- public const double TwoPI = 2.0D * Math.PI;
-
- // a = e^((2/3) * pi * i)
- private const double Rad120 = TwoPI / 3.0D;
- private static readonly ComplexNumber a = new ComplexNumber(Math.Cos(Rad120), Math.Sin(Rad120));
- private static readonly ComplexNumber aSq = a * a;
-
- // Fields
-
- ///
- /// A-to-neutral conductor
- ///
- public Conductor AN;
-
- ///
- /// B-to-neutral conductor
- ///
- public Conductor BN;
-
- ///
- /// C-to-neutral conductor
- ///
- public Conductor CN;
-
- ///
- /// Timestamp of the start of the cycle.
- ///
- public DateTime StartTime;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public CycleData()
- {
- AN = new Conductor();
- BN = new Conductor();
- CN = new Conductor();
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The index of the cycle being created.
- /// The value to divide from the sample rate to determine the index of the sample at the start of the cycle.
- /// The frequency of the measured system, in Hz.
- /// The data set containing voltage measurements.
- /// The data set containing current measurements.
- public CycleData(int cycleIndex, int sampleRateDivisor, double frequency, MeasurementDataSet voltageDataSet, MeasurementDataSet currentDataSet)
- {
- int sampleIndex;
-
- AN = new Conductor(cycleIndex, sampleRateDivisor, frequency, voltageDataSet.AN, currentDataSet.AN);
- BN = new Conductor(cycleIndex, sampleRateDivisor, frequency, voltageDataSet.BN, currentDataSet.BN);
- CN = new Conductor(cycleIndex, sampleRateDivisor, frequency, voltageDataSet.CN, currentDataSet.CN);
-
- sampleIndex = cycleIndex * (voltageDataSet.AN.SampleRate / sampleRateDivisor);
- StartTime = new DateTime(voltageDataSet.AN.Times[sampleIndex]);
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Calculates the positive, negative, and zero sequence components
- /// and returns them in an array with indexes 1, 2, and 0 respectively.
- ///
- /// The cycle of A-to-neutral data to be used.
- /// The cycle of B-to-neutral data to be used.
- /// The cycle of C-to-neutral data to be used.
- /// An array of size 3 containing the zero sequence, positive sequence, and negative sequence components in that order.
- public static ComplexNumber[] CalculateSequenceComponents(Cycle anCycle, Cycle bnCycle, Cycle cnCycle)
- {
- ComplexNumber an = anCycle.Complex;
- ComplexNumber bn = bnCycle.Complex;
- ComplexNumber cn = cnCycle.Complex;
-
- ComplexNumber[] sequenceComponents = new ComplexNumber[3];
-
- sequenceComponents[0] = (an + bn + cn) / 3.0D;
- sequenceComponents[1] = (an + a * bn + aSq * cn) / 3.0D;
- sequenceComponents[2] = (an + aSq * bn + a * cn) / 3.0D;
-
- return sequenceComponents;
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Libraries/FaultAlgorithms/CycleDataSet.cs b/Libraries/FaultAlgorithms/CycleDataSet.cs
deleted file mode 100644
index 34b810b7..00000000
--- a/Libraries/FaultAlgorithms/CycleDataSet.cs
+++ /dev/null
@@ -1,303 +0,0 @@
-//*********************************************************************************************************************
-// CycleDataSet.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright © 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// • Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// • Neither the name of the Electric Power Research Institute, Inc. (“EPRI”) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// • TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 06/14/2012 - Stephen C. Wills, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-using System.Collections;
-using Gemstone.Numeric;
-using Gemstone.Numeric.Analysis;
-
-namespace FaultAlgorithms
-{
- ///
- /// Represents a collection of all the cycles extracted from a given data set.
- ///
- public class CycleDataSet : IEnumerable
- {
- #region [ Members ]
-
- // Fields
- private List m_cycles;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public CycleDataSet()
- {
- m_cycles = new List();
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The frequency of the measured system, in Hz.
- /// The data set containing voltage data points.
- /// The data set containing current data points.
- public CycleDataSet(double frequency, MeasurementDataSet voltageDataSet, MeasurementDataSet currentDataSet)
- {
- Populate(frequency, voltageDataSet, currentDataSet);
- }
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the data structure containing a
- /// full cycle of data at the given index.
- ///
- /// The index of the cycle.
- /// The cycle of data at the given index.
- public CycleData this[int i]
- {
- get
- {
- return m_cycles[i];
- }
- set
- {
- while(i >= m_cycles.Count)
- m_cycles.Add(null);
-
- m_cycles[i] = value;
- }
- }
-
- ///
- /// Gets the size of the cycle data set.
- ///
- public int Count
- {
- get
- {
- return m_cycles.Count;
- }
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Populates the cycle data set by calculating cycle
- /// data based on the given measurement data sets.
- ///
- /// The frequency of the measured system, in Hz.
- /// Data set containing voltage waveform measurements.
- /// Data set containing current waveform measurements.
- public void Populate(double frequency, MeasurementDataSet voltageDataSet, MeasurementDataSet currentDataSet)
- {
- List measurementDataList;
- int sampleRateDivisor;
- int numberOfCycles;
-
- measurementDataList = new List()
- {
- voltageDataSet.AN, voltageDataSet.BN, voltageDataSet.CN,
- currentDataSet.AN, currentDataSet.BN, currentDataSet.CN
- };
-
- sampleRateDivisor = measurementDataList
- .Select(measurementData => measurementData.SampleRate)
- .GreatestCommonDenominator();
-
- numberOfCycles = measurementDataList
- .Select(measurementData => (measurementData.Measurements.Length - measurementData.SampleRate + 1) / (measurementData.SampleRate / sampleRateDivisor))
- .Min();
-
- for (int i = 0; i < numberOfCycles; i++)
- m_cycles.Add(new CycleData(i, sampleRateDivisor, frequency, voltageDataSet, currentDataSet));
- }
-
- ///
- /// Returns the index of the cycle with the largest total current.
- ///
- /// The index of the cycle with the largest total current.
- public int GetLargestCurrentIndex()
- {
- int index = 0;
- int bestFaultIndex = -1;
- double largestCurrent = 0.0D;
-
- foreach (CycleData cycle in m_cycles)
- {
- double totalCurrent = cycle.AN.I.RMS + cycle.BN.I.RMS + cycle.CN.I.RMS;
-
- if (totalCurrent > largestCurrent)
- {
- bestFaultIndex = index;
- largestCurrent = totalCurrent;
- }
-
- index++;
- }
-
- return bestFaultIndex;
- }
-
- ///
- /// Clears the cycle data set so that it can be repopulated.
- ///
- public void Clear()
- {
- m_cycles.Clear();
- }
-
- ///
- /// Returns an enumerator that iterates through the collection of cycles.
- ///
- /// An object that can be used to iterate through the collection.
- public IEnumerator GetEnumerator()
- {
- foreach (CycleData cycle in m_cycles)
- {
- yield return cycle;
- }
- }
-
- ///
- /// Returns an enumerator that iterates through the collection of cycles.
- ///
- /// An object that can be used to iterate through the collection.
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Methods
-
- ///
- /// Exports the given to a CSV file.
- ///
- /// The name of the CSV file.
- /// The cycle data set to be exported.
- public static void ExportToCSV(string fileName, CycleDataSet cycles)
- {
- const string Header =
- "AN V RMS,AN V Phase,AN V Peak," +
- "BN V RMS,BN V Phase,BN V Peak," +
- "CN V RMS,CN V Phase,CN V Peak," +
- "Pos V Magnitude,Pos V Angle," +
- "Neg V Magnitude,Neg V Angle," +
- "Zero V Magnitude,Zero V Angle," +
- "AN I RMS,AN I Phase,AN I Peak," +
- "BN I RMS,BN I Phase,BN I Peak," +
- "CN I RMS,CN I Phase,CN I Peak," +
- "Pos I Magnitude,Pos I Angle," +
- "Neg I Magnitude,Neg I Angle," +
- "Zero I Magnitude,Zero I Angle";
-
- using (FileStream fileStream = File.OpenWrite(fileName))
- {
- using (TextWriter fileWriter = new StreamWriter(fileStream))
- {
- // Write the CSV header to the file
- fileWriter.WriteLine(Header);
-
- // Write data to the file
- foreach (CycleData cycleData in cycles.m_cycles)
- fileWriter.WriteLine(ToCSV(cycleData));
- }
- }
- }
-
- // Converts the cycle data to a row of CSV data.
- private static string ToCSV(CycleData cycleData)
- {
- ComplexNumber[] vSeq = CycleData.CalculateSequenceComponents(cycleData.AN.V, cycleData.BN.V, cycleData.CN.V);
- ComplexNumber[] iSeq = CycleData.CalculateSequenceComponents(cycleData.AN.I, cycleData.BN.I, cycleData.CN.I);
-
- string vCsv = string.Format("{0},{1},{2}", ToCSV(cycleData.AN.V), ToCSV(cycleData.BN.V), ToCSV(cycleData.CN.V));
- string vSeqCsv = string.Format("{0},{1},{2}", ToCSV(vSeq[1]), ToCSV(vSeq[2]), ToCSV(vSeq[0]));
- string iCsv = string.Format("{0},{1},{2}", ToCSV(cycleData.AN.I), ToCSV(cycleData.BN.I), ToCSV(cycleData.CN.I));
- string iSeqCsv = string.Format("{0},{1},{2}", ToCSV(iSeq[1]), ToCSV(iSeq[2]), ToCSV(iSeq[0]));
-
- return string.Format("{0},{1},{2},{3}", vCsv, vSeqCsv, iCsv, iSeqCsv);
- }
-
- // Converts the cycle to CSV data.
- private static string ToCSV(Cycle cycle)
- {
- return string.Format("{0},{1},{2}", cycle.RMS, cycle.Phase.ToDegrees(), cycle.Peak);
- }
-
- // Converts the sequence component to CSV data.
- private static string ToCSV(ComplexNumber sequenceComponent)
- {
- return string.Format("{0},{1}", sequenceComponent.Magnitude, sequenceComponent.Angle.ToDegrees());
- }
-
- #endregion
- }
-}
diff --git a/Libraries/FaultAlgorithms/FaultAlgorithms.csproj b/Libraries/FaultAlgorithms/FaultAlgorithms.csproj
deleted file mode 100644
index b8917102..00000000
--- a/Libraries/FaultAlgorithms/FaultAlgorithms.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- net9.0
- Debug;Development;Release
- enable
- enable
-
-
-
-
-
-
-
-
diff --git a/Libraries/FaultAlgorithms/MeasurementData.cs b/Libraries/FaultAlgorithms/MeasurementData.cs
deleted file mode 100644
index 04da176a..00000000
--- a/Libraries/FaultAlgorithms/MeasurementData.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-//*********************************************************************************************************************
-// MeasurementData.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// Neither the name of the Electric Power Research Institute, Inc. (EPRI) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 05/23/2012 - J. Ritchie Carroll, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-namespace FaultAlgorithms
-{
- ///
- /// Represents a set of single phase power time-domain data.
- ///
- public class MeasurementData
- {
- #region [ Members ]
-
- // Fields
-
- ///
- /// Array of times in ticks (100 nanosecond intervals).
- ///
- public long[] Times;
-
- ///
- /// Array of measured values.
- ///
- public double[] Measurements;
-
- ///
- /// The number of measured samples per cycle of data.
- ///
- public int SampleRate;
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Libraries/FaultAlgorithms/MeasurementDataSet.cs b/Libraries/FaultAlgorithms/MeasurementDataSet.cs
deleted file mode 100644
index 1a6c0fb0..00000000
--- a/Libraries/FaultAlgorithms/MeasurementDataSet.cs
+++ /dev/null
@@ -1,272 +0,0 @@
-//*********************************************************************************************************************
-// MeasurementDataSet.cs
-// Version 1.1 and subsequent releases
-//
-// Copyright 2013, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Version 1.0
-//
-// Copyright 2012 ELECTRIC POWER RESEARCH INSTITUTE, INC. All rights reserved.
-//
-// openFLE ("this software") is licensed under BSD 3-Clause license.
-//
-// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-// following conditions are met:
-//
-// Redistributions of source code must retain the above copyright notice, this list of conditions and
-// the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-// the following disclaimer in the documentation and/or other materials provided with the distribution.
-//
-// Neither the name of the Electric Power Research Institute, Inc. (EPRI) nor the names of its contributors
-// may be used to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL EPRI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//
-// This software incorporates work covered by the following copyright and permission notice:
-//
-// TVA Code Library 4.0.4.3 - Tennessee Valley Authority, tvainfo@tva.gov
-// No copyright is claimed pursuant to 17 USC 105. All Other Rights Reserved.
-//
-// Licensed under TVA Custom License based on NASA Open Source Agreement (TVA Custom NOSA);
-// you may not use TVA Code Library except in compliance with the TVA Custom NOSA. You may
-// obtain a copy of the TVA Custom NOSA at http://tvacodelibrary.codeplex.com/license.
-//
-// TVA Code Library is provided by the copyright holders and contributors "as is" and any express
-// or implied warranties, including, but not limited to, the implied warranties of merchantability
-// and fitness for a particular purpose are disclaimed.
-//
-//*********************************************************************************************************************
-//
-// Code Modification History:
-// -------------------------------------------------------------------------------------------------------------------
-// 05/23/2012 - J. Ritchie Carroll, Grid Protection Alliance
-// Generated original version of source code.
-//
-//*********************************************************************************************************************
-
-using Gemstone;
-
-namespace FaultAlgorithms
-{
- ///
- /// Represents a set of 3-phase line-to-neutral and line-to-line time-domain power data.
- ///
- public class MeasurementDataSet
- {
- #region [ Members ]
-
- // Constants
-
- private const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss.ffffff";
-
- // Fields
-
- ///
- /// Line-to-neutral A-phase data.
- ///
- public MeasurementData AN;
-
- ///
- /// Line-to-neutral B-phase data.
- ///
- public MeasurementData BN;
-
- ///
- /// Line-to-neutral C-phase data.
- ///
- public MeasurementData CN;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new .
- ///
- public MeasurementDataSet()
- {
- AN = new MeasurementData();
- BN = new MeasurementData();
- CN = new MeasurementData();
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Uses system frequency to calculate the sample rate for each set
- /// of in this measurement data set.
- ///
- /// The frequency of the measured system, in Hz.
- public void CalculateSampleRates(double frequency)
- {
- CalculateSampleRate(frequency, AN);
- CalculateSampleRate(frequency, BN);
- CalculateSampleRate(frequency, CN);
- }
-
- ///
- /// Explicitly sets the sample rate for each set of
- /// in this measurement data set.
- ///
- /// The sample rate.
- public void SetSampleRate(int sampleRate)
- {
- AN.SampleRate = sampleRate;
- BN.SampleRate = sampleRate;
- CN.SampleRate = sampleRate;
- }
-
- ///
- /// Writes all voltage measurement data to a CSV file.
- ///
- /// Export file name.
- public void ExportVoltageDataToCSV(string fileName)
- {
- const string Header = "Time,AN,BN,CN,AB,BC,CA";
-
- using (FileStream fileStream = File.OpenWrite(fileName))
- {
- using (TextWriter fileWriter = new StreamWriter(fileStream))
- {
- // Write the CSV header to the file
- fileWriter.WriteLine(Header);
-
- // Write the data to the file
- for (int i = 0; i < AN.Times.Length; i++)
- {
- string time = new DateTime(AN.Times[i]).ToString(DateTimeFormat);
-
- double an = AN.Measurements[i];
- double bn = BN.Measurements[i];
- double cn = CN.Measurements[i];
-
- fileWriter.Write("{0},{1},{2},{3},", time, an, bn, cn);
- fileWriter.WriteLine("{0},{1},{2}", an - bn, bn - cn, cn - an);
- }
- }
- }
- }
-
- ///
- /// Writes all current measurement data to a CSV file.
- ///
- /// Export file name.
- public void ExportCurrentDataToCSV(string fileName)
- {
- const string Header = "Time,AN,BN,CN";
-
- using (FileStream fileStream = File.OpenWrite(fileName))
- {
- using (TextWriter fileWriter = new StreamWriter(fileStream))
- {
- // Write the CSV header to the file
- fileWriter.WriteLine(Header);
-
- // Write the data to the file
- for (int i = 0; i < AN.Times.Length; i++)
- {
- string time = new DateTime(AN.Times[i]).ToString(DateTimeFormat);
-
- double an = AN.Measurements[i];
- double bn = BN.Measurements[i];
- double cn = CN.Measurements[i];
-
- fileWriter.WriteLine("{0},{1},{2},{3}", time, an, bn, cn);
- }
- }
- }
- }
-
- private void CalculateSampleRate(double frequency, MeasurementData measurementData)
- {
- long[] times;
- long startTicks;
- long endTicks;
- double cycles;
-
- // Get the collection of measurement timestamps
- times = measurementData.Times;
-
- // Determine the start and end time of the data set
- startTicks = times[0];
- endTicks = times[times.Length - 1];
-
- // Determine the number of cycles in the file,
- // based on the system frequency
- cycles = frequency * Ticks.ToSeconds(endTicks - startTicks);
-
- // Calculate the number of samples per cycle
- measurementData.SampleRate = (int)Math.Round(times.Length / cycles);
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Methods
-
- ///
- /// Writes all measurement data to a CSV file.
- ///
- /// Export file name.
- /// The voltage measurement data to be written to the file.
- /// The current measurement data to be written to the file.
- public static void ExportToCSV(string fileName, MeasurementDataSet voltageData, MeasurementDataSet currentData)
- {
- const string Header = "Time,AN V,BN V,CN V,AB V,BC V,CA V,AN I,BN I,CN I";
-
- using (FileStream fileStream = File.Create(fileName))
- {
- using (TextWriter fileWriter = new StreamWriter(fileStream))
- {
- // Write the CSV header to the file
- fileWriter.WriteLine(Header);
-
- // Write the data to the file
- for (int i = 0; i < voltageData.AN.Times.Length; i++)
- {
- string time = new DateTime(voltageData.AN.Times[i]).ToString(DateTimeFormat);
-
- double vAN = voltageData.AN.Measurements[i];
- double vBN = voltageData.BN.Measurements[i];
- double vCN = voltageData.CN.Measurements[i];
-
- double iAN = currentData.AN.Measurements[i];
- double iBN = currentData.BN.Measurements[i];
- double iCN = currentData.CN.Measurements[i];
-
- fileWriter.Write("{0},{1},{2},{3},", time, vAN, vBN, vCN);
- fileWriter.Write("{0},{1},{2},", vAN - vBN, vBN - vCN, vCN - vAN);
- fileWriter.WriteLine("{0},{1},{2}", iAN, iBN, iCN);
- }
- }
- }
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Libraries/FaultData/DataAnalysis/CycleDataGroup.cs b/Libraries/FaultData/DataAnalysis/CycleDataGroup.cs
deleted file mode 100644
index 3129dd76..00000000
--- a/Libraries/FaultData/DataAnalysis/CycleDataGroup.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-//******************************************************************************************************
-// CycleDataGroup.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2014 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- public class CycleDataGroup
- {
- #region [ Members ]
-
- // Constants
- private const int RMSIndex = 0;
- private const int PhaseIndex = 1;
- private const int PeakIndex = 2;
- private const int ErrorIndex = 3;
- private Asset m_asset;
- // Fields
- private DataGroup m_dataGroup;
-
- #endregion
-
- #region [ Constructors ]
-
- public CycleDataGroup(DataGroup dataGroup, Asset asset)
- {
- m_dataGroup = dataGroup;
- m_asset = asset;
- }
-
- #endregion
-
- #region [ Properties ]
-
- public DataSeries RMS
- {
- get
- {
- return m_dataGroup[RMSIndex];
- }
- }
-
- public DataSeries Phase
- {
- get
- {
- return m_dataGroup[PhaseIndex];
- }
- }
-
- public DataSeries Peak
- {
- get
- {
- return m_dataGroup[PeakIndex];
- }
- }
-
- public DataSeries Error
- {
- get
- {
- return m_dataGroup[ErrorIndex];
- }
- }
-
- public Asset Asset
- {
- get
- {
- return m_asset;
- }
- }
- #endregion
-
- #region [ Methods ]
-
- public DataGroup ToDataGroup()
- {
- return m_dataGroup;
- }
-
- public CycleDataGroup ToSubGroup(int startIndex, int endIndex)
- {
- return new CycleDataGroup(m_dataGroup.ToSubGroup(startIndex, endIndex), m_asset);
- }
-
- public CycleDataGroup ToSubGroup(DateTime startTime, DateTime endTime)
- {
- return new CycleDataGroup(m_dataGroup.ToSubGroup(startTime, endTime), m_asset);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/DataGroup.cs b/Libraries/FaultData/DataAnalysis/DataGroup.cs
deleted file mode 100644
index 20d91b75..00000000
--- a/Libraries/FaultData/DataAnalysis/DataGroup.cs
+++ /dev/null
@@ -1,662 +0,0 @@
-//******************************************************************************************************
-// DataGroup.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 05/19/2014 - Stephen C. Wills
-// Generated original version of source code.
-// 12/23/2019 - C. Lackner
-// Adjusted to read data from blob for each dataseries.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone;
-using Gemstone.Data.Model;
-using Ionic.Zlib;
-using Microsoft.Data.SqlClient;
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- public enum DataClassification
- {
- Trend,
- Event,
- FastRMS,
- Unknown
- }
-
- public class DataGroup
- {
- #region [ Members ]
-
- // Constants
-
- ///
- /// Maximum sample rate, in samples per minute, of data classified as .
- ///
- public const double TrendThreshold = 1.0D;
-
- // Fields
- private Asset m_asset;
- private DateTime m_startTime;
- private DateTime m_endTime;
- private int m_samples;
-
- private List m_dataSeries;
- private List m_disturbances;
- private DataClassification m_classification;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public DataGroup()
- {
- m_dataSeries = new List();
- m_disturbances = new List();
- m_classification = DataClassification.Unknown;
- m_asset = null;
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// Asset associated with this datagroup
- public DataGroup(Asset asset)
- {
- m_dataSeries = new List();
- m_disturbances = new List();
- m_classification = DataClassification.Unknown;
- m_asset = asset;
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// Collection of data series to be added to the data group.
- public DataGroup(IEnumerable dataSeries)
- : this()
- {
- foreach (DataSeries series in dataSeries)
- Add(series);
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// Collection of data series to be added to the data group.
- /// Asset associated with this datagroup
- public DataGroup(IEnumerable dataSeries, Asset asset)
- : this(asset)
- {
- foreach (DataSeries series in dataSeries)
- Add(series);
- }
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets the line from which measurements were taken to create the group of data.
- ///
- public Asset Asset
- {
- get
- {
- return m_asset;
- }
- }
-
- ///
- /// Gets the start time of the group of data.
- ///
- public DateTime StartTime
- {
- get
- {
- return m_startTime;
- }
- }
-
- ///
- /// Gets the end time of the group of data.
- ///
- public DateTime EndTime
- {
- get
- {
- return m_endTime;
- }
- }
-
- ///
- /// Gets the number of samples in each series.
- ///
- public int Samples
- {
- get
- {
- return m_samples;
- }
- }
-
- ///
- /// Gets the sample rate, in samples per second,
- /// of the data series in this data group.
- ///
- public double SamplesPerSecond
- {
- get
- {
- if (!m_dataSeries.Any())
- return double.NaN;
-
- return m_dataSeries[0].SampleRate;
- }
- }
-
- ///
- /// Gets the duration, in seconds,
- /// of the data series in this data group.
- ///
- public double Duration
- {
- get
- {
- if (!m_dataSeries.Any())
- return double.NaN;
-
- return m_dataSeries[0].Duration;
- }
- }
-
- ///
- /// Gets the sample rate, in samples per hour,
- /// of the data series in this data group.
- ///
- public double SamplesPerHour
- {
- get
- {
- return (m_samples - 1) / (m_endTime - m_startTime).TotalHours;
- }
- }
-
- ///
- /// Gets flag that indicates whether the data series
- /// in this data group are marked as trend channels.
- ///
- public bool Trend =>
- m_dataSeries.Any(dataSeries => dataSeries.SeriesInfo?.Channel.Trend == true);
-
- ///
- /// Gets the channels contained in this data group.
- ///
- public IReadOnlyList DataSeries
- {
- get
- {
- return m_dataSeries.AsReadOnly();
- }
- }
-
- ///
- /// Gets the disturbances contained in this data group.
- ///
- public IReadOnlyList Disturbances
- {
- get
- {
- return m_disturbances.AsReadOnly();
- }
- }
-
- ///
- /// Gets the classification of this group of data as of the last call to .
- ///
- public DataClassification Classification
- {
- get
- {
- if (m_classification == DataClassification.Unknown)
- Classify();
-
- return m_classification;
- }
- }
-
- public DataSeries this[int index]
- {
- get
- {
- return m_dataSeries[index];
- }
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Adds a channel to the group of data.
- ///
- /// The channel to be added to the group.
- ///
- /// True if the channel was successfully added. False if the channel was excluded
- /// because the channel does not match the other channels already in the data group.
- ///
- public bool Add(DataSeries dataSeries)
- {
- Asset asset;
- DateTime startTime;
- DateTime endTime;
- int samples;
- bool trend;
-
- // Unable to add null data series
- if ((object)dataSeries == null)
- return false;
-
- // Data series without data is irrelevant to data grouping
- if (!dataSeries.DataPoints.Any())
- return false;
-
- // Do not add the same data series twice
- if (m_dataSeries.Contains(dataSeries))
- return false;
-
- // Get information about the line this data is associated with
- if ((object)dataSeries.SeriesInfo != null)
- asset = dataSeries.SeriesInfo.Channel.Asset;
- else
- asset = null;
-
- // Get the start time, end time, number of samples, and
- // trend flag for the data series passed into this function
- startTime = dataSeries.DataPoints[0].Time;
- endTime = dataSeries.DataPoints[dataSeries.DataPoints.Count - 1].Time;
- samples = dataSeries.DataPoints.Count;
- trend = dataSeries.SeriesInfo?.Channel.Trend == true;
-
- // If there are any disturbances in this data group that do not overlap
- // with the data series, do not include the data series in the data group
- if (m_disturbances.Select(disturbance => disturbance.ToRange()).Any(range => range.Start > endTime || range.End < startTime))
- return false;
-
- // If there are any disturbances associated with the data in this group and the data
- // to be added is trending data, do not include the trending data in the data group
- if (m_disturbances.Any() && CalculateSamplesPerMinute(startTime, endTime, samples) <= TrendThreshold)
- return false;
-
- // At this point, if there is no existing data in the data
- // group, add the data as the first series in the data group
- if (m_dataSeries.Count == 0)
- {
- if (m_asset == null)
- {
- m_asset = asset;
- }
- m_startTime = startTime;
- m_endTime = endTime;
- m_samples = samples;
-
- m_dataSeries.Add(dataSeries);
- m_classification = DataClassification.Unknown;
-
- return true;
- }
-
- // If the data being added matches the parameters for this data group, add the data to the data group
- // Note that it does not have to match Asset
- if (startTime == m_startTime && endTime == m_endTime && samples == m_samples && trend == Trend)
- {
- m_dataSeries.Add(dataSeries);
- return true;
- }
-
- return false;
- }
-
- ///
- /// Adds a disturbance to the group of data.
- ///
- /// The disturbance to be added to the group.
- /// True if the disturbance was successfully added.
- public bool Add(ReportedDisturbance disturbance)
- {
- // Unable to add null disturbance
- if ((object)disturbance == null)
- return false;
-
- // Do not add the same disturbance twice
- if (m_disturbances.Contains(disturbance))
- return false;
-
- // If the data in this data group is trending data,
- // do not add the disturbance to the data group
- if (Classification == DataClassification.Trend)
- return false;
-
- // Get the start time and end time of the disturbance.
- DateTime startTime = disturbance.Time;
- DateTime endTime = startTime + disturbance.Duration;
-
- // If there are no data series and no other disturbances,
- // make this the first piece of data to be added to the data group
- if (!m_dataSeries.Any() && !m_disturbances.Any())
- {
- m_startTime = startTime;
- m_endTime = endTime;
- m_disturbances.Add(disturbance);
- m_classification = DataClassification.Event;
- return true;
- }
-
- // If the disturbance overlaps with
- // this data group, add the disturbance
- if (startTime <= m_endTime && m_startTime <= endTime)
- {
- // If the only data in the data group is disturbances,
- // adjust the start time and end time
- if (!m_dataSeries.Any() && startTime < m_startTime)
- m_startTime = startTime;
-
- if (!m_dataSeries.Any() && endTime > m_endTime)
- m_endTime = endTime;
-
- m_disturbances.Add(disturbance);
- return true;
- }
-
- return false;
- }
-
- ///
- /// Removes a channel from the data group.
- ///
- /// The channel to be removed from the data group.
- /// True if the channel existed in the group and was removed; false otherwise.
- public bool Remove(DataSeries dataSeries)
- {
- if (m_dataSeries.Remove(dataSeries))
- {
- m_classification = m_disturbances.Any()
- ? DataClassification.Event
- : DataClassification.Unknown;
-
- return true;
- }
-
- return false;
- }
-
- ///
- /// Removes a disturbance from the data group.
- ///
- /// THe disturbance to be removed from the data group.
- /// True if the disturbance existed in the group and was removed; false otherwise.
- public bool Remove(ReportedDisturbance disturbance)
- {
- if (m_disturbances.Remove(disturbance))
- {
- if (!m_disturbances.Any())
- m_classification = DataClassification.Unknown;
-
- return true;
- }
-
- return false;
- }
-
- public DataGroup ToSubGroup(int startIndex, int endIndex)
- {
- DataGroup subGroup = new DataGroup();
-
- foreach (DataSeries dataSeries in m_dataSeries)
- subGroup.Add(dataSeries.ToSubSeries(startIndex, endIndex));
-
- return subGroup;
- }
-
- public DataGroup ToSubGroup(DateTime startTime, DateTime endTime)
- {
- DataGroup subGroup = new DataGroup();
-
- foreach (DataSeries dataSeries in m_dataSeries)
- subGroup.Add(dataSeries.ToSubSeries(startTime, endTime));
-
- return subGroup;
- }
-
- // Overwrite To Data to save Data into ChannelBlob instead of File Blob
- // This needs to be done to avoid data duplication
- public Dictionary ToData()
- {
- Dictionary result = new Dictionary();
-
- var timeSeries = m_dataSeries[0].DataPoints
- .Select(dataPoint => new { Time = dataPoint.Time.Ticks, Compressed = false })
- .ToList();
-
- for (int i = 1; i < timeSeries.Count; i++)
- {
- long previousTimestamp = m_dataSeries[0][i - 1].Time.Ticks;
- long timestamp = timeSeries[i].Time;
- long diff = timestamp - previousTimestamp;
-
- if (diff >= 0 && diff <= ushort.MaxValue)
- timeSeries[i] = new { Time = diff, Compressed = true };
-
-
- }
-
- int timeSeriesByteLength = timeSeries.Sum(obj => obj.Compressed ? sizeof(ushort) : sizeof(int) + sizeof(long));
- int dataSeriesByteLength = sizeof(int) + (2 * sizeof(double)) + (m_samples * sizeof(ushort));
- int totalByteLength = sizeof(int) + timeSeriesByteLength + dataSeriesByteLength;
-
- foreach (DataSeries dataSeries in m_dataSeries)
- {
- byte[] data = new byte[totalByteLength];
- int offset = 0;
-
- offset += LittleEndian.CopyBytes(m_samples, data, offset);
-
- List uncompressedIndexes = timeSeries
- .Select((obj, Index) => new { obj.Compressed, Index })
- .Where(obj => !obj.Compressed)
- .Select(obj => obj.Index)
- .ToList();
-
- for (int i = 0; i < uncompressedIndexes.Count; i++)
- {
- int index = uncompressedIndexes[i];
- int nextIndex = (i + 1 < uncompressedIndexes.Count) ? uncompressedIndexes[i + 1] : timeSeries.Count;
-
- offset += LittleEndian.CopyBytes(nextIndex - index, data, offset);
- offset += LittleEndian.CopyBytes(timeSeries[index].Time, data, offset);
-
- for (int j = index + 1; j < nextIndex; j++)
- offset += LittleEndian.CopyBytes((ushort)timeSeries[j].Time, data, offset);
- }
-
-
- if (dataSeries.Calculated) continue;
-
- const ushort NaNValue = ushort.MaxValue;
- const ushort MaxCompressedValue = ushort.MaxValue - 1;
- int seriesID = dataSeries.SeriesInfo?.ID ?? 0;
- double range = dataSeries.Maximum - dataSeries.Minimum;
- double decompressionOffset = dataSeries.Minimum;
- double decompressionScale = range / MaxCompressedValue;
- double compressionScale = (decompressionScale != 0.0D) ? 1.0D / decompressionScale : 0.0D;
-
- offset += LittleEndian.CopyBytes(seriesID, data, offset);
- offset += LittleEndian.CopyBytes(decompressionOffset, data, offset);
- offset += LittleEndian.CopyBytes(decompressionScale, data, offset);
-
- foreach (DataPoint dataPoint in dataSeries.DataPoints)
- {
- ushort compressedValue = (ushort)Math.Round((dataPoint.Value - decompressionOffset) * compressionScale);
-
- if (compressedValue == NaNValue)
- compressedValue--;
-
- if (double.IsNaN(dataPoint.Value))
- compressedValue = NaNValue;
-
- offset += LittleEndian.CopyBytes(compressedValue, data, offset);
- }
- byte[] returnArray = GZipStream.CompressBuffer(data);
- returnArray[0] = 0x44;
- returnArray[1] = 0x33;
-
- int dataSeriesID = dataSeries.SeriesInfo?.ID ?? 0;
- result.Add(dataSeriesID, returnArray);
- }
-
- return result ;
- }
-
- public void FromData(List data)
- {
- FromData(null, data);
- }
-
- public void FromData(Meter meter, List dataList)
- {
- var decompressed = dataList.SelectMany(d => ChannelData.Decompress(d));
-
- foreach (Tuple> tuple in decompressed)
- {
- DataSeries dataSeries = new DataSeries();
-
- if (tuple.Item1 > 0 && !(meter is null))
- dataSeries.SeriesInfo = meter.Series.FirstOrDefault(s => s.ID == tuple.Item1);
-
- dataSeries.DataPoints = tuple.Item2;
-
- Add(dataSeries);
- }
- }
-
- private void Classify()
- {
- if (IsTrend())
- m_classification = DataClassification.Trend;
- else if (IsEvent())
- m_classification = DataClassification.Event;
- else if (IsFastRMS())
- m_classification = DataClassification.FastRMS;
- else
- m_classification = DataClassification.Unknown;
- }
-
- private bool IsTrend()
- {
- if (!m_dataSeries.Any() || m_disturbances.Any())
- return false;
-
- double samplesPerMinute = CalculateSamplesPerMinute(m_startTime, m_endTime, m_samples);
- return samplesPerMinute <= TrendThreshold;
- }
-
- private bool IsEvent()
- {
- if (m_disturbances.Any())
- return true;
-
- return m_dataSeries
- .Where(dataSeries => (object)dataSeries.SeriesInfo != null)
- .Where(IsInstantaneous)
- .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementType.Name != "Digital")
- .Any();
- }
-
- private bool IsInstantaneous(DataSeries dataSeries)
- {
- string characteristicName = dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name;
- string seriesTypeName = dataSeries.SeriesInfo.SeriesType.Name;
-
- return (characteristicName == "Instantaneous") &&
- (seriesTypeName == "Values" || seriesTypeName == "Instantaneous");
- }
-
- private bool IsFastRMS()
- {
- return m_dataSeries
- .Where(dataSeries => (object)dataSeries.SeriesInfo != null)
- .Where(IsRMS)
- .Any();
- }
-
- private bool IsRMS(DataSeries dataSeries)
- {
- string characteristicName = dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name;
- string seriesTypeName = dataSeries.SeriesInfo.SeriesType.Name;
-
- return (characteristicName == "RMS") &&
- (seriesTypeName == "Values" || seriesTypeName == "Instantaneous");
- }
-
- private double CalculateSamplesPerMinute(DateTime startTime, DateTime endTime, int samples)
- {
- return (samples - 1) / (endTime - startTime).TotalMinutes;
- }
-
- #endregion
- }
-
- public static partial class TableOperationsExtensions
- {
- public static Event GetEvent(this TableOperations eventTable, FileGroup fileGroup, DataGroup dataGroup)
- {
- int fileGroupID = fileGroup.ID;
- int assetID = dataGroup.Asset.ID;
- DateTime startTime = dataGroup.StartTime;
- DateTime endTime = dataGroup.EndTime;
- int samples = dataGroup.Samples;
-
- IDbDataParameter startTimeParameter = new SqlParameter()
- {
- ParameterName = nameof(dataGroup.StartTime),
- DbType = DbType.DateTime2,
- Value = startTime
- };
-
- IDbDataParameter endTimeParameter = new SqlParameter()
- {
- ParameterName = nameof(dataGroup.EndTime),
- DbType = DbType.DateTime2,
- Value = endTime
- };
-
- RecordRestriction recordRestriction =
- new RecordRestriction("FileGroupID = {0}", fileGroupID) &
- new RecordRestriction("AssetID = {0}", assetID) &
- new RecordRestriction("StartTime = {0}", startTimeParameter) &
- new RecordRestriction("EndTime = {0}", endTimeParameter) &
- new RecordRestriction("Samples = {0}", samples);
-
- return eventTable.QueryRecord(recordRestriction);
- }
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/DataSeries.cs b/Libraries/FaultData/DataAnalysis/DataSeries.cs
deleted file mode 100644
index cbc7d9d1..00000000
--- a/Libraries/FaultData/DataAnalysis/DataSeries.cs
+++ /dev/null
@@ -1,588 +0,0 @@
-//******************************************************************************************************
-// DataSeries.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 05/15/2014 - Stephen C. Wills
-// Generated original version of source code.
-// 07/09/2019 - Christoph Lackner
-// Added length property and Threshhold method.
-//
-//******************************************************************************************************
-
-using Gemstone;
-using Gemstone.Numeric.Interpolation;
-using Ionic.Zlib;
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- ///
- /// Represents a series of data points.
- ///
- public class DataSeries
- {
- #region [ Members ]
-
- // Fields
- private Series m_seriesInfo;
- private List m_dataPoints;
-
- private double? m_duration;
- private double? m_sampleRate;
- private double? m_minimum;
- private double? m_maximum;
- private double? m_average;
-
- #endregion
-
- #region [ Constructors ]
-
- public DataSeries()
- {
- m_dataPoints = new List();
- }
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the configuration information
- /// that defines the data in this series.
- ///
- public Series SeriesInfo
- {
- get
- {
- return m_seriesInfo;
- }
- set
- {
- m_seriesInfo = value;
- }
- }
-
- ///
- /// Gets or sets the data points that make up the series.
- ///
- public List DataPoints
- {
- get
- {
- return m_dataPoints;
- }
- set
- {
- m_dataPoints = value ?? new List();
- m_duration = null;
- m_sampleRate = null;
- m_minimum = null;
- m_maximum = null;
- m_average = null;
- }
- }
-
- ///
- /// Gets the duration of the series, in seconds.
- ///
- public double Duration
- {
- get
- {
- if (m_duration.HasValue)
- return m_duration.Value;
-
- if (!m_dataPoints.Any())
- return double.NaN;
-
- m_duration = m_dataPoints.Last().Time.Subtract(m_dataPoints.First().Time).TotalSeconds;
-
- return m_duration.Value;
- }
- }
-
- ///
- /// Gets the Start Time of the dataseries.
- ///
- public DateTime StartTime
- {
- get
- {
- if (!m_dataPoints.Any())
- return DateTime.MinValue;
- return m_dataPoints.First().Time;
- }
- }
-
- ///
- /// Gets the End Time of the dataseries.
- ///
- public DateTime EndTime
- {
- get
- {
- if (!m_dataPoints.Any())
- return DateTime.MinValue;
- return m_dataPoints.Last().Time;
- }
- }
-
-
- ///
- /// Gets the Length of the series, in datapoints.
- ///
- public int Length
- {
- get
- {
-
- if (!m_dataPoints.Any())
- return 0;
-
- return m_dataPoints.Count;
- }
- }
-
- ///
- /// Gets the sample rate of the series, in samples per second.
- ///
- public double SampleRate
- {
- get
- {
- if (m_sampleRate.HasValue)
- return m_sampleRate.Value;
-
- if (!m_dataPoints.Any())
- return double.NaN;
-
- int index = (m_dataPoints.Count > 128) ? 128 : m_dataPoints.Count - 1;
-
- m_sampleRate = (Duration != 0.0D)
- ? index / (m_dataPoints[index].Time - m_dataPoints[0].Time).TotalSeconds
- : double.NaN;
-
- return m_sampleRate.Value;
- }
- }
-
- ///
- /// Gets the maximum value in the series.
- ///
- public double Maximum
- {
- get
- {
- if (m_maximum.HasValue)
- return m_maximum.Value;
-
- if (!m_dataPoints.Any(dataPoint => !double.IsNaN(dataPoint.Value)))
- return double.NaN;
-
- m_maximum = m_dataPoints
- .Select(point => point.Value)
- .Where(value => !double.IsNaN(value))
- .Max();
-
- return m_maximum.Value;
- }
- }
-
- ///
- /// Gets the minimum value in the series.
- ///
- public double Minimum
- {
- get
- {
- if (m_minimum.HasValue)
- return m_minimum.Value;
-
- if (!m_dataPoints.Any(dataPoint => !double.IsNaN(dataPoint.Value)))
- return double.NaN;
-
- m_minimum = m_dataPoints
- .Select(dataPoint => dataPoint.Value)
- .Where(value => !double.IsNaN(value))
- .Min();
-
- return m_minimum.Value;
- }
- }
-
- ///
- /// Gets the average value in the series.
- ///
- public double Average
- {
- get
- {
- if (m_average.HasValue)
- return m_average.Value;
-
- if (!m_dataPoints.Any(dataPoint => !double.IsNaN(dataPoint.Value)))
- return double.NaN;
-
- m_average = m_dataPoints
- .Select(dataPoint => dataPoint.Value)
- .Where(value => !double.IsNaN(value))
- .Average();
-
- return m_average.Value;
- }
- }
-
- public DataPoint this[int index]
- {
- get
- {
- return m_dataPoints[index];
- }
- }
-
- ///
- /// Flag that tells the DataGroup .ToData function not to add to data blob because this value is calculated.
- ///
- public bool Calculated { get; set; } = false;
-
- #endregion
-
- #region [ Methods ]
-
-
- ///
- /// Creates a new that is a subset.
- ///
- /// The index at which the new DataSeries starts.
- /// The index at which the new DataSeries ends.
- /// a new
- public DataSeries ToSubSeries(int startIndex, int endIndex)
- {
- DataSeries subSeries = new DataSeries();
- int count;
-
- subSeries.SeriesInfo = m_seriesInfo;
-
- if (startIndex < 0)
- startIndex = 0;
-
- if (endIndex >= m_dataPoints.Count)
- endIndex = m_dataPoints.Count - 1;
-
- count = endIndex - startIndex + 1;
-
- if (count > 0)
- subSeries.DataPoints = m_dataPoints.Skip(startIndex).Take(count).ToList();
-
- return subSeries;
- }
-
- ///
- /// Creates a new that is a subset.
- ///
- /// The index at which the new DataSeries starts.
- /// a new
- public DataSeries ToSubSeries(int startSeries) => ToSubSeries(startSeries, this.Length);
-
- public DataSeries ToSubSeries(DateTime startTime, DateTime endTime)
- {
- DataSeries subSeries = new DataSeries();
-
- subSeries.SeriesInfo = m_seriesInfo;
-
- subSeries.DataPoints = m_dataPoints
- .SkipWhile(point => point.Time < startTime)
- .TakeWhile(point => point.Time <= endTime)
- .ToList();
-
- return subSeries;
- }
-
- ///
- /// Creates a new that is a subset.
- ///
- /// The time at which the new DataSeries starts.
- /// a new
- public DataSeries ToSubSeries(DateTime startTime) => ToSubSeries(startTime, this[this.Length - 1].Time);
-
- public DataSeries Shift(TimeSpan timeShift)
- {
- DataSeries shifted = new DataSeries();
-
- shifted.SeriesInfo = m_seriesInfo;
-
- shifted.DataPoints = m_dataPoints
- .Select(dataPoint => dataPoint.Shift(timeShift))
- .ToList();
-
- return shifted;
- }
-
- public DataSeries Negate()
- {
- DataSeries negatedDataSeries = new DataSeries();
-
- negatedDataSeries.DataPoints = m_dataPoints
- .Select(point => point.Negate())
- .ToList();
-
- return negatedDataSeries;
- }
-
- public DataSeries Add(DataSeries operand)
- {
- DataSeries sum = new DataSeries();
-
- if (m_dataPoints.Count != operand.DataPoints.Count)
- throw new InvalidOperationException("Cannot take the sum of series with mismatched time values");
-
- sum.DataPoints = m_dataPoints
- .Zip(operand.DataPoints, Add)
- .ToList();
-
- return sum;
- }
-
- public DataSeries Subtract(DataSeries operand)
- {
- return Add(operand.Negate());
- }
-
- public DataSeries Multiply(double value)
- {
- DataSeries result = new DataSeries();
-
- result.DataPoints = m_dataPoints
- .Select(point => point.Multiply(value))
- .ToList();
-
- return result;
- }
-
- public DataSeries Copy()
- {
- return Multiply(1.0D);
- }
-
- public int Threshhold(double value)
- {
- return m_dataPoints.FindIndex(x => x.LargerThan(value));
- }
-
- ///
- /// Downsamples the current DataSeries to requested sample count, if the
- ///
- ///
- public void Downsample(int maxSampleCount)
- {
- // don't actually downsample, if it doesn't need it.
- if (DataPoints.Count <= maxSampleCount) return;
-
- DateTime epoch = new DateTime(1970, 1, 1);
- double startTime = StartTime.Subtract(epoch).TotalMilliseconds;
- double endTime = EndTime.Subtract(epoch).TotalMilliseconds;
- List data = new List();
-
- // milliseconds per returned sampled size
- int step = (int)(Duration*1000) / maxSampleCount;
- if (step < 1)
- step = 1;
-
- int index = 0;
- for (double n = startTime * 1000; n <= endTime * 1000; n += 2 * step)
- {
- DataPoint min = null;
- DataPoint max = null;
-
- while (index < DataPoints.Count() && DataPoints[index].Time.Subtract(epoch).TotalMilliseconds * 1000 < n + 2 * step)
- {
- if (min == null || min.Value > DataPoints[index].Value)
- min = DataPoints[index];
-
- if (max == null || max.Value <= DataPoints[index].Value)
- max = DataPoints[index];
-
- ++index;
- }
-
- if (min != null)
- {
- if (min.Time < max.Time)
- {
- data.Add(min);
- data.Add(max);
- }
- else if (min.Time > max.Time)
- {
- data.Add(max);
- data.Add(min);
- }
- else
- {
- data.Add(min);
- }
- }
- }
- DataPoints = data;
- }
-
- ///
- /// Upsamples the current DataSeries to requested sample count, assuming the requested rate is larger than the current
- ///
- ///
- public void Upsample(int minSamplesPerCycle, double systemFrequency)
- {
- // don't actually upsample, if it doesn't need it.
- if (minSamplesPerCycle <= 0)
- return;
- TimeSpan duration = EndTime - StartTime;
- double cycles = duration.TotalSeconds * systemFrequency;
- int minSampleCount = (int)Math.Round(cycles * minSamplesPerCycle);
- if (minSampleCount <= DataPoints.Count)
- return;
-
- // Creating spline fit to perform upsampling
- List xValues = DataPoints
- .Select(point => (double) point.Time.Subtract(StartTime).Ticks)
- .ToList();
- List yValues= DataPoints
- .Select(point => point.Value)
- .ToList();
- SplineFit splineFit = SplineFit.ComputeCubicSplines(xValues, yValues);
-
- List data = Enumerable
- .Range(0, minSampleCount)
- .Select(sample => sample * duration.Ticks / minSampleCount)
- .Select(sampleTicks =>
- new DataPoint()
- {
- Time = StartTime.AddTicks(sampleTicks),
- Value = splineFit.CalculateY(sampleTicks)
- }
- ).ToList();
-
- DataPoints = data;
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Methods
-
- public static DataSeries Merge(IEnumerable dataSeriesList)
- {
- if (dataSeriesList == null)
- throw new ArgumentNullException(nameof(dataSeriesList));
-
- DataSeries mergedSeries = new DataSeries();
- DateTime lastTime = default(DateTime);
-
- IEnumerable dataPoints = dataSeriesList
- .Where(dataSeries => dataSeries != null)
- .Where(dataSeries => dataSeries.DataPoints.Count != 0)
- .OrderBy(dataSeries => dataSeries[0].Time)
- .SelectMany(series => series.DataPoints);
-
- foreach (DataPoint next in dataPoints)
- {
- if (mergedSeries.DataPoints.Count == 0 || next.Time > lastTime)
- {
- mergedSeries.DataPoints.Add(next);
- lastTime = next.Time;
- }
- }
-
- return mergedSeries;
- }
-
- private static DataPoint Add(DataPoint point1, DataPoint point2)
- {
- return point1.Add(point2);
- }
-
- public static DataSeries FromData(Meter meter, byte[] data)
- {
-
- if (data == null)
- return null;
-
- // Restore the GZip header before uncompressing
- data[0] = 0x1F;
- data[1] = 0x8B;
-
- byte[] uncompressedData = GZipStream.UncompressBuffer(data);
- int offset = 0;
-
- int samples = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- List times = new List();
-
- while (times.Count < samples)
- {
- int timeValues = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- long currentValue = LittleEndian.ToInt64(uncompressedData, offset);
- offset += sizeof(long);
- times.Add(new DateTime(currentValue));
-
- for (int i = 1; i < timeValues; i++)
- {
- currentValue += LittleEndian.ToUInt16(uncompressedData, offset);
- offset += sizeof(ushort);
- times.Add(new DateTime(currentValue));
- }
- }
-
- DataSeries dataSeries = new DataSeries();
- int seriesID = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- if (seriesID > 0 && !(meter is null))
- dataSeries.SeriesInfo = meter.Series.FirstOrDefault(s => s.ID == seriesID);
-
- const ushort NaNValue = ushort.MaxValue;
- double decompressionOffset = LittleEndian.ToDouble(uncompressedData, offset);
- double decompressionScale = LittleEndian.ToDouble(uncompressedData, offset + sizeof(double));
- offset += 2 * sizeof(double);
-
- for (int i = 0; i < samples; i++)
- {
- ushort compressedValue = LittleEndian.ToUInt16(uncompressedData, offset);
- offset += sizeof(ushort);
-
- double decompressedValue = decompressionScale * compressedValue + decompressionOffset;
-
- if (compressedValue == NaNValue)
- decompressedValue = double.NaN;
-
- dataSeries.DataPoints.Add(new DataPoint()
- {
- Time = times[i],
- Value = decompressedValue
- });
- }
-
- return dataSeries;
-
- }
-
- #endregion
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/ReportedDisturbance.cs b/Libraries/FaultData/DataAnalysis/ReportedDisturbance.cs
deleted file mode 100644
index a078eb5b..00000000
--- a/Libraries/FaultData/DataAnalysis/ReportedDisturbance.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-//******************************************************************************************************
-// ReportedDisturbance.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 12/06/2017 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone;
-using Gemstone.PQDIF.Logical;
-
-namespace FaultData.DataAnalysis
-{
- public class ReportedDisturbance
- {
- public ReportedDisturbance(Phase phase, DateTime time, double max, double min, double avg, TimeSpan duration, QuantityUnits units)
- {
- Phase = phase;
- Time = time;
- Maximum = max;
- Minimum = min;
- Average = avg;
- Duration = duration;
- Units = units;
- }
-
- public Phase Phase { get; }
- public DateTime Time { get; }
- public double Maximum { get; }
- public double Minimum { get; }
- public double Average { get; }
- public TimeSpan Duration { get; }
- public QuantityUnits Units { get; }
-
- public ReportedDisturbance ShiftTimestampTo(DateTime shiftedTime) =>
- new ReportedDisturbance(Phase, shiftedTime, Maximum, Minimum, Average, Duration, Units);
-
- public Range ToRange()
- {
- return new Range(Time, Time + Duration);
- }
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/Transform.cs b/Libraries/FaultData/DataAnalysis/Transform.cs
deleted file mode 100644
index 9e4aa28d..00000000
--- a/Libraries/FaultData/DataAnalysis/Transform.cs
+++ /dev/null
@@ -1,358 +0,0 @@
-//******************************************************************************************************
-// Transform.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/28/2014 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Numeric.Analysis;
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- public static class Transform
- {
- public static DataGroup Combine(params DataGroup[] dataGroups)
- {
- DataGroup combination = new DataGroup();
-
- foreach (DataGroup dataGroup in dataGroups)
- {
- foreach (DataSeries dataSeries in dataGroup.DataSeries)
- combination.Add(dataSeries);
- }
-
- return combination;
- }
-
- public static VICycleDataGroup ToVICycleDataGroup(VIDataGroup dataGroup, double frequency, bool compress = false)
- {
- DataSeries[] cycleSeries = dataGroup.Data;
-
- return new VICycleDataGroup(cycleSeries
- .Where(dataSeries => (object)dataSeries != null)
- .Select(dataSeries => ToCycleDataGroup(dataSeries, frequency, compress))
- .ToList(), dataGroup.Asset);
- }
-
- public static CycleDataGroup ToCycleDataGroup(DataSeries dataSeries, double frequency, bool compress=false)
- {
- if (dataSeries is null)
- return null;
-
- DataSeries rmsSeries = new DataSeries();
- DataSeries phaseSeries = new DataSeries();
- DataSeries peakSeries = new DataSeries();
- DataSeries errorSeries = new DataSeries();
-
- // Set series info to the source series info
- rmsSeries.SeriesInfo = dataSeries.SeriesInfo;
- phaseSeries.SeriesInfo = dataSeries.SeriesInfo;
- peakSeries.SeriesInfo = dataSeries.SeriesInfo;
- errorSeries.SeriesInfo = dataSeries.SeriesInfo;
-
- // Get samples per cycle of the data series based on the given frequency
- int samplesPerCycle = CalculateSamplesPerCycle(dataSeries, frequency);
-
- //preinitialize size of SeriesInfo
- int ncycleData = dataSeries.DataPoints.Count - samplesPerCycle + 1;
-
- if (ncycleData <= 0)
- return null;
-
- rmsSeries.DataPoints.Capacity = ncycleData;
- phaseSeries.DataPoints.Capacity = ncycleData;
- peakSeries.DataPoints.Capacity = ncycleData;
- errorSeries.DataPoints.Capacity = ncycleData;
-
- // Initialize arrays of y-values and t-values for calculating cycle data as necessary
- double[] yValues = new double[samplesPerCycle];
- double[] tValues = new double[samplesPerCycle];
-
- void CaptureCycle(int cycleIndex)
- {
- DateTime startTime = dataSeries.DataPoints[0].Time;
-
- for (int i = 0; i < samplesPerCycle; i++)
- {
- DateTime time = dataSeries.DataPoints[cycleIndex + i].Time;
- double value = dataSeries.DataPoints[cycleIndex + i].Value;
- tValues[i] = time.Subtract(startTime).TotalSeconds;
- yValues[i] = value;
- }
- }
-
- // Obtain a list of time gaps in the data series
- List gapIndexes = Enumerable.Range(0, dataSeries.DataPoints.Count - 1)
- .Where(index =>
- {
- DataPoint p1 = dataSeries[index];
- DataPoint p2 = dataSeries[index + 1];
- double cycleDiff = (p2.Time - p1.Time).TotalSeconds * frequency;
-
- // Detect gaps larger than a quarter cycle.
- // Tolerance of 0.000062 calculated
- // assuming 3.999 samples per cycle
- return (cycleDiff > 0.250062);
- })
- .ToList();
-
- double sum = 0;
-
- if (dataSeries.DataPoints.Count >= samplesPerCycle)
- {
- CaptureCycle(0);
- sum = yValues.Sum(y => y * y);
-
- DateTime cycleTime = dataSeries.DataPoints[0].Time;
- SineWave sineFit = WaveFit.SineFit(yValues, tValues, frequency);
- double phase = sineFit.Phase;
-
- double ComputeSineError() => tValues
- .Select(sineFit.CalculateY)
- .Zip(yValues, (estimate, value) => Math.Abs(estimate - value))
- .Sum();
-
- double sineError = ComputeSineError();
- double previousSineError = sineError;
-
- rmsSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = Math.Sqrt(sum / samplesPerCycle)
- });
-
- phaseSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = phase
- });
-
- peakSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = sineFit.Amplitude
- });
-
- errorSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = sineError
- });
-
- // Reduce RMS to max 2 pt per cycle to get half cycle RMS
- int step = 1;
- if (compress)
- step = (int)Math.Floor(samplesPerCycle / 2.0D);
- if (step == 0)
- step = 1;
-
- for (int cycleIndex = step; cycleIndex < dataSeries.DataPoints.Count - samplesPerCycle + 1; cycleIndex += step)
- {
- for (int j = 0; j < step; j++)
- {
- int oldIndex = cycleIndex - step + j;
- int newIndex = oldIndex + samplesPerCycle;
- double oldValue = dataSeries.DataPoints[oldIndex].Value;
- double newValue = dataSeries.DataPoints[newIndex].Value;
- sum += newValue * newValue - oldValue * oldValue;
- }
-
- // If the cycle following i contains a data gap, do not calculate cycle data
- if (gapIndexes.Any(index => cycleIndex <= index && (cycleIndex + samplesPerCycle - 1) > index))
- continue;
-
- phase += 2 * Math.PI * frequency * (dataSeries.DataPoints[cycleIndex].Time - cycleTime).TotalSeconds;
-
- // Use the time of the first data point in the cycle as the time of the cycle
- cycleTime = dataSeries.DataPoints[cycleIndex].Time;
-
- CaptureCycle(cycleIndex);
-
- if (compress)
- sineError = ComputeSineError();
-
- if (!compress || Math.Abs(previousSineError - sineError) > sineError * 0.0001)
- {
- sineFit = WaveFit.SineFit(yValues, tValues, frequency);
- phase = sineFit.Phase;
- sineError = ComputeSineError();
- }
-
- previousSineError = sineError;
-
- rmsSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = Math.Sqrt(sum / samplesPerCycle)
- });
-
- phaseSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = phase
- });
-
- peakSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = sineFit.Amplitude
- });
-
- errorSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = sineError
- });
- }
- }
-
- // Add a series to the data group for each series of cycle data
- DataGroup dataGroup = new DataGroup();
- dataGroup.Add(rmsSeries);
- dataGroup.Add(phaseSeries);
- dataGroup.Add(peakSeries);
- dataGroup.Add(errorSeries);
-
- return new CycleDataGroup(dataGroup, dataSeries.SeriesInfo.Channel.Asset);
- }
-
- public static DataSeries ToRMS(DataSeries dataSeries, double frequency, bool compress = false)
- {
- DataSeries rmsSeries = new DataSeries();
-
- int samplesPerCycle;
- double[] yValues;
- double[] tValues;
- double sum;
-
- DateTime cycleTime;
-
- if ((object)dataSeries == null)
- return null;
-
- // Set series info to the source series info
- rmsSeries.SeriesInfo = dataSeries.SeriesInfo;
-
-
- // Get samples per cycle of the data series based on the given frequency
- samplesPerCycle = Transform.CalculateSamplesPerCycle(dataSeries, frequency);
-
- //preinitialize size of SeriesInfo
- int ncycleData = dataSeries.DataPoints.Count - samplesPerCycle;
- rmsSeries.DataPoints = new List(ncycleData);
-
-
-
- // Initialize arrays of y-values and t-values for calculating cycle data as necessary
- yValues = new double[samplesPerCycle];
- tValues = new double[samplesPerCycle];
-
- // Obtain a list of time gaps in the data series
- List gapIndexes = Enumerable.Range(0, dataSeries.DataPoints.Count - 1)
- .Where(index =>
- {
- DataPoint p1 = dataSeries[index];
- DataPoint p2 = dataSeries[index + 1];
- double cycleDiff = (p2.Time - p1.Time).TotalSeconds * frequency;
-
- // Detect gaps larger than a quarter cycle.
- // Tolerance of 0.000062 calculated
- // assuming 3.999 samples per cycle
- return (cycleDiff > 0.250062);
- })
- .ToList();
-
- sum = 0;
-
- if (dataSeries.DataPoints.Count > samplesPerCycle)
- {
- sum = dataSeries.DataPoints.Take(samplesPerCycle).Sum(pt => pt.Value * pt.Value);
-
- rmsSeries.DataPoints.Add(new DataPoint()
- {
- Time = dataSeries.DataPoints[0].Time,
- Value = Math.Sqrt(sum / samplesPerCycle)
- });
-
- cycleTime = dataSeries.DataPoints[0].Time;
-
- // Reduce RMS to max 2 pt per cycle to get half cycle RMS
- int step = 1;
- if (compress)
- step = (int)Math.Floor(samplesPerCycle / 2.0D);
- if (step == 0)
- step = 1;
-
- for (int i = step; i < dataSeries.DataPoints.Count - samplesPerCycle; i = i + step)
- {
-
- for (int j = 0; j < step; j++)
- {
- sum = sum - dataSeries.DataPoints[i - step + j].Value * dataSeries.DataPoints[i - step + j].Value;
- sum = sum + dataSeries.DataPoints[i - step + j + samplesPerCycle].Value * dataSeries.DataPoints[i - step + j + samplesPerCycle].Value;
- }
-
- // If the cycle following i contains a data gap, do not calculate cycle data
- if (gapIndexes.Any(index => i <= index && (i + samplesPerCycle - 1) > index))
- continue;
-
- // Use the time of the first data point in the cycle as the time of the cycle
- cycleTime = dataSeries.DataPoints[i].Time;
-
- rmsSeries.DataPoints.Add(new DataPoint()
- {
- Time = cycleTime,
- Value = Math.Sqrt(sum / samplesPerCycle)
- });
-
- }
- }
-
- return rmsSeries;
- }
-
- public static List ToValues(DataSeries series)
- {
- return series.DataPoints
- .Select(dataPoint => dataPoint.Value)
- .ToList();
- }
-
- public static int CalculateSamplesPerCycle(DataSeries dataSeries, double frequency)
- {
- return CalculateSamplesPerCycle(dataSeries.SampleRate, frequency);
- }
-
- public static int CalculateSamplesPerCycle(double samplesPerSecond, double frequency)
- {
- int[] commonSampleRates =
- {
- 4, 8, 16, 32,
- 80, 96, 100, 200,
- 64, 128, 256, 512, 1024
- };
-
- int calculatedRate = (int)Math.Round(samplesPerSecond / frequency);
- int nearestCommonRate = commonSampleRates.MinBy(rate => Math.Abs(calculatedRate - rate));
- int diff = Math.Abs(calculatedRate - nearestCommonRate);
- return (diff < nearestCommonRate * 0.1D) ? nearestCommonRate : calculatedRate;
- }
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/VICycleDataGroup.cs b/Libraries/FaultData/DataAnalysis/VICycleDataGroup.cs
deleted file mode 100644
index d913f052..00000000
--- a/Libraries/FaultData/DataAnalysis/VICycleDataGroup.cs
+++ /dev/null
@@ -1,476 +0,0 @@
-//******************************************************************************************************
-// VICycleDataGroup.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2014 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using FaultAlgorithms;
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- public class VICycleDataGroup
- {
- #region [ Members ]
-
- // Fields
- private List m_vIndices;
- private Asset m_asset;
-
- private int m_iaIndex;
- private int m_ibIndex;
- private int m_icIndex;
- private int m_irIndex;
-
- private List m_cycleDataGroups;
-
- private class VIndices
- {
- public int Va;
- public int Vb;
- public int Vc;
-
- public int Vab;
- public int Vbc;
- public int Vca;
-
- public int distance;
- public VIndices()
- {
- Va = -1;
- Vb = -1;
- Vc = -1;
- Vab = -1;
- Vbc = -1;
- Vca = -1;
-
- distance = -1;
- }
-
- public int DefinedNeutralVoltages
- {
- get
- {
- return ((Va > -1) ? 1 : 0) + ((Vb > -1) ? 1 : 0) + ((Vc > -1) ? 1 : 0);
- }
- }
-
- public int DefinedLineVoltages
- {
- get
- {
- return ((Vab > -1) ? 1 : 0) + ((Vbc > -1) ? 1 : 0) + ((Vca > -1) ? 1 : 0);
- }
- }
-
- public bool allVoltagesDefined
- {
- get
- {
- return ((Vab > -1) && (Vbc > -1) && (Vca > -1) &&
- (Va > -1) && (Vb > -1) && (Vc > -1));
- }
- }
-
- }
-
-
- public double VBase => m_asset.VoltageKV;
-
- #endregion
-
- #region [ Constructors ]
-
- public VICycleDataGroup(DataGroup dataGroup)
- {
- m_vIndices = new List();
- m_asset = dataGroup.Asset;
-
- m_cycleDataGroups = dataGroup.DataSeries
- .Select((dataSeries, index) => new { DataSeries = dataSeries, Index = index })
- .GroupBy(obj => obj.Index / 4)
- .Where(grouping => grouping.Count() >= 4)
- .Select(grouping => grouping.Select(obj => obj.DataSeries))
- .Select(grouping => new CycleDataGroup(new DataGroup(grouping, dataGroup.Asset), dataGroup.Asset))
- .ToList();
-
- MapIndexes();
- }
-
- public VICycleDataGroup(List cycleDataGroups, Asset asset)
- {
- m_vIndices = new List();
- m_cycleDataGroups = new List(cycleDataGroups);
- m_asset = asset;
- MapIndexes();
- }
-
- #endregion
-
- #region [ Properties ]
-
- public CycleDataGroup VA
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Va >= 0) ? m_cycleDataGroups[m_vIndices[0].Va] : null;
- }
- }
-
- public CycleDataGroup VB
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Vb >= 0) ? m_cycleDataGroups[m_vIndices[0].Vb] : null;
- }
- }
-
- public CycleDataGroup VC
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Vc >= 0) ? m_cycleDataGroups[m_vIndices[0].Vc] : null;
- }
- }
-
- public CycleDataGroup VAB
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Vab >= 0) ? m_cycleDataGroups[m_vIndices[0].Vab] : null;
- }
- }
-
- public CycleDataGroup VBC
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Vbc >= 0) ? m_cycleDataGroups[m_vIndices[0].Vbc] : null;
- }
- }
-
- public CycleDataGroup VCA
- {
- get
- {
- return (m_vIndices.Count > 0 && m_vIndices[0].Vca >= 0) ? m_cycleDataGroups[m_vIndices[0].Vca] : null;
- }
- }
-
- public CycleDataGroup IA
- {
- get
- {
- return (m_iaIndex >= 0) ? m_cycleDataGroups[m_iaIndex] : null;
- }
- }
-
- public CycleDataGroup IB
- {
- get
- {
- return (m_ibIndex >= 0) ? m_cycleDataGroups[m_ibIndex] : null;
- }
- }
-
- public CycleDataGroup IC
- {
- get
- {
- return (m_icIndex >= 0) ? m_cycleDataGroups[m_icIndex] : null;
- }
- }
-
- public CycleDataGroup IR
- {
- get
- {
- return (m_irIndex >= 0) ? m_cycleDataGroups[m_irIndex] : null;
- }
- }
-
- public List CycleDataGroups {
- get {
- return m_cycleDataGroups;
- }
- }
-
- #endregion
-
- #region [ Methods ]
-
- public DataGroup ToDataGroup()
- {
- return Transform.Combine(m_cycleDataGroups
- .Select(cycleDataGroup => cycleDataGroup.ToDataGroup())
- .ToArray());
- }
-
- public VICycleDataGroup ToSubSet(int startIndex, int endIndex)
- {
- return new VICycleDataGroup(m_cycleDataGroups
- .Select(cycleDataGroup => cycleDataGroup.ToSubGroup(startIndex, endIndex))
- .ToList(), m_asset);
- }
-
- public VICycleDataGroup ToSubSet(DateTime startTime, DateTime endTime)
- {
- return new VICycleDataGroup(m_cycleDataGroups
- .Select(cycleDataGroup => cycleDataGroup.ToSubGroup(startTime, endTime))
- .ToList(), m_asset);
- }
-
- public void PushDataTo(CycleDataSet cycleDataSet)
- {
- FaultAlgorithms.CycleData cycleData;
- Cycle[] cycles;
- CycleDataGroup[] cycleDataGroups;
-
- cycleDataGroups = new CycleDataGroup[] { VA, VB, VC, IA, IB, IC };
- cycles = new Cycle[cycleDataGroups.Length];
-
- for (int i = 0; i < VA.ToDataGroup().Samples; i++)
- {
- cycleData = new FaultAlgorithms.CycleData();
-
- cycles[0] = cycleData.AN.V;
- cycles[1] = cycleData.BN.V;
- cycles[2] = cycleData.CN.V;
- cycles[3] = cycleData.AN.I;
- cycles[4] = cycleData.BN.I;
- cycles[5] = cycleData.CN.I;
-
- for (int j = 0; j < cycles.Length; j++)
- {
- if (cycleDataGroups[j] == null)
- continue;
-
- cycles[j].RMS = cycleDataGroups[j].RMS[i].Value;
- cycles[j].Phase = cycleDataGroups[j].Phase[i].Value;
- cycles[j].Peak = cycleDataGroups[j].Peak[i].Value;
- cycles[j].Error = cycleDataGroups[j].Error[i].Value;
- }
-
- cycleDataSet[i] = cycleData;
- }
- }
-
- private void MapIndexes()
- {
-
- m_iaIndex = -1;
- m_ibIndex = -1;
- m_icIndex = -1;
- m_irIndex = -1;
-
- List vaIndices = new List();
- List vbIndices = new List();
- List vcIndices = new List();
- List vabIndices = new List();
- List vbcIndices = new List();
- List vcaIndices = new List();
-
- for (int i = 0; i < m_cycleDataGroups.Count; i++)
- {
- if (isVoltage("AN", m_cycleDataGroups[i]))
- vaIndices.Add(i);
- else if (isVoltage("BN", m_cycleDataGroups[i]))
- vbIndices.Add(i);
- else if (isVoltage("CN", m_cycleDataGroups[i]))
- vcIndices.Add(i);
- else if (isVoltage("AB", m_cycleDataGroups[i]))
- vabIndices.Add(i);
- else if (isVoltage("BC", m_cycleDataGroups[i]))
- vbcIndices.Add(i);
- else if (isVoltage("CA", m_cycleDataGroups[i]))
- vcaIndices.Add(i);
-
- }
-
- //Walk through all Va and try to get corresponding Vb and Vc...
- List ProcessedIndices = new List();
- foreach (int? VaIndex in vaIndices)
- {
- int assetID = m_cycleDataGroups[(int)VaIndex].Asset.ID;
-
- int VbIndex = vbIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VcIndex = vcIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VabIndex = vabIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VbcIndex = vbcIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VcaIndex = vcaIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
-
- VIndices set = new VIndices();
- ProcessedIndices.Add(VaIndex);
- set.Va = (int)VaIndex;
-
- if (VbIndex > -1)
- {
- ProcessedIndices.Add(VbIndex);
- set.Vb = VbIndex;
- }
- if (VcIndex > -1)
- {
- ProcessedIndices.Add(VcIndex);
- set.Vc = VcIndex;
- }
-
- if (VabIndex > -1)
- {
- ProcessedIndices.Add(VabIndex);
- set.Vab = VabIndex;
- }
- if (VbcIndex > -1)
- {
- ProcessedIndices.Add(VbcIndex);
- set.Vbc = VbcIndex;
- }
- if (VcaIndex > -1)
- {
- ProcessedIndices.Add(VcaIndex);
- set.Vca = VcaIndex;
- }
-
-
- if (assetID == m_asset.ID)
- {
- set.distance = 0;
- }
- else
- {
- set.distance = m_asset.DistanceToAsset(assetID);
- }
-
- m_vIndices.Add(set);
- }
-
- // Also walk though all Vab to catch Leftover Cases where Va is not present
- foreach (int? VabIndex in vabIndices)
- {
- int assetID = m_cycleDataGroups[(int)VabIndex].Asset.ID;
-
- int VaIndex = vaIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VbIndex = vbIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VcIndex = vcIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
-
- int VbcIndex = vbcIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
- int VcaIndex = vcaIndices.Cast().FirstOrDefault(i => m_cycleDataGroups[(int)i].Asset.ID == assetID && !ProcessedIndices.Contains(i)) ?? -1;
-
- VIndices set = new VIndices();
- ProcessedIndices.Add(VabIndex);
- set.Vab = (int)VabIndex;
-
- if (VbIndex > -1)
- {
- ProcessedIndices.Add(VbIndex);
- set.Vb = VbIndex;
- }
- if (VcIndex > -1)
- {
- ProcessedIndices.Add(VcIndex);
- set.Vc = VcIndex;
- }
-
- if (VaIndex > -1)
- {
- ProcessedIndices.Add(VaIndex);
- set.Va = VaIndex;
- }
- if (VbcIndex > -1)
- {
- ProcessedIndices.Add(VbcIndex);
- set.Vbc = VbcIndex;
- }
- if (VcaIndex > -1)
- {
- ProcessedIndices.Add(VcaIndex);
- set.Vca = VcaIndex;
- }
-
-
- if (assetID == m_asset.ID)
- {
- set.distance = 0;
- }
- else
- {
- set.distance = m_asset.DistanceToAsset(assetID);
- }
-
- m_vIndices.Add(set);
- }
-
- for (int i = 0; i < m_cycleDataGroups.Count; i++)
- {
- string measurementType = m_cycleDataGroups[i].RMS.SeriesInfo.Channel.MeasurementType.Name;
- string phase = m_cycleDataGroups[i].RMS.SeriesInfo.Channel.Phase.Name;
-
-
- if (measurementType == "Current" && phase == "AN")
- m_iaIndex = i;
- else if (measurementType == "Current" && phase == "BN")
- m_ibIndex = i;
- else if (measurementType == "Current" && phase == "CN")
- m_icIndex = i;
- else if (measurementType == "Current" && phase == "RES")
- m_irIndex = i;
- }
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Methods
-
- private static bool isVoltage(string phase, CycleDataGroup dataGroup)
- {
-
- string measurementType = dataGroup.RMS.SeriesInfo.Channel.MeasurementType.Name;
- string seriesPhase = dataGroup.RMS.SeriesInfo.Channel.Phase.Name;
-
- if (measurementType != "Voltage")
- return false;
-
- if (seriesPhase != phase)
- return false;
-
- return true;
-
- }
-
- private static bool isCurrent(string phase, CycleDataGroup dataGroup)
- {
- string measurementType = dataGroup.RMS.SeriesInfo.Channel.MeasurementType.Name;
- string seriesPhase = dataGroup.RMS.SeriesInfo.Channel.Phase.Name;
-
- if (measurementType != "Current")
- return false;
-
- if (seriesPhase != phase)
- return false;
-
- return true;
-
- }
-
- #endregion
-
- }
-}
diff --git a/Libraries/FaultData/DataAnalysis/VIDataGroup.cs b/Libraries/FaultData/DataAnalysis/VIDataGroup.cs
deleted file mode 100644
index ae088e05..00000000
--- a/Libraries/FaultData/DataAnalysis/VIDataGroup.cs
+++ /dev/null
@@ -1,521 +0,0 @@
-//******************************************************************************************************
-// VIDataGroup.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2014 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data;
-using openXDA.Model;
-
-namespace FaultData.DataAnalysis
-{
- public class VIDataGroup
- {
- #region [ Members ]
-
- // Fields
- private List m_vIndices;
-
- private int m_iaIndex;
- private int m_ibIndex;
- private int m_icIndex;
- private int m_irIndex;
-
- private DataGroup m_dataGroup;
-
- private class VIndices
- {
- public int Va { get; set; } = -1;
- public int Vb { get; set; } = -1;
- public int Vc { get; set; } = -1;
-
- public int Vab { get; set; } = -1;
- public int Vbc { get; set; } = -1;
- public int Vca { get; set; } = -1;
-
- public int Distance { get; set; } = -1;
-
- public int DefinedNeutralVoltages =>
- (Va >= 0 ? 1 : 0) +
- (Vb >= 0 ? 1 : 0) +
- (Vc >= 0 ? 1 : 0);
-
- public int DefinedLineVoltages =>
- (Vab >= 0 ? 1 : 0) +
- (Vbc >= 0 ? 1 : 0) +
- (Vca >= 0 ? 1 : 0);
-
- public bool AllVoltagesDefined =>
- (Va >= 0) && (Vb >= 0) && (Vc >= 0) &&
- (Vab >= 0) && (Vbc >= 0) && (Vca >= 0);
- }
-
- #endregion
-
- #region [ Constructors ]
-
- public VIDataGroup(DataGroup dataGroup)
- {
-
- // Initialize each of
- // the indexes to -1
- m_vIndices = new List();
-
- m_iaIndex = -1;
- m_ibIndex = -1;
- m_icIndex = -1;
- m_irIndex = -1;
-
- // Initialize the data group
- m_dataGroup = new DataGroup(dataGroup.DataSeries, dataGroup.Asset);
-
- HashSet connectedAssets = new HashSet(dataGroup.Asset.ConnectedAssets.Select(item => item.ID));
-
- var groupings = dataGroup.DataSeries
- .Select((DataSeries, Index) => new { DataSeries, Index })
- .Where(item => !(item.DataSeries.SeriesInfo is null))
- .Where(item => item.DataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name == "Instantaneous")
- .Where(item => new[] { "Instantaneous", "Values" }.Contains(item.DataSeries.SeriesInfo.SeriesType.Name))
- .GroupBy(item => item.DataSeries.SeriesInfo.Channel.AssetID)
- .OrderBy(grouping => grouping.Key == dataGroup.Asset.ID ? 0 : 1)
- .ThenBy(grouping => connectedAssets.Contains(grouping.Key) ? 0 : 1)
- .ToList();
-
- foreach (var grouping in groupings)
- {
- VIndices set = new VIndices() { Distance = 0 };
-
- int assetID = grouping.Key;
-
- if (assetID != dataGroup.Asset.ID)
- set.Distance = dataGroup.Asset.DistanceToAsset(assetID);
-
- foreach (var item in grouping)
- {
- string measurementType = item.DataSeries.SeriesInfo.Channel.MeasurementType.Name;
- string phase = item.DataSeries.SeriesInfo.Channel.Phase.Name;
-
- if (measurementType == "Voltage" && phase == "AN")
- set.Va = item.Index;
-
- if (measurementType == "Voltage" && phase == "BN")
- set.Vb = item.Index;
-
- if (measurementType == "Voltage" && phase == "CN")
- set.Vc = item.Index;
-
- if (measurementType == "Voltage" && phase == "AB")
- set.Vab = item.Index;
-
- if (measurementType == "Voltage" && phase == "BC")
- set.Vbc = item.Index;
-
- if (measurementType == "Voltage" && phase == "CA")
- set.Vca = item.Index;
-
- if (m_iaIndex < 0 && measurementType == "Current" && phase == "AN")
- m_iaIndex = item.Index;
-
- if (m_ibIndex < 0 && measurementType == "Current" && phase == "BN")
- m_ibIndex = item.Index;
-
- if (m_icIndex < 0 && measurementType == "Current" && phase == "CN")
- m_icIndex = item.Index;
-
- if (m_irIndex < 0 && measurementType == "Current" && phase == "RES")
- m_irIndex = item.Index;
- }
-
- if (set.DefinedLineVoltages + set.DefinedNeutralVoltages > 0)
- m_vIndices.Add(set);
- }
-
- if (m_vIndices.Count() == 0)
- m_vIndices.Add(new VIndices());
-
- CalculateMissingCurrentChannel();
- CalculateMissingLLVoltageChannels();
-
- m_vIndices.Sort((a, b) =>
- {
- if (b.AllVoltagesDefined && !a.AllVoltagesDefined)
- return 1;
- if (a.AllVoltagesDefined && !b.AllVoltagesDefined)
- return -1;
- if (!(a.Distance >= 0 && b.Distance >= 0))
- return b.Distance.CompareTo(a.Distance);
- return a.Distance.CompareTo(b.Distance);
- });
- }
-
- private VIDataGroup()
- {
- }
-
- #endregion
-
- #region [ Properties ]
-
- public DataSeries VA => (m_vIndices[0].Va >= 0)
- ? m_dataGroup[m_vIndices[0].Va]
- : null;
-
- public DataSeries VB => (m_vIndices[0].Vb >= 0)
- ? m_dataGroup[m_vIndices[0].Vb]
- : null;
-
- public DataSeries VC => (m_vIndices[0].Vc >= 0)
- ? m_dataGroup[m_vIndices[0].Vc]
- : null;
-
- public DataSeries VAB => (m_vIndices[0].Vab >= 0)
- ? m_dataGroup[m_vIndices[0].Vab]
- : null;
-
- public DataSeries VBC => (m_vIndices[0].Vbc >= 0)
- ? m_dataGroup[m_vIndices[0].Vbc]
- : null;
-
- public DataSeries VCA => (m_vIndices[0].Vca >= 0)
- ? m_dataGroup[m_vIndices[0].Vca]
- : null;
-
- public DataSeries IA => (m_iaIndex >= 0)
- ? m_dataGroup[m_iaIndex]
- : null;
-
- public DataSeries IB => (m_ibIndex >= 0)
- ? m_dataGroup[m_ibIndex]
- : null;
-
- public DataSeries IC => (m_icIndex >= 0)
- ? m_dataGroup[m_icIndex]
- : null;
-
- public DataSeries IR => (m_irIndex >= 0)
- ? m_dataGroup[m_irIndex]
- : null;
-
- public int DefinedNeutralVoltages => m_vIndices
- .Select(item => item.DefinedNeutralVoltages)
- .FirstOrDefault();
-
- public int DefinedLineVoltages => m_vIndices
- .Select(item => item.DefinedLineVoltages)
- .FirstOrDefault();
-
- public int DefinedCurrents =>
- CurrentIndexes.Count(index => index >= 0);
-
- public int DefinedPhaseCurrents =>
- PhaseCurrentIndexes.Count(index => index >= 0);
-
- public bool AllVIChannelsDefined =>
- m_vIndices[0].AllVoltagesDefined &&
- CurrentIndexes.All(index => index >= 0);
-
- private int[] CurrentIndexes =>
- new int[] { m_iaIndex, m_ibIndex, m_icIndex, m_irIndex };
-
- private int[] PhaseCurrentIndexes =>
- new int[] { m_iaIndex, m_ibIndex, m_icIndex };
-
- public Asset Asset => m_dataGroup.Asset;
-
- public DataSeries[] Data
- {
- get
- {
- List result = new List();
-
- foreach (VIndices Vindex in m_vIndices)
- {
- if (Vindex.Va > -1)
- result.Add(m_dataGroup[Vindex.Va]);
- if (Vindex.Vb > -1)
- result.Add(m_dataGroup[Vindex.Vb]);
- if (Vindex.Vc > -1)
- result.Add(m_dataGroup[Vindex.Vc]);
-
- if (Vindex.Vab > -1)
- result.Add(m_dataGroup[Vindex.Vab]);
- if (Vindex.Vbc > -1)
- result.Add(m_dataGroup[Vindex.Vbc]);
- if (Vindex.Vca > -1)
- result.Add(m_dataGroup[Vindex.Vca]);
- }
-
- if (m_iaIndex > -1)
- result.Add(m_dataGroup[m_iaIndex]);
- if (m_ibIndex > -1)
- result.Add(m_dataGroup[m_ibIndex]);
- if (m_icIndex > -1)
- result.Add(m_dataGroup[m_icIndex]);
- if (m_irIndex > -1)
- result.Add(m_dataGroup[m_irIndex]);
-
- return result.ToArray();
- }
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Given three of the four current channels, calculates the
- /// missing channel based on the relationship IR = IA + IB + IC.
- ///
- private void CalculateMissingCurrentChannel()
- {
- Meter meter;
- DataSeries missingSeries;
-
- // If the data group does not have exactly 3 channels,
- // then there is no missing channel or there is not
- // enough data to calculate the missing channel
- if (DefinedCurrents != 3)
- return;
-
- // Get the meter associated with the channels in this data group
- meter = (IA ?? IB).SeriesInfo.Channel.Meter;
-
- if (m_iaIndex == -1)
- {
- // Calculate IA = IR - IB - IC
- missingSeries = IR.Add(IB.Negate()).Add(IC.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, IR.SeriesInfo.Channel.Asset, "Current", "AN", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_iaIndex = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
- else if (m_ibIndex == -1)
- {
- // Calculate IB = IR - IA - IC
- missingSeries = IR.Add(IA.Negate()).Add(IC.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, IR.SeriesInfo.Channel.Asset, "Current", "BN", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_ibIndex = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
- else if (m_icIndex == -1)
- {
- // Calculate IC = IR - IA - IB
- missingSeries = IR.Add(IA.Negate()).Add(IB.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, IR.SeriesInfo.Channel.Asset, "Current", "CN", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_icIndex = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
- else
- {
- // Calculate IR = IA + IB + IC
- missingSeries = IA.Add(IB).Add(IC);
- missingSeries.SeriesInfo = GetSeriesInfo(meter, IA.SeriesInfo.Channel.Asset, "Current", "RES", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_irIndex = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
- }
-
- private void CalculateMissingLLVoltageChannels()
- {
- Meter meter;
- DataSeries missingSeries;
-
- //Do this for every Voltage set
- for (int i = 0; i < m_vIndices.Count(); i++)
- {
- // If all line voltages are already present or there are not
- // at least 2 lines we will not perform line to line calculations
- if (m_vIndices[i].DefinedLineVoltages == 3 || m_vIndices[i].DefinedNeutralVoltages < 2)
- continue;
-
- // Get the meter associated with the channels in this data group
- DataSeries VA = null;
- DataSeries VB = null;
- DataSeries VC = null;
-
- if (m_vIndices[i].Va > -1)
- VA = m_dataGroup[m_vIndices[i].Va];
- if (m_vIndices[i].Vb > -1)
- VB = m_dataGroup[m_vIndices[i].Vb];
- if (m_vIndices[i].Vc > -1)
- VC = m_dataGroup[m_vIndices[i].Vc];
-
- meter = (VA ?? VB ?? VC).SeriesInfo.Channel.Meter;
-
- if (m_vIndices[i].Vab == -1 && !(VA is null) && !(VB is null))
- {
- // Calculate VAB = VA - VB
- missingSeries = VA.Add(VB.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, VA.SeriesInfo.Channel.Asset, "Voltage", "AB", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_vIndices[i].Vab = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
-
- if (m_vIndices[i].Vbc == -1 && !(VB is null) && !(VC is null))
- {
- // Calculate VBC = VB - VC
- missingSeries = VB.Add(VC.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, VB.SeriesInfo.Channel.Asset, "Voltage", "BC", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_vIndices[i].Vbc = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
-
- if (m_vIndices[i].Vca == -1 && !(VC is null) && !(VA is null))
- {
- // Calculate VCA = VC - VA
- missingSeries = VC.Add(VA.Negate());
- missingSeries.SeriesInfo = GetSeriesInfo(meter, VC.SeriesInfo.Channel.Asset, "Voltage", "CA", m_dataGroup.SamplesPerHour);
- missingSeries.Calculated = true;
- m_vIndices[i].Vca = m_dataGroup.DataSeries.Count;
- m_dataGroup.Add(missingSeries);
- }
- }
- }
-
- public DataGroup ToDataGroup()
- {
- return new DataGroup(m_dataGroup.DataSeries, m_dataGroup.Asset);
- }
-
- public VIDataGroup ToSubGroup(int startIndex, int endIndex)
- {
- VIDataGroup subGroup = new VIDataGroup();
-
- subGroup.m_vIndices = m_vIndices;
- subGroup.m_iaIndex = m_iaIndex;
- subGroup.m_ibIndex = m_ibIndex;
- subGroup.m_icIndex = m_icIndex;
- subGroup.m_irIndex = m_irIndex;
-
- subGroup.m_dataGroup = m_dataGroup.ToSubGroup(startIndex, endIndex);
-
- return subGroup;
- }
-
- public VIDataGroup ToSubGroup(DateTime startTime, DateTime endTime)
- {
- VIDataGroup subGroup = new VIDataGroup();
-
- subGroup.m_vIndices = m_vIndices;
- subGroup.m_iaIndex = m_iaIndex;
- subGroup.m_ibIndex = m_ibIndex;
- subGroup.m_icIndex = m_icIndex;
- subGroup.m_irIndex = m_irIndex;
-
- subGroup.m_dataGroup = m_dataGroup.ToSubGroup(startTime, endTime);
-
- return subGroup;
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Methods
- private static Series GetSeriesInfo(Meter meter, Asset asset, string measurementTypeName, string phaseName, double samplesPerHour)
- {
- string measurementCharacteristicName = "Instantaneous";
- string seriesTypeName = "Values";
-
- char typeDesignation = (measurementTypeName == "Current") ? 'I' : measurementTypeName[0];
- string phaseDesignation = (phaseName == "RES") ? "R" : phaseName.TrimEnd('N');
- string channelName = string.Concat(typeDesignation, phaseDesignation);
-
- ChannelKey channelKey = new ChannelKey(asset.ID, 0, channelName, measurementTypeName, measurementCharacteristicName, phaseName);
- SeriesKey seriesKey = new SeriesKey(channelKey, seriesTypeName);
-
- Channel dbChannel = (meter.ConnectionFactory is null)
- ? meter.Channels.FirstOrDefault(channel => channelKey.Equals(new ChannelKey(channel)))
- : FastSearch(meter, channelKey);
-
- Series dbSeries = dbChannel?.Series
- .FirstOrDefault(series => seriesKey.Equals(new SeriesKey(series)));
-
- if (dbSeries is null)
- {
- if (dbChannel is null)
- {
- MeasurementType measurementType = new MeasurementType() { Name = measurementTypeName };
- MeasurementCharacteristic measurementCharacteristic = new MeasurementCharacteristic() { Name = measurementCharacteristicName };
- Phase phase = new Phase() { Name = phaseName };
-
- dbChannel = new Channel()
- {
- MeterID = meter.ID,
- AssetID = asset.ID,
- MeasurementTypeID = measurementType.ID,
- MeasurementCharacteristicID = measurementCharacteristic.ID,
- PhaseID = phase.ID,
- Name = channelKey.Name,
- SamplesPerHour = samplesPerHour,
- Description = string.Concat(measurementCharacteristicName, " ", measurementTypeName, " ", phaseName),
- Enabled = true,
-
- Meter = meter,
- Asset = asset,
- MeasurementType = measurementType,
- MeasurementCharacteristic = measurementCharacteristic,
- Phase = phase,
- Series = new List()
- };
-
- meter.Channels.Add(dbChannel);
- }
-
- SeriesType seriesType = new SeriesType() { Name = seriesTypeName };
-
- dbSeries = new Series()
- {
- ChannelID = dbChannel.ID,
- SeriesTypeID = seriesType.ID,
- SourceIndexes = string.Empty,
-
- Channel = dbChannel,
- SeriesType = seriesType
- };
-
- dbChannel.Series.Add(dbSeries);
- }
-
- return dbSeries;
- }
-
- private static Channel FastSearch(Meter meter, ChannelKey channelKey)
- {
- using (AdoDataConnection connection = meter.ConnectionFactory())
- {
- Channel search = channelKey.Find(connection, meter.ID);
-
- if (search is null)
- return null;
-
- return meter.Channels
- .FirstOrDefault(channel => channel.ID == search.ID);
- }
- }
-
- #endregion
- }
-}
diff --git a/Libraries/FaultData/FaultData.csproj b/Libraries/FaultData/FaultData.csproj
deleted file mode 100644
index b19aaa40..00000000
--- a/Libraries/FaultData/FaultData.csproj
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- net9.0
- Debug;Development;Release
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Libraries/openHistorian.XDALink/Historian.cs b/Libraries/openHistorian.XDALink/Historian.cs
deleted file mode 100644
index a7517018..00000000
--- a/Libraries/openHistorian.XDALink/Historian.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-//******************************************************************************************************
-// Historian.cs - Gbtc
-//
-// Copyright © 2015, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/23/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone;
-using Gemstone.WordExtensions;
-using openHistorian.Net;
-using openHistorian.Queues;
-using openHistorian.Snap;
-using SnapDB.Snap;
-using SnapDB.Snap.Filters;
-using SnapDB.Snap.Services;
-using SnapDB.Snap.Services.Reader;
-
-namespace openHistorian.XDALink
-{
- ///
- /// Series ID values.
- ///
- public enum SeriesID
- {
- Minimum = 0,
- Maximum = 1,
- Average = 2
- }
-
- public class Historian : IDisposable
- {
- #region [ Members ]
-
- // Constants
-
- ///
- /// Default historian server port number.
- ///
- public const int DefaultHistorianPort = 38402;
-
- // Fields
- private HistorianClient m_client;
- private ClientDatabaseBase m_database;
- private Lazy m_queue;
- private List> m_treeStreams;
-
- private bool m_disposed;
-
- #endregion
-
- #region [ Constructors ]
-
- public Historian(string server, string database)
- {
- string[] split = server.Split(':');
- int port;
-
- if (split.Length == 1)
- {
- m_client = new HistorianClient(split[0], DefaultHistorianPort);
- }
- else
- {
- if (!int.TryParse(split[1], out port))
- throw new ArgumentException("Invalid format for server[:port]. " + server, "server");
-
- m_client = new HistorianClient(split[0], port);
- }
-
- m_database = m_client.GetDatabase(database);
- m_queue = new Lazy(() => new HistorianInputQueue(() => m_database));
- m_treeStreams = new List>();
- }
-
- #endregion
-
- #region [ Methods ]
-
- public IEnumerable Read(IEnumerable channels, DateTime startTime, DateTime stopTime)
- {
- IEnumerable measurementIDs = channels.SelectMany(GetAllMeasurementIDs);
- return Read(measurementIDs, startTime, stopTime);
- }
-
- public void Write(int channelID, SeriesID seriesID, DateTime timestamp, double value)
- {
- HistorianKey historianKey = new HistorianKey();
- HistorianValue historianValue = new HistorianValue();
-
- historianKey.PointID = ToPointID(channelID, (int)seriesID);
- historianKey.TimestampAsDate = timestamp;
- historianValue.AsSingle = (float)value;
-
- m_queue.Value.Enqueue(historianKey, historianValue);
- }
-
- public void Flush()
- {
- Flush(1);
- }
-
- public void Flush(int pollingFrequency)
- {
- if (m_queue.IsValueCreated)
- {
- while (m_queue.Value.Size > 0)
- Thread.Sleep(1000 / pollingFrequency);
- }
- }
-
- public void Dispose()
- {
- if (!m_disposed)
- {
- try
- {
- foreach (TreeStream stream in m_treeStreams)
- stream.Dispose();
-
- if (m_queue.IsValueCreated)
- {
- Flush(10);
- m_queue.Value.Dispose();
- }
-
- m_database.Dispose();
- m_client.Dispose();
- }
- finally
- {
- m_disposed = true;
- }
- }
- }
-
- private IEnumerable Read(IEnumerable measurementIDs, DateTime startTime, DateTime stopTime)
- {
- SeekFilterBase timeFilter = TimestampSeekFilter.CreateFromRange(startTime, stopTime);
- MatchFilterBase pointFilter = null;
- HistorianKey key = new HistorianKey();
- HistorianValue value = new HistorianValue();
-
- if ((object)measurementIDs != null)
- pointFilter = PointIDMatchFilter.CreateFromList(measurementIDs);
-
- // Start stream reader for the provided time window and selected points
- using (TreeStream stream = m_database.Read(SortedTreeEngineReaderOptions.Default, timeFilter, pointFilter))
- {
- m_treeStreams.Add(stream);
-
- while (stream.Read(key, value))
- {
- yield return new TrendingDataPoint()
- {
- ChannelID = (int)key.PointID.HighDoubleWord(),
- SeriesID = (SeriesID)(int)key.PointID.LowDoubleWord(),
- Timestamp = key.TimestampAsDate,
- Value = value.AsSingle
- };
- }
- }
- }
-
- private IEnumerable GetAllMeasurementIDs(int channel)
- {
- return SeriesIDs.Select(series => ToPointID(channel, (int)series));
- }
-
- #endregion
-
- #region [ Static ]
-
- // Static Fields
- private static readonly List SeriesIDs = Enum.GetValues(typeof(SeriesID))
- .Cast()
- .ToList();
-
- // Static Methods
-
- public static ulong ToPointID(int channel, int series)
- {
- return Word.MakeQuadWord((uint)channel, (uint)series);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openHistorian.XDALink/ImportedMeasurement.cs b/Libraries/openHistorian.XDALink/ImportedMeasurement.cs
deleted file mode 100644
index e6721fb5..00000000
--- a/Libraries/openHistorian.XDALink/ImportedMeasurement.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-//******************************************************************************************************
-// ImportedMeasurement.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 09/27/2017 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-#pragma warning disable 1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
-using System.IO;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Text;
-using Newtonsoft.Json;
-
-namespace openHistorian.XDALink
-{
- public class ImportedMeasurement
- {
- public Guid? NodeID { get; set; }
-
- public Guid? SourceNodeID { get; set; }
-
- public Guid? SignalID { get; set; }
-
- [StringLength(200)]
- public string Source { get; set; }
-
- public long PointID { get; set; }
-
- [StringLength(200)]
- public string PointTag { get; set; }
-
- [StringLength(200)]
- public string AlternateTag { get; set; }
-
- [StringLength(4)]
- public string SignalTypeAcronym { get; set; }
-
- [StringLength(200)]
- public string SignalReference { get; set; }
-
- public int? FramesPerSecond { get; set; }
-
- [StringLength(200)]
- public string ProtocolAcronym { get; set; }
-
- [StringLength(200)]
- [DefaultValue("Frame")]
- public string ProtocolType { get; set; }
-
- public int? PhasorID { get; set; }
-
- public char? PhasorType { get; set; }
-
- public char? Phase { get; set; }
-
- [DefaultValue(0.0D)]
- public double Adder { get; set; }
-
- [DefaultValue(1.0D)]
- public double Multiplier { get; set; }
-
- [StringLength(200)]
- public string CompanyAcronym { get; set; }
-
- public double? Longitude { get; set; }
-
- public double? Latitude { get; set; }
-
- public string Description { get; set; }
-
- [DefaultValue(false)]
- public bool Enabled { get; set; }
- }
-
- public class ImportedMeasurementsTable
- {
- #region [ Members ]
-
- // Fields
- private string m_historianURL;
- private string m_authString;
-
- #endregion
-
- #region [ Constructors ]
-
- public ImportedMeasurementsTable(string historianURL, string username, string password)
- {
- m_historianURL = historianURL;
-
- string unencodedAuthString = $"{username}:{password}";
- byte[] authBytes = Encoding.UTF8.GetBytes(unencodedAuthString);
- m_authString = Convert.ToBase64String(authBytes);
- }
-
- #endregion
-
- #region [ Methods ]
-
- public IEnumerable FindAll()
- {
- string url = GetURL("/api/importedmeasurements/findall");
- return RequestMeasurements(url);
- }
-
- public IEnumerable FindByID(long pointID)
- {
- string url = GetURL($"/api/importedmeasurements/findbyid/{pointID}");
- return RequestMeasurements(url);
- }
-
- public IEnumerable FindByPointTag(string pointTag)
- {
- string url = GetURL($"/api/importedmeasurements/findbypointtag/{pointTag}");
- return RequestMeasurements(url);
- }
-
- public IEnumerable FindByAlternateTag(string alternateTag)
- {
- string url = GetURL($"/api/importedmeasurements/findbyalternatetag/{alternateTag}");
- return RequestMeasurements(url);
- }
-
- public void ImportMeasurements(IEnumerable measurements)
- {
- string antiForgeryToken = GenerateAntiForgeryToken();
- string url = GetURL("/api/importedmeasurements/importmeasurements");
-
- using (MemoryStream stream = new MemoryStream())
- using (StreamWriter writer = new StreamWriter(stream))
- using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
- {
- JsonSerializer serializer = new JsonSerializer();
- serializer.Serialize(jsonWriter, measurements);
- jsonWriter.Flush();
-
- using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url))
- using (ByteArrayContent content = new ByteArrayContent(stream.ToArray()))
- using (HttpClient client = CreateClient())
- {
- request.Content = content;
- request.Headers.Add("X-GSF-Verify", antiForgeryToken);
- content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
- client.SendAsync(request).Result.Dispose();
- }
- }
- }
-
- public void DeleteMeasurement(long pointID)
- {
- string antiForgeryToken = GenerateAntiForgeryToken();
- string url = GetURL($"/api/importedmeasurements/deletemeasurement/{pointID}");
-
- using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, url))
- using (HttpClient client = CreateClient())
- {
- request.Headers.Add("X-GSF-Verify", antiForgeryToken);
- client.SendAsync(request).Result.Dispose();
- }
- }
-
- private IEnumerable RequestMeasurements(string url)
- {
- using (HttpClient client = CreateClient())
- using (Stream response = client.GetStreamAsync(url).Result)
- using (StreamReader streamReader = new StreamReader(response))
- using (JsonTextReader jsonReader = new JsonTextReader(streamReader))
- {
- JsonSerializer serializer = new JsonSerializer();
- return serializer.Deserialize>(jsonReader);
- }
- }
-
- private string GenerateAntiForgeryToken()
- {
- string url = GetURL($"/api/importedmeasurements/generaterequestverficationtoken");
-
- using (HttpClient client = CreateClient())
- {
- return client.GetStringAsync(url).Result;
- }
- }
-
- private string GetURL(string relativePath)
- {
- string baseURL = m_historianURL.TrimEnd('/');
- string subURL = relativePath.TrimStart('/');
- return $"{baseURL}/{subURL}";
- }
-
- private HttpClient CreateClient()
- {
- HttpClient client = new HttpClient();
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", m_authString);
- return client;
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openHistorian.XDALink/TrendingDataPoint.cs b/Libraries/openHistorian.XDALink/TrendingDataPoint.cs
deleted file mode 100644
index 6548742f..00000000
--- a/Libraries/openHistorian.XDALink/TrendingDataPoint.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-//******************************************************************************************************
-// TrendingDataPoint.cs - Gbtc
-//
-// Copyright © 2015, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/23/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-
-namespace openHistorian.XDALink
-{
- public class TrendingDataPoint
- {
- #region [ Members ]
-
- // Fields
- private int m_channelID;
- private SeriesID m_seriesID;
- private DateTime m_timestamp;
- private double m_value;
-
- #endregion
-
- #region [ Properties ]
-
- public int ChannelID
- {
- get
- {
- return m_channelID;
- }
- set
- {
- m_channelID = value;
- }
- }
-
- public SeriesID SeriesID
- {
- get
- {
- return m_seriesID;
- }
- set
- {
- m_seriesID = value;
- }
- }
-
- public DateTime Timestamp
- {
- get
- {
- return m_timestamp;
- }
- set
- {
- m_timestamp = value;
- }
- }
-
- public double Value
- {
- get
- {
- return m_value;
- }
- set
- {
- m_value = value;
- }
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openHistorian.XDALink/openHistorian.XDALink.csproj b/Libraries/openHistorian.XDALink/openHistorian.XDALink.csproj
deleted file mode 100644
index 5e8ee63c..00000000
--- a/Libraries/openHistorian.XDALink/openHistorian.XDALink.csproj
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
- Debug
- AnyCPU
- Library
- openHistorian.XDALink
- openHistorian.XDALink
- net9.0
- Debug;Development;Release
- enable
- true
- enable
-
-
- true
- full
- false
- ..\..\..\Build\Output\Debug\Libraries\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- ..\..\..\Build\Output\Release\Libraries\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
- ..\..\Dependencies\openHistorian\openHistorian.Core.dll
-
-
-
-
-
-
-
-
diff --git a/Libraries/openXDA.APIAuthentication/APIQuery.cs b/Libraries/openXDA.APIAuthentication/APIQuery.cs
deleted file mode 100644
index 58f8643a..00000000
--- a/Libraries/openXDA.APIAuthentication/APIQuery.cs
+++ /dev/null
@@ -1,311 +0,0 @@
-//******************************************************************************************************
-// APIQuery.cs - Gbtc
-//
-// Copyright © 2022, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 07/01/2022 - Christoph Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Net.Sockets;
-using System.Security.Principal;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace openXDA.APIAuthentication
-{
- ///
- /// Exceptions thrown during an API query.
- ///
- public class APIQueryException : Exception
- {
- ///
- /// Creates a new instance of the class.
- ///
- /// The URL of the host that issued the failure.
- /// The error message that explains the reason for the exception.
- /// The exception that is the cause of the current exception.
- public APIQueryException(string hostURL, string message, Exception innerException)
- : base(message, innerException)
- {
- HostURL = hostURL;
- }
-
- ///
- /// The URL of the host that issued the failure.
- ///
- public string HostURL { get; }
- }
-
- ///
- /// Issues requests to the API using API authentication.
- /// This class handles the GSF token and authentication
- ///
- public class APIQuery
- {
- #region [ Members ]
-
- // Nested Types
- private class Host
- {
- public Host(string url) =>
- URL = url;
-
- public string URL { get; }
- public string AntiForgeryToken { get; set; }
- }
-
- private class HostUnreachableException : Exception
- {
- }
-
- // Fields
- private int m_hostIndex;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The API key used to identify the user of the API.
- /// The token used to authenticate the user of the API.
- /// URL that locates the host providing access to the API.
- public APIQuery(string apiKey, string apiToken, string hostURL)
- : this(apiKey, apiToken, new[] { hostURL })
- {
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// The API key used to identify the user of the API.
- /// The token used to authenticate the user of the API.
- /// List of URLs that locate the hosts providing access to the API.
- public APIQuery(string apiKey, string apiToken, IEnumerable hostURLs)
- {
- APIKey = apiKey;
- APIToken = apiToken;
-
- Hosts = hostURLs
- .Select(url => new Host(url))
- .ToList();
-
- // Select a random host for the first API call attempt
- if (Hosts.Count > 1)
- Interlocked.Exchange(ref m_hostIndex, InitialHostIndex);
- }
-
- #endregion
-
- #region[ Properties ]
-
- ///
- /// The API key identifying the user of the API.
- ///
- public string APIKey { get; }
-
- ///
- /// The API token used to authenticate the user.
- ///
- public string APIToken { get; }
-
- ///
- /// The list of URLs that locate the hosts providing access to the API.
- ///
- public IEnumerable HostsURLs => Hosts
- .Select(host => host.URL);
-
- private List Hosts { get; }
-
- private int InitialHostIndex => Tuple
- .Create(Environment.TickCount, Environment.MachineName)
- .GetHashCode() % Hosts.Count;
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Sends a web request to the host using the credentials for API authentication.
- ///
- /// Action that configures the HTTP request.
- /// Path to the API endpoint locating the resource to be requested.
- /// being impersonated if the APIToken supports impersonation. set to NULL for using APIAuthentication only
- /// Token used to cancel the request before it has completed.
- /// The HTTP response returned by the host that handled the request.
- public Task SendWebRequestAsync(Action configure, string path, IPrincipal user = null, CancellationToken cancellationToken = default) =>
- SendWebRequestAsync(configure, path, HttpCompletionOption.ResponseContentRead, user, cancellationToken);
-
- ///
- /// Sends a web request to the host using the credentials for API authentication.
- ///
- /// Action that configures the HTTP request.
- /// Path to the API endpoint locating the resource to be requested.
- /// When the operation should complete (as soon as a response is available or after reading the whole response content).
- /// being impersonated if the APIToken supports impersonation. set to NULL for using APIAuthentication only
- /// Token used to cancel the request before it has completed.
- /// The HTTP response returned by the host that handled the request.
- public async Task SendWebRequestAsync(Action configure, string path, HttpCompletionOption httpCompletionOption, IPrincipal user = null, CancellationToken cancellationToken = default)
- {
- int initialHostIndex = Interlocked.CompareExchange(ref m_hostIndex, 0, 0);
-
- void UpdateHostIndex(int hostIndex) =>
- Interlocked.CompareExchange(ref m_hostIndex, hostIndex, initialHostIndex);
-
- for (int i = 0; i < Hosts.Count; i++)
- {
- int hostIndex = (initialHostIndex + i) % Hosts.Count;
- Host host = Hosts[hostIndex];
-
- try
- {
- HttpResponseMessage response = await SendWebRequestToAsync(host, configure, path, httpCompletionOption, user, cancellationToken).ConfigureAwait(false);
- UpdateHostIndex(hostIndex);
- return response;
- }
- catch (HostUnreachableException)
- {
- continue;
- }
- catch (Exception ex)
- {
- UpdateHostIndex(hostIndex);
-
- string message = $"Failed when sending API query to host {host.URL}: {ex.Message}";
- throw new APIQueryException(host.URL, message, ex);
- }
- }
-
- return new HttpResponseMessage(HttpStatusCode.NotFound);
- }
-
- private async Task SendWebRequestToAsync(Host host, Action configure, string path, HttpCompletionOption httpCompletionOption,IPrincipal user, CancellationToken cancellationToken)
- {
- using (HttpRequestMessage request = BuildRequest(host, path, configure, user))
- {
- if (request.Method != HttpMethod.Get)
- {
- if (host.AntiForgeryToken == null)
- host.AntiForgeryToken = await GetAntiForgeryTokenAsync(host, cancellationToken).ConfigureAwait(false);
-
- request.Headers.Add("X-GSF-Verify", host.AntiForgeryToken);
- }
-
- return await CallAPIAsync(request, httpCompletionOption, cancellationToken).ConfigureAwait(false);
- }
- }
-
- private async Task GetAntiForgeryTokenAsync(Host host, CancellationToken cancellationToken)
- {
- void ConfigureTokenRequest(HttpRequestMessage tokenRequest)
- {
- MediaTypeWithQualityHeaderValue mediaType = new MediaTypeWithQualityHeaderValue("text/plain");
- tokenRequest.Headers.Accept.Add(mediaType);
- tokenRequest.Method = HttpMethod.Get;
- }
-
- using (HttpRequestMessage tokenRequest = BuildRequest(host, "api/rvht", ConfigureTokenRequest, null))
- using (HttpResponseMessage tokenResponse = await CallAPIAsync(tokenRequest, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false))
- {
- tokenResponse.EnsureSuccessStatusCode();
- return await tokenResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
- }
- }
-
- private async Task CallAPIAsync(HttpRequestMessage request, HttpCompletionOption httpCompletionOption, CancellationToken cancellationToken)
- {
- try
- {
- return await HttpClient.SendAsync(request, httpCompletionOption, cancellationToken).ConfigureAwait(false);
- }
- catch (HttpRequestException ex)
- {
- // If there are no other hosts to try,
- // then we can just throw the exception as-is
- if (Hosts.Count == 1)
- throw;
-
- if (IndicatesHostIsUnreachable(ex))
- throw new HostUnreachableException();
-
- throw;
- }
- }
-
- private HttpRequestMessage BuildRequest(Host host, string path, Action configure, IPrincipal user)
- {
- HttpRequestMessage request = new HttpRequestMessage();
-
- try
- {
- string cleanHostURL = host.URL.Trim().TrimEnd('/');
- string cleanPath = path.Trim().TrimStart('/');
- string fullurl = $"{cleanHostURL}/{cleanPath}";
- request.RequestUri = new Uri(fullurl);
- configure(request);
-
- string type = "XDA-API";
- string decode = $"{APIKey}:{APIToken}";
-
- if (!(user is null))
- {
- type= "XDA-API-IMP";
- decode = $"{decode}:{user.Identity.Name}";
- }
-
- Encoding utf8 = new UTF8Encoding(false);
- byte[] credentialData = utf8.GetBytes(decode);
- string credentials = Convert.ToBase64String(credentialData);
- request.Headers.Authorization = new AuthenticationHeaderValue(type, credentials);
-
- return request;
- }
- catch
- {
- request.Dispose();
- throw;
- }
- }
-
- private bool IndicatesHostIsUnreachable(Exception ex)
- {
- if (ex is SocketException socketException)
- return socketException.SocketErrorCode == SocketError.ConnectionRefused || socketException.SocketErrorCode == SocketError.TimedOut;
- if (ex.InnerException is null)
- return false;
- return IndicatesHostIsUnreachable(ex.InnerException);
- }
-
- #endregion
-
- #region [ Static ]
-
- private static HttpClient HttpClient { get; }
- = new HttpClient();
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.APIAuthentication/IAPICredentialRetriever.cs b/Libraries/openXDA.APIAuthentication/IAPICredentialRetriever.cs
deleted file mode 100644
index 3b4d8b04..00000000
--- a/Libraries/openXDA.APIAuthentication/IAPICredentialRetriever.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-//******************************************************************************************************
-// XDAAPIHelper.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/17/2025 - Gabriel Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Security.Claims;
-
-namespace openXDA.APIAuthentication
-{
- ///
- /// Interface of credential retriever object for .
- ///
- public interface IAPICredentialRetriever
- {
- #region [ Properties ]
-
- ///
- /// API Token used to access OpenXDA
- ///
- string Token { get; }
-
- ///
- /// API Key used to access OpenXDA
- ///
- string Key { get; }
-
- ///
- /// API Key used to access OpenXDA
- ///
- string Host { get; }
-
- ///
- /// Refreshes the settings from the original source.
- ///
- /// A flag indicating if the operation was successful.
- bool TryRefreshSettings();
-
- ///
- /// Retrieves customer key from the claims principle.
- ///
- /// A value of signifies the current user is authorized to view any object the controller may retrieve.
- /// A flag indicating if the operation was successful.
- bool TryRetrieveCustomer(ClaimsPrincipal principal, out string customerKey);
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.APIAuthentication/Properties/AssemblyInfo.cs b/Libraries/openXDA.APIAuthentication/Properties/AssemblyInfo.cs
deleted file mode 100644
index 33057741..00000000
--- a/Libraries/openXDA.APIAuthentication/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("openXDA.APIAuthentication")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("GPA")]
-[assembly: AssemblyProduct("openXDA.APIAuthentication")]
-[assembly: AssemblyCopyright("Copyright © 2022")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("93FF1E73-CD8B-4F01-89BC-A4A242FA06A6")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("3.0.5.93")]
-[assembly: AssemblyVersion("3.0.5.93")]
-[assembly: AssemblyFileVersion("3.0.5.93")]
diff --git a/Libraries/openXDA.APIAuthentication/XDAAPI.cs b/Libraries/openXDA.APIAuthentication/XDAAPI.cs
deleted file mode 100644
index 46315a82..00000000
--- a/Libraries/openXDA.APIAuthentication/XDAAPI.cs
+++ /dev/null
@@ -1,232 +0,0 @@
-//******************************************************************************************************
-// XDAAPI.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/21/2025 - Gabriel Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using Newtonsoft.Json;
-
-namespace openXDA.APIAuthentication
-{
- ///
- /// Helper class that provides openXDA API Calls.
- ///
- public class XDAAPI
- {
- #region [ Properties ]
- ///
- /// Tells users if the helper has been intialized or not.
- ///
- public bool IsIntialized { get; private set; }
-
- ///
- /// API Token used to access OpenXDA
- ///
- public string Token => SettingsRetriever.Token;
-
- ///
- /// API Key used to access OpenXDA
- ///
- public string Key => SettingsRetriever.Key;
-
- ///
- /// API Key used to access OpenXDA
- ///
- public string Host => SettingsRetriever.Host;
-
- ///
- /// Object that retireves the token,key, and host of the helper.
- ///
- private IAPICredentialRetriever SettingsRetriever { get; set; }
-
- #endregion
-
- #region [ Methods ]
- ///
- /// Creates API object and registers retriever.
- ///
- public XDAAPI(IAPICredentialRetriever retriever)
- {
- SettingsRetriever = retriever;
- if (!TryRefreshSettings())
- throw new ArgumentException("Unable to load settings from retriever.");
- }
-
- ///
- /// Recalls the setup settings function from to refetch settings.
- ///
- public bool TryRefreshSettings()
- {
- bool success = SettingsRetriever.TryRefreshSettings();
- if (success)
- IsIntialized = true;
- return success;
- }
-
- ///
- /// Retrieves customer key from the claims principle.
- ///
- /// A value of signifies the current user is authorized to view any object the controller may retrieve.
- /// A flag indicating if the operation was successful.
- public bool TryRetrieveCustomer(ClaimsPrincipal principal, out string customerKey) => SettingsRetriever.TryRetrieveCustomer(principal, out customerKey);
-
- ///
- /// Gets Response Task from XDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public Task GetResponseTask(string requestURI, HttpContent content = null)
- {
- if (!IsIntialized)
- throw new InvalidOperationException("API helper has not been intialized.");
-
- APIQuery query = new APIQuery(Key, Token, Host.Split(';'));
-
- void ConfigureRequest(HttpRequestMessage request)
- {
- if (content == null)
- {
- request.Method = HttpMethod.Get;
- request.Headers.Accept.Clear();
- request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- }
- else
- {
- request.Method = HttpMethod.Post;
- request.Content = content;
- }
- }
-
- return query.SendWebRequestAsync(ConfigureRequest, requestURI);
- }
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a string
- ///
- /// Path to specific API request
- /// string
- public async Task GetAsync(string requestURI)
- {
- if (!IsIntialized)
- throw new InvalidOperationException("API helper has not been intialized.");
-
- APIQuery query = new APIQuery(Key, Token, Host.Split(';'));
-
- void ConfigureRequest(HttpRequestMessage request)
- {
- request.Method = HttpMethod.Get;
- request.Headers.Accept.Clear();
- request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- }
-
- HttpResponseMessage responseMessage = await query.SendWebRequestAsync(ConfigureRequest, requestURI).ConfigureAwait(false);
- responseMessage.EnsureSuccessStatusCode();
- return await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
- }
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a stream
- ///
- /// Path to specific API request
- /// stream
- public async Task GetStreamAsync(string requestURI)
- {
- if (!IsIntialized)
- throw new InvalidOperationException("API helper has not been intialized.");
-
- APIQuery query = new APIQuery(Key, Token, Host.Split(';'));
-
- void ConfigureRequest(HttpRequestMessage request)
- {
- request.Method = HttpMethod.Get;
- request.Headers.Accept.Clear();
- request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- }
-
- HttpResponseMessage responseMessage = await query.SendWebRequestAsync(ConfigureRequest, requestURI).ConfigureAwait(false);
- responseMessage.EnsureSuccessStatusCode();
- return await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
- }
-
- ///
- /// Makes a Get Request to OpenXDA to obtain an object
- ///
- /// Path to specific API request
- /// a object
- public async Task GetAsync(string requestURI)
- {
- if (!IsIntialized)
- throw new InvalidOperationException("API helper has not been intialized.");
-
- string result = await GetAsync(requestURI).ConfigureAwait(false);
- T resultObject = JsonConvert.DeserializeObject(result);
- return resultObject;
- }
-
- ///
- /// Makes Post request on OpenXDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public async Task PostAsync(string requestURI, HttpContent content)
- {
- if (!IsIntialized)
- throw new InvalidOperationException("API helper has not been intialized.");
-
- APIQuery query = new APIQuery(Key, Token, Host.Split(';'));
-
- void ConfigureRequest(HttpRequestMessage request)
- {
- request.Method = HttpMethod.Post;
- request.Content = content;
- }
-
- HttpResponseMessage responseMessage = await query.SendWebRequestAsync(ConfigureRequest, requestURI).ConfigureAwait(false);
- return await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
- }
-
- ///
- /// Makes Post request on OpenXDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public async Task PostAllAsync(string endpoint, HttpContent content) => await PostAsync(endpoint, content).ConfigureAwait(false);
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a objects
- ///
- /// Path to specific API request
- /// a object
- public async Task> GetAllAsync(string requestURI) => await GetAsync>(requestURI).ConfigureAwait(false);
-
- #endregion
-
- }
-}
diff --git a/Libraries/openXDA.APIAuthentication/XDAAPIHelper.cs b/Libraries/openXDA.APIAuthentication/XDAAPIHelper.cs
deleted file mode 100644
index ace01df4..00000000
--- a/Libraries/openXDA.APIAuthentication/XDAAPIHelper.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-//******************************************************************************************************
-// XDAAPIHelper.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 03/15/2024 - Gabriel Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Collections.Generic;
-using System.IO;
-using System.Net.Http;
-using System.Security.Claims;
-using System.Threading.Tasks;
-
-namespace openXDA.APIAuthentication
-{
- ///
- /// Wrapper class that turns into a static for easy use across an application.
- ///
- ///
- /// Must be initialized with the method to fetch settings.
- ///
- public static class XDAAPIHelper
- {
- #region [ Properties ]
- ///
- /// Tells users if the helper has been intialized or not.
- ///
- public static bool IsIntialized {
- get
- {
- return !(API is null);
- }
- }
-
- ///
- /// API Token used to access OpenXDA
- ///
- public static string Token => API.Token;
-
- ///
- /// API Key used to access OpenXDA
- ///
- public static string Key => API.Key;
-
- ///
- /// API Key used to access OpenXDA
- ///
- public static string Host => API.Host;
-
- ///
- /// Object that retireves the token, key, and host of the helper.
- ///
- private static XDAAPI API { get; set; }
-
- #endregion
-
- #region [ Methods ]
- ///
- /// Function for setup of static helper. This must be ran once before using the helper.
- ///
- public static void InitializeHelper(IAPICredentialRetriever retriever)
- {
- API = new XDAAPI(retriever);
- }
-
- ///
- /// Recalls the setup settings function from to refetch settings.
- ///
- public static bool TryRefreshSettings() => API.TryRefreshSettings();
-
- ///
- /// Retrieves customer key from the claims principle.
- ///
- /// A value of signifies the current user is authorized to view any object the controller may retrieve.
- /// A flag indicating if the operation was successful.
- public static bool TryRetrieveCustomer(ClaimsPrincipal principal, out string customerKey) => API.TryRetrieveCustomer(principal, out customerKey);
-
- ///
- /// Gets Response Task from XDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public static Task GetResponseTask(string requestURI, HttpContent content = null) => API.GetResponseTask(requestURI, content);
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a string
- ///
- /// Path to specific API request
- /// string
- public static async Task GetAsync(string requestURI) => await API.GetAsync(requestURI).ConfigureAwait(false);
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a stream
- ///
- /// Path to specific API request
- /// stream
- public static async Task GetStreamAsync(string requestURI) => await API.GetStreamAsync(requestURI).ConfigureAwait(false);
-
- ///
- /// Makes a Get Request to OpenXDA to obtain an object
- ///
- /// Path to specific API request
- /// a object
- public static async Task GetAsync(string requestURI) => await API.GetAsync(requestURI).ConfigureAwait(false);
-
- ///
- /// Makes Post request on OpenXDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public static async Task PostAsync(string requestURI, HttpContent content) => await API.PostAsync(requestURI, content).ConfigureAwait(false);
-
- ///
- /// Makes Post request on OpenXDA
- ///
- /// Path to specific API request
- /// The of the request
- /// response as a
- public static async Task PostAllAsync(string endpoint, HttpContent content) => await API.PostAllAsync(endpoint, content).ConfigureAwait(false);
-
- ///
- /// Makes a Get Request to OpenXDA to obtain a objects
- ///
- /// Path to specific API request
- /// a object
- public static async Task> GetAllAsync(string requestURI) => await API.GetAllAsync(requestURI).ConfigureAwait(false);
-
- #endregion
-
- }
-}
diff --git a/Libraries/openXDA.APIAuthentication/openXDA.APIAuthentication.csproj b/Libraries/openXDA.APIAuthentication/openXDA.APIAuthentication.csproj
deleted file mode 100644
index facf64dd..00000000
--- a/Libraries/openXDA.APIAuthentication/openXDA.APIAuthentication.csproj
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
- net9.0
- Debug;Development;Release
- Library
- false
- openXDA.APIAuthentication
- GPA
- openXDA.APIAuthentication
- Copyright © 2022
-
-
- ..\..\..\Build\Output\Debug\Libraries\
- ..\..\..\Build\Output\Debug\Libraries\openXDA.APIAuthentication.xml
-
-
- ..\..\..\Build\Output\Release\Libraries\
- ..\..\..\Build\Output\Release\Libraries\openXDA.APIAuthentication.xml
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Libraries/openXDA.Configuration/BreakerSection.cs b/Libraries/openXDA.Configuration/BreakerSection.cs
deleted file mode 100644
index d6d07ff3..00000000
--- a/Libraries/openXDA.Configuration/BreakerSection.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-//******************************************************************************************************
-// BreakerSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/02/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class BreakerSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "Breakers";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the flag that determines whether to apply additional logic
- /// to help obtain more accurate breaker timing results in cases where DC
- /// current gradually drains from the line after the breaker is open.
- ///
- [Setting]
- [DefaultValue(false)]
- public bool ApplyDCOffsetLogic { get; set; }
-
- ///
- /// Gets or sets the size of the window, in cycles,
- /// to use when applying the DC offset logic.
- ///
- [Setting]
- [DefaultValue(9.0D / 8.0D)]
- public double DCOffsetWindowSize { get; set; }
-
- ///
- /// Gets or sets the maximum number of cycles that a breaker
- /// operation's timing can exceed the configured breaker speed.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double LateBreakerThreshold { get; set; }
-
- ///
- /// Gets or sets the minimum number of cycles that the breaker is expected
- /// to remain closed after receiving the trip coil energized signal.
- ///
- ///
- /// This value helps to prevent phase timing calculations when the current
- /// signal is not large enough to detect the point at which the breaker opened.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double MinCyclesBeforeOpen { get; set; }
-
- ///
- /// Gets or sets the minimum amount of time, in cycles, the system must wait
- /// before automatically reclosing after a breaker operation has occurred.
- ///
- [Setting]
- [DefaultValue(15.0D)]
- public double MinWaitBeforeReclose { get; set; }
-
- ///
- /// Gets or sets the maximum RMS current, in amps,
- /// at which the breaker can be considered open.
- ///
- [Setting]
- [DefaultValue(20.0D)]
- public double OpenBreakerThreshold { get; set; }
-
- ///
- /// Gets or sets the minimum duration, in cycles, for which the current must remain
- /// at zero in order for a subsequent current spike to be considered a restrike.
- ///
- [Setting]
- [DefaultValue(0.125D)]
- public double MinCyclesBeforeRestrike { get; set; }
-
- ///
- /// Gets or sets the maximum duration, in cycles, for which the current must remain
- /// at zero in order for a subsequent current spike to be considered a restrike.
- ///
- [Setting]
- [DefaultValue(70.0D)]
- public double MaxCyclesBeforeRestrike { get; set; }
-
- ///
- /// Gets or sets the flag that determines whether the system should apply the
- /// BreakerOpen event type to events.
- ///
- [Setting]
- [DefaultValue(true)]
- public bool BreakerOpenEventTypeEnabled { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/COMTRADESection.cs b/Libraries/openXDA.Configuration/COMTRADESection.cs
deleted file mode 100644
index e457f275..00000000
--- a/Libraries/openXDA.Configuration/COMTRADESection.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-//******************************************************************************************************
-// COMTRADESection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 06/07/2019 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Configuration;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class COMTRADESection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "COMTRADE";
-
- #endregion
-
- #region [ Properties ]
-
- public TimeSpan MinWaitTime { get; set; }
-
- [Setting]
- [DefaultValue(false)]
- public bool WaitForINF { get; set; }
-
- [Setting]
- [DefaultValue(false)]
- public bool UseRelaxedValidation { get; set; }
-
- [Setting]
- [DefaultValue("SELECT ID FROM Meter WHERE Make = 'SEL'")]
- public string Root2AdjustmentQuery { get; set; }
-
- [Setting]
- [SettingName(nameof(MinWaitTime))]
- [DefaultValue(15.0D)]
- [EditorBrowsable(EditorBrowsableState.Never)]
- public double _MinWaitTime
- {
- get => MinWaitTime.TotalSeconds;
- set => MinWaitTime = TimeSpan.FromSeconds(value);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/DataAnalysisSection.cs b/Libraries/openXDA.Configuration/DataAnalysisSection.cs
deleted file mode 100644
index d62142e7..00000000
--- a/Libraries/openXDA.Configuration/DataAnalysisSection.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-//******************************************************************************************************
-// DataAnalysisSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 01/16/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class DataAnalysisSection
- {
- public const string CategoryName = "DataAnalysis";
-
- ///
- /// Gets or sets the threshold, in amps, at which the
- /// current exceeds engineering reasonableness.
- ///
- [Setting]
- [DefaultValue(0.1D)]
- public double InterruptionThreshold { get; set; }
-
- ///
- /// Gets or sets the units of measure to use
- /// for lengths (line length and fault distance).
- ///
- [Setting]
- [DefaultValue("miles")]
- public string LengthUnits { get; set; }
-
- ///
- /// Gets or sets the threshold, in amps, at which the
- /// current exceeds engineering reasonableness.
- ///
- [Setting]
- [DefaultValue(1000000.0D)]
- public double MaxCurrent { get; set; }
-
- ///
- /// Gets or sets the maximum duration, in seconds,
- /// of the events processed by openXDA.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double MaxEventDuration { get; set; }
-
- ///
- /// Gets or sets the maximum number of hours beyond the current system time
- /// before the time of the record indicates that the data is unreasonable.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double MaxTimeOffset { get; set; }
-
- ///
- /// Gets or sets the per-unit threshold at which the
- /// voltage exceeds engineering reasonableness.
- ///
- [Setting]
- [DefaultValue(2.0D)]
- public double MaxVoltage { get; set; }
-
- ///
- /// Gets or sets the maximum number of hours prior to the current system time
- /// before the time of the record indicates that the data is unreasonable.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double MinTimeOffset { get; set; }
-
- ///
- /// Gets or sets the threshold, in amps, at which the
- /// current exceeds engineering reasonableness.
- ///
- [Setting]
- [DefaultValue(0.9D)]
- public double SagThreshold { get; set; }
-
- ///
- /// Gets or sets the threshold, in amps, at which the
- /// current exceeds engineering reasonableness.
- ///
- [Setting]
- [DefaultValue(1.1D)]
- public double SwellThreshold { get; set; }
-
- ///
- /// Gets or sets the system frequency.
- ///
- [Setting]
- [DefaultValue(60.0D)]
- public double SystemFrequency { get; set; }
-
- ///
- /// Gets or sets the maximum distance, in seconds,
- /// between a meter's clock and real time.
- ///
- [Setting]
- [DefaultValue(0.5D)]
- public double TimeTolerance { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/DataPusherSection.cs b/Libraries/openXDA.Configuration/DataPusherSection.cs
deleted file mode 100644
index 78cd591d..00000000
--- a/Libraries/openXDA.Configuration/DataPusherSection.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//******************************************************************************************************
-// DataPusherSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 02/08/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class DataPusherSection
- {
- public const string CategoryName = "DataPusher";
-
- [Setting]
- [DefaultValue("systemSettings")]
- public string ConnectionString { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/EMAXSection.cs b/Libraries/openXDA.Configuration/EMAXSection.cs
deleted file mode 100644
index 22ba7df7..00000000
--- a/Libraries/openXDA.Configuration/EMAXSection.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-//******************************************************************************************************
-// EMAXSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 09/25/2017 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class EMAXSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "EMAX";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the value that indicates whether timestamp
- /// correction should be applied when reading native EMAX files.
- ///
- [Setting]
- [DefaultValue(true)]
- public bool ApplyTimestampCorrection { get; set; }
-
- ///
- /// Gets or sets the value that indicates whether value
- /// correction should be applied when reading native EMAX files.
- ///
- [Setting]
- [DefaultValue(true)]
- public bool ApplyValueCorrection { get; set; }
-
- ///
- /// Gets or sets the path to the directory where COMTRADE
- /// exports should be located after reading an EMAX file.
- ///
- [Setting]
- [DefaultValue("")]
- public string COMTRADEExportDirectory { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/EPRICapBankAnalyticSection.cs b/Libraries/openXDA.Configuration/EPRICapBankAnalyticSection.cs
deleted file mode 100644
index 41d0f1d5..00000000
--- a/Libraries/openXDA.Configuration/EPRICapBankAnalyticSection.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-//******************************************************************************************************
-// EPRICapBankAnalyticSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/04/2020 - C. Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class EPRICapBankAnalyticSection
- {
- public const string CategoryName = "EPRICapBankAnalytic";
-
- [Setting]
- [DefaultValue(false)]
- public bool Enabled { get; set; }
-
- [Setting]
- [DefaultValue("./CapBankAnalysis/Data/")]
- public string DataFileLocation { get; set; }
-
- [Setting]
- [DefaultValue("./CapBankAnalysis/Parameter/")]
- public string ParameterFileLocation { get; set; }
-
- [Setting]
- [DefaultValue("./CapBankAnalysis/Results/")]
- public string ResultFileLocation { get; set; }
-
- [Setting]
- [DefaultValue(500.0D)]
- public double VThreshhold { get; set; }
-
- [Setting]
- [DefaultValue(4.0D)]
- public double IThreshhold { get; set; }
-
- [Setting]
- [DefaultValue(10.0D)]
- public double THDLimit { get; set; }
-
- [Setting]
- [DefaultValue(1.0D)]
- public double Toffset { get; set; }
-
- [Setting]
- [DefaultValue(true)]
- public bool EvalPreInsertion { get; set; }
-
- [Setting]
- [DefaultValue("openXDA.CapSwitchAnalysis.dll")]
- public string AnalysisRoutineAssembly { get; set; }
-
- [Setting]
- [DefaultValue("openXDA.CapSwitchAnalysis.Analyzer.RunAnalytic")]
- public string AnalysisRoutineMethod { get; set; }
-
- [Setting]
- [DefaultValue("")]
- public string Analyzer { get; set; }
-
- [Setting]
- [DefaultValue(1200000)]
- public int Delay { get; set; }
-
- [Setting]
- [DefaultValue(false)]
- public bool KeepFiles { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/Edition/EditionChecker.cs b/Libraries/openXDA.Configuration/Edition/EditionChecker.cs
deleted file mode 100644
index 2d4d7d73..00000000
--- a/Libraries/openXDA.Configuration/Edition/EditionChecker.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-//******************************************************************************************************
-// EditionChecker.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/07/2024 - Gabriel Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using Gemstone.Configuration;
-using Gemstone.Data;
-using Gemstone.Data.Model;
-using openXDA.Model;
-
-namespace openXDA.Configuration
-{
- ///
- /// Enum to hold different editions of XDA
- ///
- public enum Edition
- {
- Base = 0,
- Enterprise = 1
- }
-
- ///
- /// Helper class that checks the edition of XDA
- ///
- public static class EditionChecker
- {
- ///
- /// Current XDA Edition
- ///
- private static Edition CheckedEdition { get; set; }
- // ToDo: Think about replacing this with a hash function instead
- private static Guid MagicGuid = new Guid("aa644f0c-a82b-4cf1-ba6e-be3a1b05eb6a");
-
- static EditionChecker()
- {
- UpdateEdition();
- }
-
- ///
- /// Checks to see if current edition is equal to or higher than supplied
- ///
- /// response as a
- public static bool CheckEdition(Edition editionLevel)
- {
- return CheckedEdition.CompareTo(editionLevel) >= 0;
- }
-
- ///
- /// Updates the current edition based on the value in the database
- ///
- public static void UpdateEdition()
- {
- using (AdoDataConnection connection = new AdoDataConnection(Settings.Default))
- {
- Guid value;
- try
- {
- value = new Guid(new TableOperations(connection).QueryRecordWhere($"Name = 'System.EditionKey'")?.Value);
- }
- catch
- {
- value = new Guid("00000000-0000-0000-0000-000000000000");
- }
- if (value == MagicGuid) CheckedEdition = Edition.Enterprise;
- else CheckedEdition = Edition.Base;
- }
- }
-
- ///
- /// Returns the current edition
- ///
- /// response as a
- public static Edition GetEdition()
- {
- return CheckedEdition;
- }
-
- }
-}
diff --git a/Libraries/openXDA.Configuration/Edition/HttpEditionFilterAttribute.cs b/Libraries/openXDA.Configuration/Edition/HttpEditionFilterAttribute.cs
deleted file mode 100644
index 79368e28..00000000
--- a/Libraries/openXDA.Configuration/Edition/HttpEditionFilterAttribute.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-//******************************************************************************************************
-// HttpEditionFilterAttirbute.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/07/2024 - Gabriel Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-
-namespace openXDA.Configuration
-{
- ///
- /// Defines an attribute that will disallow an http method if it does not pass the edition requirement.
- ///
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
- public class HttpEditionFilterAttribute : ActionFilterAttribute
- {
- ///
- /// Gets the edition needed specified by attribute construction.
- ///
- public Edition EditionRequred { get; }
- public HttpEditionFilterAttribute(Edition edition)
- {
- EditionRequred = edition;
- }
-
- ///
- /// Creates a new .
- ///
- /// Edition this http method requires.
- public override void OnActionExecuting(ActionExecutingContext actionContext)
- {
- // Wrong edition: skip the method and return forbidden
- if (!EditionChecker.CheckEdition(EditionRequred))
- actionContext.Result = new ForbidResult();
-
- base.OnActionExecuting(actionContext);
- }
- }
-}
diff --git a/Libraries/openXDA.Configuration/EmailSection.cs b/Libraries/openXDA.Configuration/EmailSection.cs
deleted file mode 100644
index c092607c..00000000
--- a/Libraries/openXDA.Configuration/EmailSection.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-//******************************************************************************************************
-// EmailSection.cs - Gbtc
-//
-// Copyright © 2015, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/02/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.StringExtensions;
-using System.ComponentModel;
-using System.Configuration;
-using System.Security;
-
-namespace openXDA.Configuration
-{
- public class EmailSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "Email";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the address used by the administrator of the email system.
- ///
- [Setting]
- [DefaultValue("xda-admin@gridprotectionalliance.org")]
- public string AdminAddress { get; set; }
-
- ///
- /// Gets or sets the address used in the To line when blind-copying recipients.
- ///
- [Setting]
- [DefaultValue("")]
- public string BlindCopyAddress { get; set; }
-
- ///
- /// Gets or sets the hostname or IP address of the SMTP server to
- /// use for sending automated email notifications when faults occur.
- ///
- [Setting]
- [DefaultValue("")]
- public string SMTPServer { get; set; }
-
- ///
- /// Gets or sets the email address used when sending automated email notifications.
- ///
- [Setting]
- [DefaultValue("openXDA@gridprotectionalliance.org")]
- public string FromAddress { get; set; }
-
- ///
- /// Gets or sets the username used to authenticate to the SMTP server.
- ///
- [Setting]
- [DefaultValue("")]
- public string Username { get; set; }
-
- ///
- /// Gets or sets the password used to authenticate to the SMTP server.
- ///
- [Setting]
- [DefaultValue(null)]
- public string Password
- {
- get => SecurePassword.ToUnsecureString() ?? "";
- set => SecurePassword = value?.ToSecureString() ?? new SecureString();
- }
-
- ///
- /// Gets or sets the flag that determines whether to enable
- /// SSL when establishing communications with the SMTP server.
- ///
- [Setting]
- [DefaultValue(false)]
- public bool EnableSSL { get; set; }
-
- ///
- /// Sets the minimum number of samples in an email chart
- ///
- [Setting]
- [DefaultValue(-1)]
- public int MinimumChartSamplesPerCycle { get; set; }
-
- ///
- /// Gets the password as a .
- ///
- public SecureString SecurePassword { get; private set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/EventEmailSection.cs b/Libraries/openXDA.Configuration/EventEmailSection.cs
deleted file mode 100644
index 64f48794..00000000
--- a/Libraries/openXDA.Configuration/EventEmailSection.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//******************************************************************************************************
-// EventEmailSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 02/13/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-using Gemstone.Configuration;
-
-namespace openXDA.Configuration
-{
- public class EventEmailSection
- {
- public const string CategoryName = "EventEmail";
-
- [Setting]
- [DefaultValue(false)]
- public bool Enabled { get; set; }
-
- [Setting]
- [DefaultValue(0)]
- public int MaxEmailCount { get; set; }
-
- [Setting]
- [SettingName(nameof(MaxEmailSpan))]
- [DefaultValue(0.0D)]
- public double MaxEmailSeconds
- {
- get => MaxEmailSpan.TotalSeconds;
- set => MaxEmailSpan = TimeSpan.FromSeconds(value);
- }
-
- [Setting]
- [DefaultValue("http://localhost:8989/RestoreEventEmail.cshtml")]
- public string RestorationURL { get; set; }
-
- public TimeSpan MaxEmailSpan { get; set; }
-
- [Setting]
- [SettingName(nameof(EmailDuplicateThresholdMinutes))]
- [DefaultValue(0.0D)]
- public double EmailDuplicateThresholdMinutes
- {
- get => EmailDuplicateThreshold.TotalMinutes;
- set => EmailDuplicateThreshold = TimeSpan.FromMinutes(value);
- }
-
- public TimeSpan EmailDuplicateThreshold { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/FaultLocationSection.cs b/Libraries/openXDA.Configuration/FaultLocationSection.cs
deleted file mode 100644
index a9e6e72c..00000000
--- a/Libraries/openXDA.Configuration/FaultLocationSection.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-//******************************************************************************************************
-// FaultLocationSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/02/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public enum FaultCalculationCycleMethod
- {
- MaxCurrent,
- LastFaultedCycle,
- LastFaultedCycleExceptAirGapRes
- }
-
- public class FaultLocationSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "FaultLocation";
-
- #endregion
-
- #region [ Properties ]
-
- [Setting]
- [DefaultValue(5.0D)]
- public double PrefaultTrigger { get; set; }
-
- [Setting]
- [DefaultValue(50.0D)]
- public double PrefaultTriggerAdjustment { get; set; }
-
- [Setting]
- [DefaultValue(1.05D)]
- public double MaxFaultDistanceMultiplier { get; set; }
-
- [Setting]
- [DefaultValue(-0.05D)]
- public double MinFaultDistanceMultiplier { get; set; }
-
- [Setting]
- [DefaultValue(FaultCalculationCycleMethod.MaxCurrent)]
- public FaultCalculationCycleMethod FaultCalculationCycleMethod { get; set; }
-
- [Setting]
- [DefaultValue(1.0D)]
- public double MinFaultSegmentCycles { get; set; }
-
- [Setting]
- [DefaultValue(10)]
- public int FaultClearingAdjustmentSamples { get; set; }
-
- [Setting]
- [DefaultValue(false)]
- public bool WarnMissingDetectionLogic { get; set; }
-
- ///
- /// Indicates whether to use the default fault detection logic
- /// when the line-specific fault detection logic fails.
- ///
- [Setting]
- [DefaultValue(true)]
- public bool UseDefaultFaultDetectionLogic { get; set; }
-
- ///
- /// Indicates whether to ignore line-specific fault detection logic.
- ///
- [Setting]
- [DefaultValue(false)]
- public bool IgnoreFaultDetectionLogic { get; set; }
-
- [Setting]
- [DefaultValue(0.8D)]
- public double FaultedVoltageThreshold { get; set; }
-
- [Setting]
- [DefaultValue(0.001D)]
- public double GroundedFaultVoltageThreshold { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/FileEnumeratorSection.cs b/Libraries/openXDA.Configuration/FileEnumeratorSection.cs
deleted file mode 100644
index 0c403c30..00000000
--- a/Libraries/openXDA.Configuration/FileEnumeratorSection.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-//******************************************************************************************************
-// FileEnumeratorSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 01/16/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-using Gemstone.IO;
-
-namespace openXDA.Configuration
-{
- //copied from GSF.IO as there was no equivalent in Gemstone.IO
- public enum FileEnumerationStrategy
- {
- //
- // Summary:
- // Enumerate all files sequentially.
- Sequential,
- //
- // Summary:
- // Enumerates the watch directories in parallel, but subdirectories are processed
- // sequentially.
- ParallelWatchDirectories,
- //
- // Summary:
- // Enumerates every directory, including subdirectories, in parallel.
- ParallelSubdirectories,
- //
- // Summary:
- // Does not enumerate directories, relying only on the file watcher to handle file
- // processing events.
- None
- }
-
- public class FileEnumeratorSection
- {
- public const string CategoryName = "FileEnumerator";
-
- ///
- /// Gets or sets the patterns used to determine which
- /// folders to skip when enumerating watch directories.
- ///
- [Setting]
- [DefaultValue("")]
- public string FolderExclusion { get; set; }
-
- ///
- /// Gets or sets the flag that determines whether the file watcher
- /// should raise events for enumerated files in alphabetical order.
- ///
- [Setting]
- [DefaultValue(false)]
- public bool OrderedEnumeration { get; set; }
-
- ///
- /// Gets or sets the strategy used for enumeration of files in the file watcher.
- ///
- [Setting]
- [DefaultValue(FileEnumerationStrategy.ParallelSubdirectories)]
- public FileEnumerationStrategy Strategy { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/FileProcessorSection.cs b/Libraries/openXDA.Configuration/FileProcessorSection.cs
deleted file mode 100644
index 2d89b5aa..00000000
--- a/Libraries/openXDA.Configuration/FileProcessorSection.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-//******************************************************************************************************
-// FileProcessorSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 01/16/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class FileProcessorSection
- {
- public const string CategoryName = "FileProcessor";
-
- ///
- /// Gets or sets the pattern used to parse file paths in
- /// order to identify the meter that the file came from.
- ///
- [Setting]
- [DefaultValue(/*lang=regex*/ @"(?[^\\]+)\\[^\\]+$")]
- public string FilePattern { get; set; }
-
- ///
- /// Gets or sets the pattern that identifies the part of the file path that
- ///
- [Setting]
- [DefaultValue(/*lang=regex*/ @"^(?.*)\.[^\.]*$")]
- public string FileGroupingPattern { get; set; }
-
- ///
- /// Gets or sets the maximum number of hours prior to the current system time
- /// before the file creation time indicates that the data should not be processed.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double MaxFileCreationTimeOffset { get; set; }
-
- ///
- /// Gets or sets the maximum file size, in MB,
- /// of the files processed by openXDA.
- ///
- [Setting]
- [DefaultValue(30.0D)]
- public double MaxFileSize { get; set; }
-
- ///
- /// Gets or sets the number of threads used
- /// for processing file data concurrently.
- ///
- ///
- /// Values less than or equal to zero will be set to the number of logical processors.
- ///
- [Setting]
- [DefaultValue(0)]
- public int ProcessingThreadCount
- {
- get
- {
- return _ProcessingThreadCount;
- }
- set
- {
- _ProcessingThreadCount = value;
-
- if (_ProcessingThreadCount <= 0)
- _ProcessingThreadCount = Environment.ProcessorCount;
- }
- }
-
- private int _ProcessingThreadCount { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/FilePrunerSection.cs b/Libraries/openXDA.Configuration/FilePrunerSection.cs
deleted file mode 100644
index 2c9a4c2b..00000000
--- a/Libraries/openXDA.Configuration/FilePrunerSection.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-//******************************************************************************************************
-// FilePrunerSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 02/08/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Configuration;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class FilePrunerSection
- {
- public const string CategoryName = "FilePruner";
-
- [Setting]
- [DefaultValue("* 0 * * *")]
- public string Schedule { get; set; }
-
- ///
- /// Gets or sets the amount of time, in days,
- /// the file pruner should keep files in openXDA's
- /// watch directories.
- ///
- [Setting]
- [SettingName(nameof(RetentionPeriod))]
- [DefaultValue(0)]
- public int RetentionPeriodDays
- {
- get => (int)RetentionPeriod.TotalDays;
- set => RetentionPeriod = TimeSpan.FromDays(value);
- }
-
- ///
- /// Gets or sets the amount of time the file pruner
- /// should keep files in openXDA's watch directories.
- ///
- public TimeSpan RetentionPeriod { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/FileWatcherSection.cs b/Libraries/openXDA.Configuration/FileWatcherSection.cs
deleted file mode 100644
index 4b25e6c1..00000000
--- a/Libraries/openXDA.Configuration/FileWatcherSection.cs
+++ /dev/null
@@ -1,308 +0,0 @@
-//******************************************************************************************************
-// FileWatcherSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 01/16/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Configuration;
-using Gemstone.IO;
-using Gemstone.StringExtensions;
-using System.ComponentModel;
-using System.Configuration;
-using System.Security;
-using FileShare = openXDA.Configuration.FileWatcher.FileShare;
-
-namespace openXDA.Configuration
-{
- namespace FileWatcher
- {
- ///
- /// Represents a file share.
- ///
- public class FileShare
- {
- #region [ Members ]
-
- // Fields
- private string m_name;
- private string m_domain;
- private string m_username;
- private SecureString m_password;
-
- private Exception m_authenticationException;
-
- #endregion
-
- #region [ Constructors ]
-
- ///
- /// Creates a new instance of the class.
- ///
- public FileShare()
- {
- }
-
- ///
- /// Creates a new instance of the class.
- ///
- /// A string containing the file share parameters as key-value pairs.
- public FileShare(string connectionString)
- {
- ConnectionStringParser parser = new ConnectionStringParser();
- parser.ParseConnectionString(connectionString, this);
- }
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the name of the file share (\\server\share).
- ///
- [Setting]
- [DefaultValue("")]
- public string Name
- {
- get
- {
- return m_name;
- }
- set
- {
- m_name = value;
- }
- }
-
- ///
- /// Gets or sets the domain of the user used to authenticate to the file share.
- ///
- [Setting]
- [DefaultValue("")]
- public string Domain
- {
- get
- {
- return m_domain;
- }
- set
- {
- m_domain = value;
- }
- }
-
- ///
- /// Gets or sets the username of the user used to authenticate to the file share.
- ///
- [Setting]
- [DefaultValue("")]
- public string Username
- {
- get
- {
- return m_username;
- }
- set
- {
- string[] splitValue;
-
- m_username = value;
-
- if ((object)value != null)
- {
- splitValue = value.Split('\\');
-
- if (splitValue.Length == 2)
- {
- m_domain = splitValue[0];
- m_username = splitValue[1];
- }
- }
- }
- }
-
- ///
- /// Gets or sets the password of the user used to authenticate to the file share.
- ///
- [Setting]
- [DefaultValue("")]
- public string Password
- {
- get
- {
- return m_password.ToUnsecureString() ?? "";
- }
- set
- {
- m_password = value.ToSecureString() ?? new SecureString();
- }
- }
-
- ///
- /// Gets the exception encountered during the most recent authentication attempt.
- ///
- public Exception AuthenticationException
- {
- get
- {
- return m_authenticationException;
- }
- }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Attempts to authenticate to the file share.
- ///
- public void Authenticate()
- {
- try
- {
- FilePath.ConnectToNetworkShare(m_name, m_username, Password, m_domain);
- m_authenticationException = null;
- }
- catch (Exception ex)
- {
- m_authenticationException = ex;
- throw;
- }
- }
-
- ///
- /// Attempts to authenticate to the file share.
- ///
- /// True if successfully authenticated. False otherwise.
- public bool TryAuthenticate()
- {
- try
- {
- Authenticate();
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- #endregion
- }
- }
-
- public class FileWatcherSection
- {
- public const string CategoryName = "FileWatcher";
-
- ///
- /// Gets or sets the size of the
- /// s' internal buffers.
- ///
- ///
- [Setting]
- [DefaultValue(65536)]
- public int BufferSize { get; set; }
-
- ///
- /// Gets or sets a list of parameters used
- /// to authenticate to multiple file shares.
- ///
- [Setting]
- [DefaultValue("")]
- public string FileShares
- {
- get
- {
- return _FileShares;
- }
- set
- {
- _FileShares = value;
-
- _FileShareList = value.ToNonNullString().ParseKeyValuePairs()
- .Select(kvp => kvp.Value)
- .Select(fileShareString => new FileShare(fileShareString))
- .ToList();
- }
- }
-
- ///
- /// Gets a list of file shares to be authenticated at startup.
- ///
- public IReadOnlyCollection FileShareList => _FileShareList.AsReadOnly();
-
- private string _FileShares { get; set; }
- private List _FileShareList { get; set; }
-
- ///
- /// Gets or sets the number of threads used
- /// internally to the file processor.
- ///
- ///
- /// Values less than or equal to zero will be set to the number of logical processors.
- ///
- [Setting]
- [DefaultValue(0)]
- public int InternalThreadCount
- {
- get => _InternalThreadCount;
- set => _InternalThreadCount = (value > 0)
- ? value
- : Environment.ProcessorCount;
- }
-
- private int _InternalThreadCount { get; set; }
-
- ///
- /// Gets or sets the list of directories to watch for files.
- ///
- [Setting]
- [DefaultValue("Watch")]
- public string WatchDirectories
-
- {
- get
- {
- return _WatchDirectories;
- }
- set
- {
- _WatchDirectories = value;
-
- if ((object)value != null)
- {
- _WatchDirectoryList = value
- .Split(Path.PathSeparator)
- .Select(path => path.Trim())
- .ToList();
- }
- }
- }
-
- ///
- /// Gets a list of directories to be watched
- /// for files containing fault records.
- ///
- public IReadOnlyCollection WatchDirectoryList => _WatchDirectoryList.AsReadOnly();
-
- private string _WatchDirectories { get; set; }
- private List _WatchDirectoryList { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/GrafanaSection.cs b/Libraries/openXDA.Configuration/GrafanaSection.cs
deleted file mode 100644
index a6d0bc31..00000000
--- a/Libraries/openXDA.Configuration/GrafanaSection.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-//******************************************************************************************************
-// GrafanaSection.cs - Gbtc
-//
-// Copyright © 2023, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/18/2023 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class GrafanaSection
- {
- public const string CategoryName = "Grafana";
-
- ///
- /// Gets or sets the base path to the Grafana server executable.
- ///
- [Setting]
- [DefaultValue(@"Grafana\bin\grafana-server.exe")]
- public string ServerPath { get; set; }
-
- ///
- /// Gets or sets the base path to the
- /// folder containing the Grafana process.
- ///
- [Setting]
- [DefaultValue("Grafana")]
- public string BasePath { get; set; }
-
- [Setting]
- [DefaultValue("http://localhost:8185")]
- public string HostedURL { get; set; }
-
- [Setting]
- [DefaultValue("admin")]
- public string AdminUser { get; set; }
-
- [Setting]
- [DefaultValue(1)]
- public int OrganizationID { get; set; }
-
- [Setting]
- [DefaultValue("X-WEBAUTH-USER")]
- public string AuthProxyHeaderName { get; set; }
-
- [Setting]
- [DefaultValue("x-last-dashboard")]
- public string LastDashboardCookieName { get; set; }
-
- [Setting]
- [DefaultValue(30)]
- public int InitializationTimeout { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/LSCVSSection.cs b/Libraries/openXDA.Configuration/LSCVSSection.cs
deleted file mode 100644
index 3cd00c05..00000000
--- a/Libraries/openXDA.Configuration/LSCVSSection.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//******************************************************************************************************
-// LSCVSSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 04/11/2022 - G. Santos
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class LSCVSSection
- {
- public const string CategoryName = "LSCVS";
-
- ///
- /// URL string of the LSCVS report server name.
- ///
- [Setting]
- [DefaultValue("http://localhost/LSCVSReport")]
- public string URL { get; set; }
-
- ///
- /// The API Key to use to authenticate to LSCVS
- ///
- [Setting]
- [DefaultValue("")]
- public string APIKey { get; set; }
-
- ///
- /// The API Token to use to authenticate to LSCVS
- ///
- [Setting]
- [DefaultValue("")]
- public string APIToken { get; set; }
-
- ///
- /// MW ratio threshold to report LSCVS event.
- ///
- [Setting]
- [DefaultValue(0.6D)]
- public double ReportingThreshold { get; set; }
-
- ///
- /// Ratio threshold for determining type III sag faults over type II or I.
- ///
- [Setting]
- [DefaultValue(0.95D)]
- public double TypeThreshold { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/OSIPISection.cs b/Libraries/openXDA.Configuration/OSIPISection.cs
deleted file mode 100644
index b5d84055..00000000
--- a/Libraries/openXDA.Configuration/OSIPISection.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-//******************************************************************************************************
-// OSIPISection.cs - Gbtc
-//
-// Copyright © 2025, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 03/21/2025 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class OSIPISection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "OSIPI";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets name of the PI historian server to connect to.
- ///
- [Setting]
- [DefaultValue("")]
- public string ServerName { get; set; }
-
- ///
- /// Gets or sets user name for logging into PI historian server.
- ///
- [Setting]
- [DefaultValue("")]
- public string UserName { get; set; }
-
- ///
- /// Gets or sets password for logging into PI historian server.
- ///
- [Setting]
- [DefaultValue("")]
- public string Password { get; set; }
-
- ///
- /// Gets or sets time to wait when establishing
- /// connection to PI server before failing.
- ///
- [Setting]
- [DefaultValue(30000)]
- public int ConnectTimeout { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/PQDIFSection.cs b/Libraries/openXDA.Configuration/PQDIFSection.cs
deleted file mode 100644
index 670a5fd0..00000000
--- a/Libraries/openXDA.Configuration/PQDIFSection.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//******************************************************************************************************
-// PQDIFSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/08/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class PQDIFSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "PQDIF";
-
- #endregion
-
- #region [ Properties ]
-
- [Setting]
- [DefaultValue(false)]
- public bool AllowMultipleDataSource { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/PQISection.cs b/Libraries/openXDA.Configuration/PQISection.cs
deleted file mode 100644
index bbdeb1f1..00000000
--- a/Libraries/openXDA.Configuration/PQISection.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-//******************************************************************************************************
-// PQISection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 07/29/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class PQISection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "PQI";
-
- #endregion
-
- #region [ Properties ]
-
- [Setting]
- [DefaultValue("https://pqiws.epri.com")]
- public string BaseURL { get; set; }
-
- [Setting]
- [DefaultValue("https://go.epri.com")]
- public string PingURL { get; set; }
-
- [Setting]
- [DefaultValue(null)]
- public string ClientID { get; set; }
-
- [Setting]
- [DefaultValue(null)]
- public string ClientSecret { get; set; }
-
- [Setting]
- [DefaultValue(null)]
- public string Username { get; set; }
-
- [Setting]
- [DefaultValue(null)]
- public string Password { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/Properties/AssemblyInfo.cs b/Libraries/openXDA.Configuration/Properties/AssemblyInfo.cs
deleted file mode 100644
index 0666cda4..00000000
--- a/Libraries/openXDA.Configuration/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("openXDA.Configuration")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("openXDA.Configuration")]
-[assembly: AssemblyCopyright("Copyright © 2021")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("83d8122c-2bcc-4813-b449-224d9f7e5aee")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("3.0.5.93")]
-[assembly: AssemblyVersion("3.0.5.93")]
-[assembly: AssemblyFileVersion("3.0.5.93")]
diff --git a/Libraries/openXDA.Configuration/RabbitMQSection.cs b/Libraries/openXDA.Configuration/RabbitMQSection.cs
deleted file mode 100644
index 12e6900a..00000000
--- a/Libraries/openXDA.Configuration/RabbitMQSection.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-//******************************************************************************************************
-// RabbitMQSection.cs - Gbtc
-//
-// Copyright © 2025, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 11/01/2025 - C. Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class RabbitMQSection
- {
- public const string CategoryName = "RabbitMQ";
-
- ///
- /// The RabbbitMQ Server Hostname or IP Address.
- ///
- [Setting]
- [DefaultValue("localhost")]
- public string Hostname { get; set; } = "localhost";
-
- ///
- /// Defines the port RabbitMQ is listening on.
- ///
- [Setting]
- [DefaultValue(5672)]
- public int Port { get; set; } = 5672;
-
- ///
- /// Defines the name of the exchange to listen to.
- ///
- [Setting]
- [DefaultValue("openxda")]
- public string ExchangeName { get; set; } = "openxda";
-
- ///
- /// Defines the routing key used to listen for messages.
- ///
- [Setting]
- [DefaultValue("openxda")]
- public string RoutingKey { get; set; } = "openxda";
-
- ///
- /// Defines a flag that determines if RabbitMQ integration is enabled.
- ///
- [Setting]
- [DefaultValue(false)]
- public bool Enabled { get; set; } = false;
-
-
- ///
- /// Defines the routing key used for outbound messages.
- ///
- [Setting]
- [DefaultValue("analytic")]
- public string OutboundRoutingKey { get; set; } = "analytic";
-
- ///
- /// Defines the username used for authenticating to the RabbitMQ service.
- ///
- [Setting]
- [DefaultValue("guest")]
- public string UserName { get; set; } = "guest";
-
- ///
- /// Defines the password used for authenticating to the RabbitMQ service.
- ///
- [Setting]
- [DefaultValue("guest")]
- public string Password { get; set; } = "guest";
- }
-}
diff --git a/Libraries/openXDA.Configuration/SCADASection.cs b/Libraries/openXDA.Configuration/SCADASection.cs
deleted file mode 100644
index acb47c91..00000000
--- a/Libraries/openXDA.Configuration/SCADASection.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-//******************************************************************************************************
-// SCADASection.cs - Gbtc
-//
-// Copyright © 2025, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 03/21/2025 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class SCADASection
- {
- #region [ Members ]
-
- // Nested Types
- public enum SCADAHistorian
- {
- None,
- eDNA,
- OSIPI
- }
-
- // Constants
- public const string CategoryName = "SCADA";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets historian used by the SCADA system.
- ///
- [Setting]
- [DefaultValue(SCADAHistorian.None)]
- public SCADAHistorian Historian { get; set; }
-
- ///
- /// Gets or sets the database query to get the list of
- /// SCADA points that indicate breaker state for the line.
- ///
- [Setting]
- [DefaultValue("SELECT NULL AS Point WHERE 1 IS NULL")]
- public string PointQuery { get; set; }
-
- ///
- /// Gets or sets the tolerance, in seconds, that determines the
- /// time range to be queried around the fault clearing point.
- ///
- [Setting]
- [DefaultValue(4.0D)]
- public double QueryTolerance { get; set; }
-
- ///
- /// Gets or sets the value of the point representing
- /// breaker state when the breaker is open.
- ///
- [Setting]
- [DefaultValue(0.0D)]
- public double BreakerOpenValue { get; set; }
-
- ///
- /// Gets the tolerance that determines the time range
- /// to be queried around the fault clearing point.
- ///
- public TimeSpan QueryToleranceSpan
- {
- get
- {
- return TimeSpan.FromSeconds(QueryTolerance);
- }
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/SSAMSSection.cs b/Libraries/openXDA.Configuration/SSAMSSection.cs
deleted file mode 100644
index dff73793..00000000
--- a/Libraries/openXDA.Configuration/SSAMSSection.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//******************************************************************************************************
-// SSAMSSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 02/08/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class SSAMSSection
- {
- public const string CategoryName = "SSAMS";
-
- private const string DefaultDataProviderString =
- "AssemblyName={System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}; " +
- "ConnectionType=System.Data.SqlClient.SqlConnection; " +
- "AdapterType=System.Data.SqlClient.SqlDataAdapter;";
-
- ///
- /// Cron string frequency at which the SSAMS process is scheduled.
- ///
- [Setting]
- [DefaultValue("* 0 * * *")]
- public string Schedule { get; set; }
-
- ///
- /// Defines the connection string of the SSAMS DB.
- ///
- [Setting]
- [DefaultValue("Data Source=localhost; Initial Catalog=openXDA; Integrated Security=SSPI")]
- public string ConnectionString { get; set; }
-
- ///
- /// Defines the connection string of the SSAMS DB.
- ///
- [Setting]
- [DefaultValue(DefaultDataProviderString)]
- public string DataProviderString { get; set; }
-
- ///
- /// Command or procedure name that defines the command executed by the external DB.
- ///
- [Setting]
- [DefaultValue("sp_LogSsamEvent")]
- public string DatabaseCommand { get; set; }
-
- ///
- /// Parameters for the external DB procedure.
- ///
- [Setting]
- [DefaultValue("1,1,'OpenXDA_HEARTBEAT','','OpenXDA adapter heartbeat at {Timestamp} UTC',''")]
- public string CommandParameters { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/Subscription.cs b/Libraries/openXDA.Configuration/Subscription.cs
deleted file mode 100644
index eac8f878..00000000
--- a/Libraries/openXDA.Configuration/Subscription.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-//******************************************************************************************************
-// SubscriptionSection.cs - Gbtc
-//
-// Copyright © 2015, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/02/2015 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class SubscriptionSection
- {
- #region [ Members ]
-
- // Constants
- public const string CategoryName = "Subscription";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets or sets the Subject Line used when sending the confirmation email
- ///
- [Setting]
- [DefaultValue("OpenXDA Confirm Email")]
- public string ConfirmSubject { get; set; }
-
- ///
- /// Gets or sets the Template used when generating the Confirmation Email
- ///
- [Setting]
- [DefaultValue("Please click the following Link to confirm your email address \n http://localhost/SystemCenterNotification/ConfirmEmail")]
- public string ConfirmTemplate { get; set; }
-
-
- ///
- /// Gets or sets the flag that determines whether a confirmed Email is Required
- /// when subscribing to a notification
- ///
- [Setting]
- [DefaultValue(true)]
- public bool RequireConfirmation { get; set; }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/SystemSection.cs b/Libraries/openXDA.Configuration/SystemSection.cs
deleted file mode 100644
index 4649edf6..00000000
--- a/Libraries/openXDA.Configuration/SystemSection.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-//******************************************************************************************************
-// SystemSection.cs - Gbtc
-//
-// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.opensource.org/licenses/eclipse-1.0.php
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 09/30/2014 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- ///
- /// Represents the system settings for openXDA.
- ///
- public class SystemSection
- {
- public const string CategoryName = "System";
-
- ///
- /// Gets or sets the time zone identifier for the time zone
- /// used by meters in the system unless configured otherwise.
- ///
- [Setting]
- [DefaultValue("UTC")]
- public string DefaultMeterTimeZone
- {
- get => DefaultMeterTimeZoneInfo.Id;
- set => DefaultMeterTimeZoneInfo = string.IsNullOrEmpty(value)
- ? TimeZoneInfo.Local
- : TimeZoneInfo.FindSystemTimeZoneById(value);
- }
-
- ///
- /// Gets the used by meters
- /// in the system unless configured otherwise.
- ///
- public TimeZoneInfo DefaultMeterTimeZoneInfo { get; private set; }
-
- ///
- /// Gets or sets the amount of time each database
- /// query is given to complete, in seconds.
- ///
- [Setting]
- [DefaultValue(120)]
- public int DbTimeout { get; set; }
-
- ///
- /// Gets or sets the time zone identifier for the
- /// time zone used by openXDA to store data.
- ///
- ///
- /// The default value for this setting (empty string)
- /// causes the setting to assume the value of the local
- /// time zone of the system openXDA is running on.
- ///
- [Setting]
- [DefaultValue("UTC")]
- public string XDATimeZone
- {
- get
- {
- return _XDATimeZone;
- }
- set
- {
- if (string.IsNullOrEmpty(value))
- _XDATimeZone = TimeZoneInfo.Local.Id;
- else
- _XDATimeZone = value;
- }
- }
-
- ///
- /// Gets the for the
- /// time zone used by openXDA to store data.
- ///
- public TimeZoneInfo XDATimeZoneInfo
- {
- get
- {
- if ((object)_XDATimeZoneInfo == null)
- _XDATimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(_XDATimeZone);
-
- return _XDATimeZoneInfo;
- }
- }
-
- private string _XDATimeZone { get; set; }
- private TimeZoneInfo _XDATimeZoneInfo { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/TaskProcessorSection.cs b/Libraries/openXDA.Configuration/TaskProcessorSection.cs
deleted file mode 100644
index e42b01fc..00000000
--- a/Libraries/openXDA.Configuration/TaskProcessorSection.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//******************************************************************************************************
-// TaskProcessorSection.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 02/24/2021 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class TaskProcessorSection
- {
- public const string CategoryName = "TaskProcessor";
-
- ///
- /// Gets or sets the query used to filter
- /// meters when polling for analysis tasks.
- ///
- [Setting]
- [DefaultValue("SELECT ID FROM Meter")]
- public string MeterFilterQuery { get; set; }
-
- ///
- /// Gets or sets the number of threads used
- /// for processing meter data concurrently.
- ///
- ///
- /// Values less than or equal to zero will be set to the number of logical processors.
- ///
- [Setting]
- [DefaultValue(0)]
- public int ProcessingThreadCount
- {
- get
- {
- return _ProcessingThreadCount;
- }
- set
- {
- _ProcessingThreadCount = value;
-
- if (_ProcessingThreadCount <= 0)
- _ProcessingThreadCount = Environment.ProcessorCount;
- }
- }
-
- private int _ProcessingThreadCount { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Configuration/TrendingDataSection.cs b/Libraries/openXDA.Configuration/TrendingDataSection.cs
deleted file mode 100644
index 389daad4..00000000
--- a/Libraries/openXDA.Configuration/TrendingDataSection.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-//******************************************************************************************************
-// TrendingDataSection.cs - Gbtc
-//
-// Copyright © 2022, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/26/2022 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel;
-using System.Configuration;
-
-namespace openXDA.Configuration
-{
- public class TrendingDataSection
- {
- #region [ Members ]
-
- // Nested Types
- public class RMSSubSection
- {
- [Setting]
- [DefaultValue(@"Trms.dat")]
- public string FolderPath { get; set; }
- [Setting]
- [DefaultValue(null)]
- public string DescriptionRegexMatchFilter { get; set; }
- }
-
- public class FlickerSubSection
- {
- [Setting]
- [DefaultValue(@"FkrR[0-9]*\.dat")]
- public string FolderPath { get; set; }
- [Setting]
- [DefaultValue(null)]
- public string DescriptionRegexMatchFilter { get; set; }
- }
-
- public class TriggerSubSection
- {
- [Setting]
- [DefaultValue(@"TrR[0-9]*\.dat")]
- public string FolderPath { get; set; }
- [Setting]
- [DefaultValue(@"\s-\sV\S*\sRMS\s*$")]
- public string DescriptionTriggerRMSMatch { get; set; }
- [Setting]
- [DefaultValue(@"\s-\sV\S*\sImpulse\s*$")]
- public string DescriptionTriggerImpulseMatch { get; set; }
- [Setting]
- [DefaultValue(@"\s-\s\S+\sTHD\s*$")]
- public string DescriptionTriggerTHDMatch { get; set; }
- [Setting]
- [DefaultValue(@"\s-\sUnbalance\s*$")]
- public string DescriptionTriggerUnbalanceMatch { get; set; }
- [Setting]
- [DefaultValue(@"\s-\s\S*I\S*\s*$")]
- public string DescriptionTriggerCurrentMatch { get; set; }
- [Setting]
- [DefaultValue(null)]
- public string DescriptionRegexMatchFilter { get; set; }
- }
-
- public class FrequencySubSection
- {
- [Setting]
- [DefaultValue(@"Tfrq[0-9]*\.dat")]
- public string FolderPath { get; set; }
- [Setting]
- [DefaultValue(null)]
- public string DescriptionRegexMatchFilter { get; set; }
- }
-
- // Constants
- public const string CategoryName = "TrendingData";
-
- #endregion
-
- #region [ Properties ]
-
- ///
- /// Gets RMS folder path settings.
- ///
- [Category]
- public RMSSubSection RMS { get; } = new RMSSubSection();
-
- ///
- /// Gets flicker folder path settings.
- ///
- [Category]
- public FlickerSubSection Flicker { get; } = new FlickerSubSection();
-
- ///
- /// Gets trigger folder path settings.
- ///
- [Category]
- public TriggerSubSection Trigger { get; } = new TriggerSubSection();
-
- ///
- /// Gets frequency folder path settings.
- ///
- [Category]
- public FrequencySubSection Frequency { get; } = new FrequencySubSection();
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Configuration/openXDA.Configuration.csproj b/Libraries/openXDA.Configuration/openXDA.Configuration.csproj
deleted file mode 100644
index 3d799a9b..00000000
--- a/Libraries/openXDA.Configuration/openXDA.Configuration.csproj
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
- Debug
- AnyCPU
- net9.0
- Debug;Development;Release
- Library
- openXDA.Configuration
- openXDA.Configuration
- false
- enable
- enable
- true
-
-
-
- true
- full
- false
- ..\..\..\Build\Output\Debug\Libraries\
- DEBUG;TRACE
- 4
-
-
-
- pdbonly
- true
- ..\..\..\Build\Output\Release\Libraries\
- TRACE
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Channels/Channel.cs b/Libraries/openXDA.Model/Channels/Channel.cs
deleted file mode 100644
index 9d65c5bc..00000000
--- a/Libraries/openXDA.Model/Channels/Channel.cs
+++ /dev/null
@@ -1,629 +0,0 @@
-//******************************************************************************************************
-// Channel.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data;
-using Gemstone.Data.Model;
-using Newtonsoft.Json;
-
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
-using System.Data;
-using System.Transactions;
-using IsolationLevel = System.Transactions.IsolationLevel;
-
-namespace openXDA.Model
-{
- public class ChannelKey : IEquatable
- {
- #region [ Constructors ]
-
- public ChannelKey(int assetID, int harmonicGroup, string name, string measurementType, string measurementCharacteristic, string phase)
- {
- LineID = assetID;
- HarmonicGroup = harmonicGroup;
- Name = name;
- MeasurementType = measurementType;
- MeasurementCharacteristic = measurementCharacteristic;
- Phase = phase;
- }
-
- public ChannelKey(Channel channel)
- : this(channel.AssetID, channel.HarmonicGroup, channel.Name, channel.MeasurementType.Name, channel.MeasurementCharacteristic.Name, channel.Phase.Name)
- {
- }
-
- #endregion
-
- #region [ Properties ]
-
- public int LineID { get; }
- public int HarmonicGroup { get; }
- public string Name { get; }
- public string MeasurementType { get; }
- public string MeasurementCharacteristic { get; }
- public string Phase { get; }
-
- #endregion
-
- #region [ Methods ]
-
- public Channel Find(AdoDataConnection connection, int meterID)
- {
- const string QueryFormat =
- "SELECT Channel.* " +
- "FROM " +
- " Channel JOIN " +
- " MeasurementType ON Channel.MeasurementTypeID = MeasurementType.ID JOIN " +
- " MeasurementCharacteristic ON Channel.MeasurementCharacteristicID = MeasurementCharacteristic.ID JOIN " +
- " Phase ON Channel.PhaseID = Phase.ID " +
- "WHERE " +
- " Channel.MeterID = {0} AND " +
- " Channel.AssetID = {1} AND " +
- " Channel.HarmonicGroup = {2} AND " +
- " Channel.Name = {3} AND " +
- " MeasurementType.Name = {4} AND " +
- " MeasurementCharacteristic.Name = {5} AND " +
- " Phase.Name = {6}";
-
- object[] parameters =
- {
- meterID,
- LineID,
- HarmonicGroup,
- Name,
- MeasurementType,
- MeasurementCharacteristic,
- Phase
- };
-
- using (DataTable table = connection.RetrieveData(QueryFormat, parameters))
- {
- if (table.Rows.Count == 0)
- return null;
-
- TableOperations channelTable = new TableOperations(connection);
- return channelTable.LoadRecord(table.Rows[0]);
- }
- }
-
- public override int GetHashCode()
- {
- StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
-
- int hash = 1009;
- hash = 9176 * hash + LineID.GetHashCode();
- hash = 9176 * hash + HarmonicGroup.GetHashCode();
- hash = 9176 * hash + stringComparer.GetHashCode(Name);
- hash = 9176 * hash + stringComparer.GetHashCode(MeasurementType);
- hash = 9176 * hash + stringComparer.GetHashCode(MeasurementCharacteristic);
- hash = 9176 * hash + stringComparer.GetHashCode(Phase);
- return hash;
- }
-
- public override bool Equals(object obj)
- {
- return Equals(obj as ChannelKey);
- }
-
- public bool Equals(ChannelKey other)
- {
- if (other is null)
- return false;
-
- StringComparison stringComparison = StringComparison.OrdinalIgnoreCase;
-
- return
- LineID.Equals(other.LineID) &&
- HarmonicGroup.Equals(other.HarmonicGroup) &&
- Name.Equals(other.Name, stringComparison) &&
- MeasurementType.Equals(other.MeasurementType, stringComparison) &&
- MeasurementCharacteristic.Equals(other.MeasurementCharacteristic, stringComparison) &&
- Phase.Equals(other.Phase, stringComparison);
- }
-
- #endregion
- }
-
- [TableName("Channel")]
- public class ChannelBase
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [ParentKey(typeof(Meter))]
- public int MeterID { get; set; }
-
- public int AssetID { get; set; }
-
- public int MeasurementTypeID { get; set; }
-
- public int MeasurementCharacteristicID { get; set; }
-
- public int PhaseID { get; set; }
-
- [StringLength(200)]
- public string Name { get; set; }
-
- public double Adder { get; set; }
-
- [DefaultValue(1.0D)]
- public double Multiplier { get; set; } = 1.0D;
-
- public double SamplesPerHour { get; set; }
-
- public double? PerUnitValue { get; set; }
-
- public int HarmonicGroup { get; set; }
-
- public string Description { get; set; }
-
- public bool Enabled { get; set; }
-
- [DefaultValue(false)]
- public bool Trend { get; set; }
-
- [DefaultValue(0)]
- public int ConnectionPriority { get; set; } = 0;
- }
-
- public class Channel : ChannelBase
- {
- #region [ Members ]
-
- // Fields
- private MeasurementType m_measurementType;
- private MeasurementCharacteristic m_measurementCharacteristic;
- private Phase m_phase;
- private Meter m_meter;
- private Asset m_asset;
- private List m_series;
-
- #endregion
-
- #region [ Properties ]
-
- [JsonIgnore]
- [NonRecordField]
- public MeasurementType MeasurementType
- {
- get
- {
- if (m_measurementType is null)
- m_measurementType = LazyContext.GetMeasurementType(MeasurementTypeID);
-
- if (m_measurementType is null)
- m_measurementType = QueryMeasurementType();
-
- return m_measurementType;
- }
- set => m_measurementType = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public MeasurementCharacteristic MeasurementCharacteristic
- {
- get
- {
- if (m_measurementCharacteristic is null)
- m_measurementCharacteristic = LazyContext.GetMeasurementCharacteristic(MeasurementCharacteristicID);
-
- if (m_measurementCharacteristic is null)
- m_measurementCharacteristic = QueryMeasurementCharacteristic();
-
- return m_measurementCharacteristic;
- }
- set => m_measurementCharacteristic = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Phase Phase
- {
- get
- {
- if (m_phase is null)
- m_phase = LazyContext.GetPhase(PhaseID);
-
- if (m_phase is null)
- m_phase = QueryPhase();
-
- return m_phase;
- }
- set => m_phase = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Meter Meter
- {
- get
- {
- if (m_meter is null)
- m_meter = LazyContext.GetMeter(MeterID);
-
- if (m_meter is null)
- m_meter = QueryMeter();
-
- return m_meter;
- }
- set => m_meter = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Asset Asset
- {
- get
- {
- if (m_asset is null)
- m_asset = LazyContext.GetAsset(AssetID);
-
- if (m_asset is null)
- m_asset = QueryAsset();
-
- return m_asset;
- }
- set => m_asset = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public List Series
- {
- get => m_series ?? (m_series = QuerySeries());
- set => m_series = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Func ConnectionFactory
- {
- get => LazyContext.ConnectionFactory;
- set => LazyContext.ConnectionFactory = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- internal LazyContext LazyContext { get; set; } = new LazyContext();
-
- #endregion
-
- #region [ Methods ]
-
- public MeasurementType GetMeasurementType(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations measurementTypeTable = new TableOperations(connection);
- return measurementTypeTable.QueryRecordWhere("ID = {0}", MeasurementTypeID);
- }
-
- public MeasurementCharacteristic GetMeasurementCharacteristic(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations measurementCharacteristicTable = new TableOperations(connection);
- return measurementCharacteristicTable.QueryRecordWhere("ID = {0}", MeasurementCharacteristicID);
- }
-
- public Phase GetPhase(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations phaseTable = new TableOperations(connection);
- return phaseTable.QueryRecordWhere("ID = {0}", PhaseID);
- }
-
- public Meter GetMeter(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations meterTable = new TableOperations(connection);
- return meterTable.QueryRecordWhere("ID = {0}", MeterID);
- }
-
- public Asset GetAsset(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations assetTable = new TableOperations(connection);
- return assetTable.QueryRecordWhere("ID = {0}", AssetID);
- }
-
- public IEnumerable GetSeries(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations seriesTable = new TableOperations(connection);
- return seriesTable.QueryRecordsWhere("ChannelID = {0}", ID);
- }
-
- private MeasurementType QueryMeasurementType()
- {
- MeasurementType measurementType;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- measurementType = GetMeasurementType(connection);
- }
-
- return LazyContext.GetMeasurementType(measurementType);
- }
-
- private MeasurementCharacteristic QueryMeasurementCharacteristic()
- {
- MeasurementCharacteristic measurementCharacteristic;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- measurementCharacteristic = GetMeasurementCharacteristic(connection);
- }
-
- return LazyContext.GetMeasurementCharacteristic(measurementCharacteristic);
- }
-
- private Phase QueryPhase()
- {
- Phase phase;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- phase = GetPhase(connection);
- }
-
- return LazyContext.GetPhase(phase);
- }
-
- private Meter QueryMeter()
- {
- Meter meter;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- meter = GetMeter(connection);
- }
-
- if ((object)meter != null)
- meter.LazyContext = LazyContext;
-
- return LazyContext.GetMeter(meter);
- }
-
- private Asset QueryAsset()
- {
- Asset asset;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- asset = GetAsset(connection);
- }
-
- if ((object)asset != null)
- asset.LazyContext = LazyContext;
-
- return LazyContext.GetAsset(asset);
- }
-
- private List QuerySeries()
- {
- List seriesList;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- seriesList = GetSeries(connection)?
- .Select(LazyContext.GetSeries)
- .ToList();
- }
-
- if ((object)seriesList != null)
- {
- foreach (Series series in seriesList)
- {
- series.Channel = this;
- series.LazyContext = LazyContext;
- }
- }
-
- return seriesList;
- }
-
- #endregion
- }
-
- public class ChannelComparer : IEqualityComparer
- {
- public bool Equals(Channel x, Channel y)
- {
- if (Object.ReferenceEquals(x, y)) return true;
-
- //Check whether any of the compared objects is null.
- if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
- return false;
-
- //Check whether the channels are equal.
- return x.ID == y.ID;
- }
-
- public int GetHashCode(Channel obj)
- {
- return obj.ID;
- }
- }
-
- [TableName("ChannelDetail")]
- public class ChannelDetail : Channel
- {
- public string MeterName { get; set; }
-
- public string AssetKey { get; set; }
-
- public string AssetName { get; set; }
-
- public new string MeasurementType { get; set; }
-
- public new string MeasurementCharacteristic { get; set; }
-
- public new string Phase { get; set; }
-
- public string Mapping { get; set; }
-
- public int SeriesTypeID { get; set; }
-
- public string SeriesType { get; set; }
-
- [SearchExtension("^VoltageKV$")]
- public static RecordRestriction GetVoltageKVRestriction(IRecordFilter filter)
- {
- return SearchRestrictionHelper.GetSearchRestriction("(SELECT VoltageKV FROM Asset WHERE Asset.ID = FullTbl.AssetID)", filter);
- }
-
- [SearchExtension("^ChannelGroupTypeID$")]
- public static RecordRestriction GetChannelGroupTypeRestriction(IRecordFilter filter)
- {
- RecordRestriction restriction = SearchRestrictionHelper.GetSearchRestriction("ID", filter);
-
- return new RecordRestriction(
- $"EXISTS(SELECT * FROM ChannelGroupType WHERE {restriction.FilterExpression} AND MeasurementTypeID = FullTbl.MeasurementTypeID AND MeasurementCharacteristicID = FullTbl.MeasurementCharacteristicID)",
- restriction.Parameters);
- }
-
- [SearchExtension("^SeriesID$")]
- public static RecordRestriction GetSeriesRestriction(IRecordFilter filter)
- {
- RecordRestriction restriction = SearchRestrictionHelper.GetSearchRestriction("Series.SeriesTypeID", filter);
-
- return new RecordRestriction(
- $"(SELECT COUNT(Series.ID) FROM SERIES WHERE Series.ChannelID = FullTbl.ID AND {restriction.FilterExpression}) > 0",
- restriction.Parameters);
- }
- }
-
- public class ChannelInfo
- {
- [PrimaryKey(true)]
- public int ChannelID { get; set; }
-
- public string ChannelName { get; set; }
-
- public string ChannelDescription { get; set; }
-
- public string MeasurementType { get; set; }
-
- public string MeasurementCharacteristic { get; set; }
-
- public string Phase { get; set; }
-
- public string SeriesType { get; set; }
-
- public string Orientation { get; set; }
-
- public string Phasing { get; set; }
- }
-
- public static partial class TableOperationsExtensions
- {
- public static DashSettings GetOrAdd(this TableOperations table, string name, string value, bool enabled = true)
- {
- TransactionScopeOption required = TransactionScopeOption.Required;
-
- TransactionOptions transactionOptions = new TransactionOptions()
- {
- IsolationLevel = IsolationLevel.ReadCommitted,
- Timeout = TransactionManager.MaximumTimeout
- };
-
- DashSettings dashSettings;
-
- using (TransactionScope transactionScope = new TransactionScope(required, transactionOptions))
- {
- if (value.Contains(","))
- dashSettings = table.QueryRecordWhere("Name = {0} AND SUBSTRING(Value, 0, CHARINDEX(',', Value)) = {1}", name, value.Split(',').First());
- else
- dashSettings = table.QueryRecordWhere("Name = {0} AND Value = {1}", name, value);
-
- if ((object)dashSettings == null)
- {
- dashSettings = new DashSettings();
- dashSettings.Name = name;
- dashSettings.Value = value;
- dashSettings.Enabled = enabled;
-
- table.AddNewRecord(dashSettings);
-
- dashSettings.ID = table.Connection.ExecuteScalar("SELECT @@IDENTITY");
- }
-
- transactionScope.Complete();
- }
-
- return dashSettings;
- }
-
- public static UserDashSettings GetOrAdd(this TableOperations table, string name, Guid user, string value, bool enabled = true)
- {
- TransactionScopeOption required = TransactionScopeOption.Required;
-
- TransactionOptions transactionOptions = new TransactionOptions()
- {
- IsolationLevel = IsolationLevel.ReadCommitted,
- Timeout = TransactionManager.MaximumTimeout
- };
-
- UserDashSettings dashSettings;
-
- using (TransactionScope transactionScope = new TransactionScope(required, transactionOptions))
- {
- if (value.Contains(","))
- dashSettings = table.QueryRecordWhere("Name = {0} AND SUBSTRING(Value, 0, CHARINDEX(',', Value)) = {1} AND UserAccountID = {2}", name, value.Split(',').First(), user);
- else
- dashSettings = table.QueryRecordWhere("Name = {0} AND Value = {1} AND UserAccountID = {2}", name, value, user);
-
- if ((object)dashSettings == null)
- {
- dashSettings = new UserDashSettings();
- dashSettings.Name = name;
- dashSettings.Value = value;
- dashSettings.Enabled = enabled;
- dashSettings.UserAccountID = user;
-
- table.AddNewRecord(dashSettings);
-
- dashSettings.ID = table.Connection.ExecuteScalar("SELECT @@IDENTITY");
- }
-
- transactionScope.Complete();
- }
-
- return dashSettings;
- }
-
- }
-
-}
diff --git a/Libraries/openXDA.Model/Channels/ChannelData.cs b/Libraries/openXDA.Model/Channels/ChannelData.cs
deleted file mode 100644
index 2ce28f94..00000000
--- a/Libraries/openXDA.Model/Channels/ChannelData.cs
+++ /dev/null
@@ -1,649 +0,0 @@
-//******************************************************************************************************
-// ChannelData.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 12/12/2019 - C. Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone;
-using Gemstone.Data;
-using Gemstone.Data.DataExtensions;
-using Gemstone.Data.Model;
-using Ionic.Zlib;
-
-namespace openXDA.Model
-{
- [TableName("ChannelData")]
- public class ChannelData
- {
- #region [ Members ]
-
- // Nested Types
- private class DigitalSection
- {
- public DateTime Start { get; set; }
- public DateTime End { get; set; }
- public int NumPoints { get; set; }
- public double Value { get; set; }
- public static int Size => 2 * sizeof(long) + sizeof(ushort) + sizeof(int);
-
- public int CopyBytes(byte[] byteArray, int offset, double compressionScale, double compressionOffset)
- {
- ushort compressedValue = (ushort)Math.Round((Value - compressionOffset) * compressionScale);
- const ushort NaNValue = ushort.MaxValue;
-
- if (compressedValue == NaNValue)
- compressedValue--;
-
- if (double.IsNaN(Value))
- compressedValue = NaNValue;
-
- int startOffset = offset;
- offset += LittleEndian.CopyBytes(Start.Ticks, byteArray, offset);
- offset += LittleEndian.CopyBytes(End.Ticks, byteArray, offset);
- offset += LittleEndian.CopyBytes(compressedValue, byteArray, offset);
- offset += LittleEndian.CopyBytes(NumPoints, byteArray, offset);
- return offset - startOffset;
- }
-
- public static DigitalSection FromBytes(byte[] bytes, int offset, double decompressionOffset, double decompressionScale)
- {
- DigitalSection section = new DigitalSection();
-
- section.Start = new DateTime(LittleEndian.ToInt64(bytes, offset));
- offset += sizeof(long);
-
- section.End = new DateTime(LittleEndian.ToInt64(bytes, offset));
- offset += sizeof(long);
-
- ushort compressedValue = LittleEndian.ToUInt16(bytes, offset);
- section.Value = decompressionScale * compressedValue + decompressionOffset;
- offset += sizeof(ushort);
-
- section.NumPoints = LittleEndian.ToInt32(bytes, offset);
-
- return section;
- }
- }
- #endregion
-
- #region [ Properties ]
-
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int SeriesID { get; set; }
-
- public int EventID { get; set; }
-
- public byte[] TimeDomainData { get; set; }
-
- public int MarkedForDeletion { get; set; }
-
- #endregion
-
- #region [ Methods ]
-
- ///
- /// Adjusts the TimeDomain Data by Moving it a certain ammount of Time
- ///
- /// The number of Ticks the Data is moved. For moving it backwards in Time this needs to be < 0
- public void AdjustData(Ticks ticks)
- {
- // Initially we assume Data is already migrated...
- if (TimeDomainData == null)
- return;
-
- Tuple> decompressed = Decompress(TimeDomainData)[0];
- List data = decompressed.Item2;
-
- foreach (DataPoint dataPoint in data)
- dataPoint.Time = dataPoint.Time.AddTicks(ticks);
-
- TimeDomainData = ToData(data, decompressed.Item1);
- }
-
- #endregion
-
- #region [ Static ]
-
- public static List DataFromEvent(int eventID, Func connectionFactory)
- {
- using (AdoDataConnection connection = connectionFactory())
- {
- TableOperations eventTable = new TableOperations(connection);
- Event evt = eventTable.QueryRecordWhere("ID = {0}", eventID);
-
- TableOperations assetTable = new TableOperations(connection);
- Asset asset = assetTable.QueryRecordWhere("ID = {0}", evt.AssetID);
- asset.ConnectionFactory = connectionFactory;
-
- List channels = asset.DirectChannels
- .Concat(asset.ConnectedChannels)
- .Where(channel => channel.MeterID == evt.MeterID)
- .ToList();
-
- if (!channels.Any())
- return new List();
-
- IEnumerable assetIDs = channels
- .Select(channel => channel.AssetID)
- .Distinct();
-
- foreach (int assetID in assetIDs)
- MigrateLegacyBlob(connection, evt.FileGroupID, assetID, evt.StartTime);
-
- // Optimization to avoid individually querying channels that don't have any data
- HashSet channelsWithData = QueryChannelsWithData(connection, evt);
- channels.RemoveAll(channel => !channelsWithData.Contains(channel.ID));
-
- List eventData = new List();
-
- foreach (Channel channel in channels)
- {
- const string DataQueryFormat =
- "SELECT ChannelData.TimeDomainData " +
- "FROM " +
- " ChannelData JOIN " +
- " Series ON ChannelData.SeriesID = Series.ID JOIN " +
- " Event ON ChannelData.EventID = Event.ID " +
- "WHERE " +
- " Event.FileGroupID = {0} AND " +
- " Series.ChannelID = {1} AND " +
- " Event.StartTime = {2}";
-
- object startTime2 = ToDateTime2(connection, evt.StartTime);
- byte[] timeDomainData = connection.ExecuteScalar(DataQueryFormat, evt.FileGroupID, channel.ID, startTime2);
-
- if (timeDomainData is null)
- continue;
-
- eventData.Add(timeDomainData);
- }
-
- return eventData;
- }
- }
-
- public static byte[] DataFromEvent(int eventID, int channelID, Func connectionFactory)
- {
- using (AdoDataConnection connection = connectionFactory())
- {
- TableOperations eventTable = new TableOperations(connection);
- Event evt = eventTable.QueryRecordWhere("ID = {0}", eventID);
- MigrateLegacyBlob(connection, evt);
-
- const string QueryFormat =
- "SELECT ChannelData.TimeDomainData " +
- "FROM " +
- " ChannelData JOIN " +
- " Series ON ChannelData.SeriesID = Series.ID " +
- "WHERE " +
- " ChannelData.EventID = {0} AND " +
- " Series.ChannelID = {1}";
-
- return connection.ExecuteScalar(QueryFormat, eventID, channelID);
- }
- }
-
- private static void MigrateLegacyBlob(AdoDataConnection connection, int fileGroupID, int assetID, DateTime startTime)
- {
- const string AssetQueryFilter = "FileGroupID = {0} AND AssetID = {1} AND StartTime = {2}";
- object startTime2 = ToDateTime2(connection, startTime);
-
- TableOperations eventTable = new TableOperations(connection);
- Event evt = eventTable.QueryRecordWhere(AssetQueryFilter, fileGroupID, assetID, startTime2);
- MigrateLegacyBlob(connection, evt);
- }
-
- private static void MigrateLegacyBlob(AdoDataConnection connection, Event evt)
- {
- if (evt is null || evt.EventDataID is null)
- return;
-
- int eventDataID = evt.EventDataID.GetValueOrDefault();
- byte[] timeDomainData = connection.ExecuteScalar("SELECT TimeDomainData FROM EventData WHERE ID = {0}", eventDataID);
- List>> decompressedData = Decompress(timeDomainData);
-
- TableOperations channelDataTable = new TableOperations(connection);
-
- foreach (Tuple> tuple in decompressedData)
- {
- int seriesID = tuple.Item1;
- List data = tuple.Item2;
-
- ChannelData channelData = new ChannelData();
- channelData.SeriesID = seriesID;
- channelData.EventID = evt.ID;
- channelData.TimeDomainData = ToData(data, seriesID);
- channelDataTable.AddNewRecord(channelData);
- }
-
- connection.ExecuteNonQuery("UPDATE Event SET EventDataID = NULL WHERE ID = {0}", evt.ID);
- connection.ExecuteNonQuery("DELETE FROM EventData WHERE ID = {0}", eventDataID);
- }
-
- ///
- /// Turns a list of DataPoints into a blob to be saved in the database.
- ///
- /// The data as a
- /// The SeriesID to be encoded into the blob
- /// The byte array to be saved as a blob in the database.
- public static byte[] ToData(List data, int seriesID)
- {
- // We can use Digital compression if the data changes no more than 10% of the time.
- bool useDigitalCompression = data
- .Skip(1)
- .Zip(data, (p2, p1) => new { p1, p2 })
- .Where(obj => obj.p1.Value != obj.p2.Value)
- .Select((_, index) => index + 1)
- .All(nChanges => nChanges <= 0.1 * data.Count);
-
- if (useDigitalCompression)
- return ToDigitalData(data, seriesID);
-
- var timeSeries = data.Select(dataPoint => new { Time = dataPoint.Time.Ticks, Compressed = false }).ToList();
-
- for (int i = 1; i < timeSeries.Count; i++)
- {
- long previousTimestamp = data[i - 1].Time.Ticks;
- long timestamp = timeSeries[i].Time;
- long diff = timestamp - previousTimestamp;
-
- if (diff >= 0 && diff <= ushort.MaxValue)
- timeSeries[i] = new { Time = diff, Compressed = true };
- }
-
- int timeSeriesByteLength = timeSeries.Sum(obj => obj.Compressed ? sizeof(ushort) : sizeof(int) + sizeof(long));
- int dataSeriesByteLength = sizeof(int) + (2 * sizeof(double)) + (data.Count * sizeof(ushort));
- int totalByteLength = sizeof(int) + timeSeriesByteLength + dataSeriesByteLength;
-
- byte[] result = new byte[totalByteLength];
- int offset = 0;
-
- offset += LittleEndian.CopyBytes(data.Count, result, offset);
-
- List uncompressedIndexes = timeSeries
- .Select((obj, Index) => new { obj.Compressed, Index })
- .Where(obj => !obj.Compressed)
- .Select(obj => obj.Index)
- .ToList();
-
- for (int i = 0; i < uncompressedIndexes.Count; i++)
- {
- int index = uncompressedIndexes[i];
- int nextIndex = (i + 1 < uncompressedIndexes.Count) ? uncompressedIndexes[i + 1] : timeSeries.Count;
-
- offset += LittleEndian.CopyBytes(nextIndex - index, result, offset);
- offset += LittleEndian.CopyBytes(timeSeries[index].Time, result, offset);
-
- for (int j = index + 1; j < nextIndex; j++)
- offset += LittleEndian.CopyBytes((ushort)timeSeries[j].Time, result, offset);
- }
-
- const ushort NaNValue = ushort.MaxValue;
- const ushort MaxCompressedValue = ushort.MaxValue - 1;
- double range = data.Select(item => item.Value).Max() - data.Select(item => item.Value).Min();
- double decompressionOffset = data.Select(item => item.Value).Min();
- double decompressionScale = range / MaxCompressedValue;
- double compressionScale = (decompressionScale != 0.0D) ? 1.0D / decompressionScale : 0.0D;
-
- offset += LittleEndian.CopyBytes(seriesID, result, offset);
- offset += LittleEndian.CopyBytes(decompressionOffset, result, offset);
- offset += LittleEndian.CopyBytes(decompressionScale, result, offset);
-
- foreach (DataPoint dataPoint in data)
- {
- ushort compressedValue = (ushort)Math.Round((dataPoint.Value - decompressionOffset) * compressionScale);
-
- if (compressedValue == NaNValue)
- compressedValue--;
-
- if (double.IsNaN(dataPoint.Value))
- compressedValue = NaNValue;
-
- offset += LittleEndian.CopyBytes(compressedValue, result, offset);
- }
-
- byte[] returnArray = GZipStream.CompressBuffer(result);
- returnArray[0] = 0x44;
- returnArray[1] = 0x33;
-
- return returnArray;
- }
-
- private static byte[] ToDigitalData(List data, int seriesID)
- {
- List digitalData = new List();
- DigitalSection currentSection = null;
- foreach (DataPoint dataPoint in data)
- {
- if (currentSection is null)
- {
- currentSection = new DigitalSection()
- {
- Start = dataPoint.Time,
- End = dataPoint.Time,
- Value = dataPoint.Value,
- NumPoints = 1
- };
- }
- else if (currentSection.Value != dataPoint.Value)
- {
- digitalData.Add(currentSection);
- currentSection = new DigitalSection()
- {
- Start = dataPoint.Time,
- End = dataPoint.Time,
- Value = dataPoint.Value,
- NumPoints = 1
- };
- }
- else
- {
- currentSection.NumPoints++;
- currentSection.End = dataPoint.Time;
- }
- }
-
- if (!(currentSection is null))
- digitalData.Add(currentSection);
-
- int totalByteLength = sizeof(int) + 2 * sizeof(double) + digitalData.Count * DigitalSection.Size;
- byte[] result = new byte[totalByteLength];
- int offset = 0;
-
- const ushort MaxCompressedValue = ushort.MaxValue - 1;
- double range = data.Select(item => item.Value).Max() - data.Select(item => item.Value).Min();
- double decompressionOffset = data.Select(item => item.Value).Min();
- double decompressionScale = range / MaxCompressedValue;
- double compressionScale = (decompressionScale != 0.0D) ? 1.0D / decompressionScale : 0.0D;
-
- offset += LittleEndian.CopyBytes(seriesID, result, offset);
- offset += LittleEndian.CopyBytes(decompressionOffset, result, offset);
- offset += LittleEndian.CopyBytes(decompressionScale, result, offset);
-
- foreach (DigitalSection digitalSection in digitalData)
- offset += digitalSection.CopyBytes(result, offset, compressionScale, decompressionOffset);
-
- byte[] returnArray = GZipStream.CompressBuffer(result);
- returnArray[0] = DigitalHeader[0];
- returnArray[1] = DigitalHeader[1];
- return returnArray;
- }
-
- ///
- /// Decompresses a byte array into a List of DataPoints
- ///
- /// The byte array filled with compressed data
- /// List of data series consisting of series ID and data points.
- public static List>> Decompress(byte[] data)
- {
- List>> result = new List>>();
-
- if (data == null)
- return result;
- // If the blob contains the GZip header,
- // use the legacy deserialization algorithm
- if (data[0] == LegacyHeader[0] && data[1] == LegacyHeader[1])
- {
- return Decompress_Legacy(data);
- }
- // If this blob uses digital decompression use that algorithm
- if (data[0] == DigitalHeader[0] && data[1] == DigitalHeader[1])
- {
- return Decompress_Digital(data);
- }
-
- // Restore the GZip header before uncompressing
- data[0] = LegacyHeader[0];
- data[1] = LegacyHeader[1];
-
- byte[] uncompressedData;
- int offset;
-
- uncompressedData = GZipStream.UncompressBuffer(data);
- offset = 0;
-
- int m_samples = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- List times = new List();
-
- while (times.Count < m_samples)
- {
- int timeValues = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- long currentValue = LittleEndian.ToInt64(uncompressedData, offset);
- offset += sizeof(long);
- times.Add(new DateTime(currentValue));
-
- for (int i = 1; i < timeValues; i++)
- {
- currentValue += LittleEndian.ToUInt16(uncompressedData, offset);
- offset += sizeof(ushort);
- times.Add(new DateTime(currentValue));
- }
- }
-
- while (offset < uncompressedData.Length)
- {
- List dataSeries = new List();
- int seriesID = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
-
- const ushort NaNValue = ushort.MaxValue;
- double decompressionOffset = LittleEndian.ToDouble(uncompressedData, offset);
- double decompressionScale = LittleEndian.ToDouble(uncompressedData, offset + sizeof(double));
- offset += 2 * sizeof(double);
-
- for (int i = 0; i < m_samples; i++)
- {
- ushort compressedValue = LittleEndian.ToUInt16(uncompressedData, offset);
- offset += sizeof(ushort);
-
- double decompressedValue = decompressionScale * compressedValue + decompressionOffset;
-
- if (compressedValue == NaNValue)
- decompressedValue = double.NaN;
-
- dataSeries.Add(new DataPoint()
- {
- Time = times[i],
- Value = decompressedValue
- });
- }
-
- result.Add(new Tuple>(seriesID, dataSeries));
- }
-
- return result;
- }
-
- private static List>> Decompress_Legacy(byte[] data)
- {
- List>> result = new List>>();
- byte[] uncompressedData;
- int offset;
- DateTime[] times;
- int seriesID;
-
- uncompressedData = GZipStream.UncompressBuffer(data);
- offset = 0;
-
- int m_samples = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- times = new DateTime[m_samples];
-
- for (int i = 0; i < m_samples; i++)
- {
- times[i] = new DateTime(LittleEndian.ToInt64(uncompressedData, offset));
- offset += sizeof(long);
- }
-
- while (offset < uncompressedData.Length)
- {
- seriesID = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- List points = new List();
-
- for (int i = 0; i < m_samples; i++)
- {
- points.Add(new DataPoint()
- {
- Time = times[i],
- Value = LittleEndian.ToDouble(uncompressedData, offset)
- });
-
- offset += sizeof(double);
- }
-
- result.Add(new Tuple>(seriesID, points));
- }
- return result;
- }
-
- ///
- /// Decompresses a Digital stored as compresed series of changes
- ///
- /// The compressed
- /// a Dictionary mapping a SeriesID to a decopmressed
- private static List>> Decompress_Digital(byte[] data)
- {
- List>> result = new List>>();
- byte[] uncompressedData;
- int offset;
- int seriesID;
- List points = new List();
-
- // Restore the GZip header before uncompressing
- data[0] = LegacyHeader[0];
- data[1] = LegacyHeader[1];
-
- uncompressedData = GZipStream.UncompressBuffer(data);
- offset = 0;
-
- seriesID = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- double decompressionOffset = LittleEndian.ToDouble(uncompressedData, offset);
- double decompressionScale = LittleEndian.ToDouble(uncompressedData, offset + sizeof(double));
- offset += 2 * sizeof(double);
-
- while(offset < uncompressedData.Length)
- {
- DigitalSection section = DigitalSection.FromBytes(uncompressedData, offset, decompressionOffset, decompressionScale);
- offset += DigitalSection.Size;
-
- points.Add(new DataPoint()
- {
- Time = section.Start,
- Value = section.Value
- });
-
- if (section.NumPoints == 1)
- continue;
-
- // Use a fixed-point offset with 6 bits of additional
- // precision to help avoid accumulation of rounding errors
- long diff = (section.End - section.Start).Ticks << 6;
- long step = diff / (section.NumPoints - 1);
- long lastOffset = step;
-
- for (int i = 1; i < section.NumPoints - 1; i++)
- {
- points.Add(new DataPoint()
- {
- Time = section.Start.AddTicks(lastOffset >> 6),
- Value = section.Value
- });
-
- lastOffset += step;
- }
-
- points.Add(new DataPoint()
- {
- Time = section.End,
- Value = section.Value
- });
- }
-
- result.Add(new Tuple>(seriesID, points));
-
- return result;
- }
-
- private static HashSet QueryChannelsWithData(AdoDataConnection connection, Event evt)
- {
- const string FilterQueryFormat =
- "SELECT Series.ChannelID " +
- "FROM " +
- " ChannelData JOIN " +
- " Series ON ChannelData.SeriesID = Series.ID JOIN " +
- " Event ON ChannelData.EventID = Event.ID " +
- "WHERE " +
- " Event.FileGroupID = {0} AND " +
- " Event.StartTime = {1}";
-
- object startTime2 = ToDateTime2(connection, evt.StartTime);
-
- using (DataTable table = connection.RetrieveData(FilterQueryFormat, evt.FileGroupID, startTime2))
- {
- IEnumerable channelsWithData = table
- .AsEnumerable()
- .Select(row => row.ConvertField("ChannelID"));
-
- return new HashSet(channelsWithData);
- }
- }
-
- private static object ToDateTime2(AdoDataConnection connection, DateTime dateTime)
- {
- using (IDbCommand command = connection.Connection.CreateCommand())
- {
- IDbDataParameter parameter = command.CreateParameter();
- parameter.DbType = DbType.DateTime2;
- parameter.Value = dateTime;
- return parameter;
- }
- }
-
- ///
- /// The header of a datablob compressed as analog Data
- ///
- public static readonly byte[] AnalogHeader = { 0x11, 0x11 };
-
- ///
- /// The header of a datablob compressed as Digital State Changes
- ///
- public static readonly byte[] DigitalHeader = { 0x22, 0x22 };
-
- ///
- /// The header of a datablob compressed as Legacy Data
- ///
- public static readonly byte[] LegacyHeader = { 0x1F, 0x8B };
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/ChannelGroup.cs b/Libraries/openXDA.Model/Channels/ChannelGroup.cs
deleted file mode 100644
index b5b463c2..00000000
--- a/Libraries/openXDA.Model/Channels/ChannelGroup.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-//******************************************************************************************************
-// ChannelGroup.cs - Gbtc
-//
-// Copyright © 2020, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 10/12/2020 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-
-
-using Gemstone.Data.Model;
-using System.ComponentModel.DataAnnotations;
-
-namespace openXDA.Model;
-
-[PostRoles("Administrator, Transmission SME")]
-[PatchRoles("Administrator, Transmission SME")]
-[DeleteRoles("Administrator, Transmission SME")]
-public class ChannelGroup
-{
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [StringLength(200)]
- public string Name { get; set; }
-
- public string Description { get; set; }
-}
diff --git a/Libraries/openXDA.Model/Channels/DataPoint.cs b/Libraries/openXDA.Model/Channels/DataPoint.cs
deleted file mode 100644
index 88c39332..00000000
--- a/Libraries/openXDA.Model/Channels/DataPoint.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-//******************************************************************************************************
-// DataPoint.cs - Gbtc
-//
-// Copyright © 2025, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 05/15/2025 - C. Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-namespace openXDA.Model
-{
- ///
- /// Represents a single data point in a time series.
- ///
- public class DataPoint
- {
- #region [ Properties ]
-
- public DateTime Time { get; set; }
- public double Value { get; set; }
-
- #endregion
-
- #region [ Methods ]
-
- public DataPoint Shift(TimeSpan timeShift)
- {
- return new DataPoint()
- {
- Time = Time.Add(timeShift),
- Value = Value
- };
- }
-
- public DataPoint Negate()
- {
- return new DataPoint()
- {
- Time = Time,
- Value = -Value
- };
- }
-
- public DataPoint Add(DataPoint point)
- {
- if (Time != point.Time)
- throw new InvalidOperationException("Cannot add datapoints with mismatched times");
-
- return new DataPoint()
- {
- Time = Time,
- Value = Value + point.Value
- };
- }
-
- public DataPoint Subtract(DataPoint point)
- {
- return Add(point.Negate());
- }
-
- public DataPoint Add(double value)
- {
- return new DataPoint()
- {
- Time = Time,
- Value = Value + value
- };
- }
-
- public DataPoint Subtract(double value)
- {
- return Add(-value);
- }
-
- public DataPoint Multiply(double value)
- {
- return new DataPoint()
- {
- Time = Time,
- Value = Value * value
- };
- }
-
- public bool LargerThan(double comparison)
- {
- return Value > comparison;
- }
-
- public bool LargerThan(DataPoint point)
- {
- return LargerThan(point.Value);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/MeasurementCharacteristic.cs b/Libraries/openXDA.Model/Channels/MeasurementCharacteristic.cs
deleted file mode 100644
index a3e49898..00000000
--- a/Libraries/openXDA.Model/Channels/MeasurementCharacteristic.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-//******************************************************************************************************
-// MeasurementCharacteristic.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel.DataAnnotations;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [PostRoles("Administrator, Transmission SME")]
- [DeleteRoles("Administrator, Transmission SME")]
- [PatchRoles("Administrator, Transmission SME")]
- public class MeasurementCharacteristic
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [StringLength(200)]
- [DefaultSortOrder]
- public string Name { get; set; }
-
- public string Description { get; set; }
-
- public bool Display { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/MeasurementType.cs b/Libraries/openXDA.Model/Channels/MeasurementType.cs
deleted file mode 100644
index 20d3ea30..00000000
--- a/Libraries/openXDA.Model/Channels/MeasurementType.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//******************************************************************************************************
-// MeasurementType.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [PostRoles("Administrator, Transmission SME")]
- [DeleteRoles("Administrator, Transmission SME")]
- [PatchRoles("Administrator, Transmission SME")]
- public class MeasurementType
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [StringLength(200)]
- [DefaultSortOrder]
- public string Name { get; set; }
-
- public string Description { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/Phase.cs b/Libraries/openXDA.Model/Channels/Phase.cs
deleted file mode 100644
index 705ec274..00000000
--- a/Libraries/openXDA.Model/Channels/Phase.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-//******************************************************************************************************
-// Phase.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel.DataAnnotations;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [PostRoles("Administrator, Transmission SME")]
- [DeleteRoles("Administrator, Transmission SME")]
- [PatchRoles("Administrator, Transmission SME")]
- public class Phase
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [StringLength(200)]
- [DefaultSortOrder]
- public string Name { get; set; }
-
- public string Description { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/Series.cs b/Libraries/openXDA.Model/Channels/Series.cs
deleted file mode 100644
index d6c96a6c..00000000
--- a/Libraries/openXDA.Model/Channels/Series.cs
+++ /dev/null
@@ -1,248 +0,0 @@
-//******************************************************************************************************
-// Series.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 06/20/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone.Data;
-using Gemstone.Data.Model;
-using Newtonsoft.Json;
-
-namespace openXDA.Model
-{
- public class SeriesKey : IEquatable
- {
- #region [ Constructors ]
-
- public SeriesKey(ChannelKey channelKey, string seriesType)
- {
- ChannelKey = channelKey;
- SeriesType = seriesType;
- }
-
- public SeriesKey(Series series)
- : this(new ChannelKey(series.Channel), series.SeriesType.Name)
- {
- }
-
- #endregion
-
- #region [ Properties ]
-
- public ChannelKey ChannelKey { get; }
- public string SeriesType { get; }
-
- #endregion
-
- #region [ Methods ]
-
- public Series Find(AdoDataConnection connection, int meterID)
- {
- const string QueryFormat =
- "SELECT Series.* " +
- "FROM " +
- " Series JOIN " +
- " Channel ON Series.ChannelID = Channel.ID JOIN " +
- " MeasurementType ON Channel.MeasurementTypeID = MeasurementType.ID JOIN " +
- " MeasurementCharacteristic ON Channel.MeasurementCharacteristicID = MeasurementCharacteristic.ID JOIN " +
- " Phase ON Channel.PhaseID = Phase.ID JOIN " +
- " SeriesType ON Series.SeriesTypeID = SeriesType.ID " +
- "WHERE " +
- " Channel.MeterID = {0} AND " +
- " Channel.AssetID = {1} AND " +
- " Channel.HarmonicGroup = {2} AND " +
- " Channel.Name = {3} AND " +
- " MeasurementType.Name = {4} AND " +
- " MeasurementCharacteristic.Name = {5} AND " +
- " Phase.Name = {6} AND " +
- " SeriesType.Name = {7}";
-
- object[] parameters =
- {
- meterID,
- ChannelKey.LineID,
- ChannelKey.HarmonicGroup,
- ChannelKey.Name,
- ChannelKey.MeasurementType,
- ChannelKey.MeasurementCharacteristic,
- ChannelKey.Phase,
- SeriesType
- };
-
- using (DataTable table = connection.RetrieveData(QueryFormat, parameters))
- {
- if (table.Rows.Count == 0)
- return null;
-
- TableOperations seriesTable = new TableOperations(connection);
- return seriesTable.LoadRecord(table.Rows[0]);
- }
- }
-
- public override int GetHashCode()
- {
- StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
-
- int hash = 1009;
- hash = 9176 * hash + ChannelKey.GetHashCode();
- hash = 9176 * hash + stringComparer.GetHashCode(SeriesType);
- return hash;
- }
-
- public override bool Equals(object obj)
- {
- return Equals(obj as SeriesKey);
- }
-
- public bool Equals(SeriesKey other)
- {
- if (other is null)
- return false;
-
- StringComparison stringComparison = StringComparison.OrdinalIgnoreCase;
-
- return
- ChannelKey.Equals(other.ChannelKey) &&
- SeriesType.Equals(other.SeriesType, stringComparison);
- }
-
- #endregion
- }
-
- public class Series
- {
- #region [ Members ]
-
- // Fields
- private SeriesType m_seriesType;
- private Channel m_channel;
-
- #endregion
-
- #region [ Properties ]
-
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int ChannelID { get; set; }
-
- public int SeriesTypeID { get; set; }
-
- public string SourceIndexes { get; set; }
-
- [JsonIgnore]
- [NonRecordField]
- public SeriesType SeriesType
- {
- get
- {
- if (m_seriesType is null)
- m_seriesType = LazyContext.GetSeriesType(SeriesTypeID);
-
- if (m_seriesType is null)
- m_seriesType = QuerySeriesType();
-
- return m_seriesType;
- }
- set => m_seriesType = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Channel Channel
- {
- get
- {
- if (m_channel is null)
- m_channel = LazyContext.GetChannel(ChannelID);
-
- if (m_channel is null)
- m_channel = QueryChannel();
-
- return m_channel;
- }
- set => m_channel = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- public Func ConnectionFactory
- {
- get => LazyContext.ConnectionFactory;
- set => LazyContext.ConnectionFactory = value;
- }
-
- [JsonIgnore]
- [NonRecordField]
- internal LazyContext LazyContext { get; set; } = new LazyContext();
-
- #endregion
-
- #region [ Methods ]
-
- public SeriesType GetSeriesType(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations seriesTypeTable = new TableOperations(connection);
- return seriesTypeTable.QueryRecordWhere("ID = {0}", SeriesTypeID);
- }
-
- public Channel GetChannel(AdoDataConnection connection)
- {
- if ((object)connection == null)
- return null;
-
- TableOperations channelTable = new TableOperations(connection);
- return channelTable.QueryRecordWhere("ID = {0}", ChannelID);
- }
-
- private SeriesType QuerySeriesType()
- {
- SeriesType seriesType;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- seriesType = GetSeriesType(connection);
- }
-
- return LazyContext.GetSeriesType(seriesType);
- }
-
- private Channel QueryChannel()
- {
- Channel channel;
-
- using (AdoDataConnection connection = ConnectionFactory?.Invoke())
- {
- channel = GetChannel(connection);
- }
-
- if ((object)channel != null)
- channel.LazyContext = LazyContext;
-
- return LazyContext.GetChannel(channel);
- }
-
- #endregion
- }
-}
diff --git a/Libraries/openXDA.Model/Channels/SeriesType.cs b/Libraries/openXDA.Model/Channels/SeriesType.cs
deleted file mode 100644
index c7621b5d..00000000
--- a/Libraries/openXDA.Model/Channels/SeriesType.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-//******************************************************************************************************
-// SeriesType.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel.DataAnnotations;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [TableName("SeriesType")]
- public class SeriesType
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- [StringLength(200)]
- public string Name { get; set; }
-
- public string Description { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/DERAnalytic/DERAnalyticResult.cs b/Libraries/openXDA.Model/DERAnalytic/DERAnalyticResult.cs
deleted file mode 100644
index c667215e..00000000
--- a/Libraries/openXDA.Model/DERAnalytic/DERAnalyticResult.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-//******************************************************************************************************
-// DERAnalyticResult.cs - Gbtc
-//
-// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 11/09/2021 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data.Model;
-
-namespace openXDA.Model;
-
-public class DERAnalyticResult
-{
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int? EventID { get; set; }
-
- public int MeterID { get; set; }
-
- public int AssetID { get; set; }
-
- public int ChannelID { get; set; }
-
- public string Regulation { get; set; }
-
-
- public string Parameter { get; set; }
-
- public double Threshold { get; set; }
-
- public double Value { get; set; }
-
- [UseEscapedName]
- public DateTime Time { get; set; }
-
- public string DataType { get; set; }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Events/BreakerRestrike.cs b/Libraries/openXDA.Model/Events/BreakerRestrike.cs
deleted file mode 100644
index e76661d5..00000000
--- a/Libraries/openXDA.Model/Events/BreakerRestrike.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-//******************************************************************************************************
-// BreakerRestrike.cs - Gbtc
-//
-// Copyright © 2019, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/30/2019 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone.Data;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- public class BreakerRestrike
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int EventID { get; set; }
-
- public int PhaseID { get; set; }
-
- public int InitialExtinguishSample { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime InitialExtinguishTime { get; set; }
- public double InitialExtinguishVoltage { get; set; }
- public int RestrikeSample { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime RestrikeTime { get; set; }
- public double RestrikeVoltage { get; set; }
- public double RestrikeCurrentPeak { get; set; }
- public double RestrikeVoltageDip { get; set; }
- public int TransientPeakSample { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime TransientPeakTime { get; set; }
- public double TransientPeakVoltage { get; set; }
- public double PerUnitTransientPeakVoltage { get; set; }
- public int FinalExtinguishSample { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime FinalExtinguishTime { get; set; }
- public double FinalExtinguishVoltage { get; set; }
- public double I2t { get; set; }
-
- }
-}
diff --git a/Libraries/openXDA.Model/Events/Disturbances/Disturbance.cs b/Libraries/openXDA.Model/Events/Disturbances/Disturbance.cs
deleted file mode 100644
index c83ce0e6..00000000
--- a/Libraries/openXDA.Model/Events/Disturbances/Disturbance.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-//******************************************************************************************************
-// Disturbance.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- public class Disturbance
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
- public int EventID { get; set; }
- public int EventTypeID { get; set; }
- public int PhaseID { get; set; }
- public double Magnitude { get; set; }
- public double PerUnitMagnitude { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, Gemstone.Data.DatabaseType.SQLServer)]
- public DateTime StartTime { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, Gemstone.Data.DatabaseType.SQLServer)]
- public DateTime EndTime { get; set; }
-
- public double DurationSeconds { get; set; }
- public double DurationCycles { get; set; }
- public int StartIndex { get; set; }
- public int EndIndex { get; set; }
- public string UpdatedBy { get; set; }
- }
-
- [TableName("DisturbanceView")]
- public class DisturbanceView: Disturbance
- {
- public int MeterID { get; set; }
- public int LineID { get; set; }
- public int? SeverityCode { get; set; }
- public string MeterName { get; set; }
- public string PhaseName { get; set; }
- }
-
- [TableName("DisturbanceView")]
- public class DisturbancesForDay : DisturbanceView { }
-
- [TableName("DisturbanceView")]
- public class DisturbancesForMeter : DisturbanceView { }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Events/Event.cs b/Libraries/openXDA.Model/Events/Event.cs
deleted file mode 100644
index 992ad47e..00000000
--- a/Libraries/openXDA.Model/Events/Event.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-//******************************************************************************************************
-// Event.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone.Data;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [TableName("Event")]
- public class Event
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int FileGroupID { get; set; }
-
- public int MeterID { get; set; }
-
- public int AssetID { get; set; }
-
- public int EventTypeID { get; set; }
-
- public int? EventDataID { get; set; }
-
- public string Name { get; set; }
-
- public string Alias { get; set; }
-
- public string ShortName { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime StartTime { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime EndTime { get; set; }
-
- public int Samples { get; set; }
-
- public int TimeZoneOffset { get; set; }
-
- public int SamplesPerSecond { get; set; }
-
- public int SamplesPerCycle { get; set; }
-
- public string Description { get; set; }
-
- public int FileVersion { get; set; }
-
- public string UpdatedBy { get; set; }
- }
-
- [TableName("EventView")]
- public class EventView : Event
- {
- [PrimaryKey(true)]
- public new int ID
- {
- get => base.ID;
- set => base.ID = value;
- }
-
- public string AssetName { get; set; }
-
- public string MeterName { get; set; }
-
- public string StationName { get; set; }
-
- public string EventTypeName { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Events/EventStat.cs b/Libraries/openXDA.Model/Events/EventStat.cs
deleted file mode 100644
index 6e004a3e..00000000
--- a/Libraries/openXDA.Model/Events/EventStat.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-//******************************************************************************************************
-// EventStat.cs - Gbtc
-//
-// Copyright © 2018, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 11/07/2018 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- public class EventStat
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
- public int EventID { get; set; }
- public double? VPeak { get; set; }
- public double? VAMax { get; set; }
- public double? VBMax { get; set; }
- public double? VCMax { get; set; }
- public double? VABMax { get; set; }
- public double? VBCMax { get; set; }
- public double? VCAMax { get; set; }
- public double? VAMin { get; set; }
- public double? VBMin { get; set; }
- public double? VCMin { get; set; }
- public double? VABMin { get; set; }
- public double? VBCMin { get; set; }
- public double? VCAMin { get; set; }
- public double? IPeak { get; set; }
- public double? IAMax { get; set; }
- public double? IBMax { get; set; }
- public double? ICMax { get; set; }
- public double? IA2t { get; set; }
- public double? IB2t { get; set; }
- public double? IC2t { get; set; }
- public double? InitialMW { get; set; }
- public double? FinalMW { get; set; }
- public int? PQViewID { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Model/Events/EventType.cs b/Libraries/openXDA.Model/Events/EventType.cs
deleted file mode 100644
index 3d5a0c19..00000000
--- a/Libraries/openXDA.Model/Events/EventType.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-//******************************************************************************************************
-// EventType.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-// 12/20/2022 - C. Lackner
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data.Model;
-
-namespace openXDA.Model;
-
-public class EventType
-{
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public string Name { get; set; }
-
- public string Description { get; set; }
-
- public bool ShowInFilter { get; set; }
-
- public string Category { get; set; }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Events/Faults/Fault.cs b/Libraries/openXDA.Model/Events/Faults/Fault.cs
deleted file mode 100644
index dbf8b955..00000000
--- a/Libraries/openXDA.Model/Events/Faults/Fault.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-//******************************************************************************************************
-// Fault.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [TableName("FaultSummary")]
- public class Fault
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int EventID { get; set; }
-
- public string Algorithm { get; set; }
-
- public int FaultNumber { get; set; }
-
- public int CalculationCycle { get; set; }
-
- public double Distance { get; set; }
-
- public int PathNumber { get; set; }
-
- public int LineSegmentID { get; set; }
-
- public double LineSegmentDistance { get; set; }
-
- public double CurrentMagnitude { get; set; }
-
- public double CurrentLag { get; set; }
-
- public double PrefaultCurrent { get; set; }
-
- public double PostfaultCurrent { get; set; }
-
- public double ReactanceRatio { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, Gemstone.Data.DatabaseType.SQLServer)]
- public DateTime Inception { get; set; }
-
- public double DurationSeconds { get; set; }
-
- public double DurationCycles { get; set; }
-
- public string FaultType { get; set; }
-
- public bool IsSelectedAlgorithm { get; set; }
-
- public bool IsValid { get; set; }
-
- public bool IsSuppressed { get; set; }
- }
-
- public class FaultSummary : Fault { }
-
- [TableName("FaultView")]
- public class FaultView : Fault
- {
- public string MeterName { get; set; }
-
- public string ShortName { get; set; }
-
- public string LocationName { get; set; }
-
- public int MeterID { get; set; }
-
- public int LineID { get; set; }
-
- public string LineName { get; set; }
-
- public int Voltage { get; set; }
-
- public DateTime InceptionTime { get; set; }
-
- public double CurrentDistance { get; set; }
-
- public int RK { get; set; }
- }
-
- [TableName("FaultView")]
- public class FaultForMeter: FaultView { }
-
- public class FaultsDetailsByDate
- {
- public int thefaultid { get; set; }
-
- public string thesite { get; set; }
-
- public string locationname { get; set; }
-
- public int themeterid { get; set; }
-
- public int thelineid { get; set; }
-
- public int theeventid { get; set; }
-
- public string thelinename { get; set; }
-
- public int voltage { get; set; }
-
- public string theinceptiontime { get; set; }
-
- public string thefaulttype { get; set; }
-
- public double thecurrentdistance { get; set; }
-
- public int notecount { get; set; }
-
- public int rk { get; set; }
-
- [NonRecordField]
- public string theeventtype { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Events/Faults/FaultCurve.cs b/Libraries/openXDA.Model/Events/Faults/FaultCurve.cs
deleted file mode 100644
index 02268fa2..00000000
--- a/Libraries/openXDA.Model/Events/Faults/FaultCurve.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-//******************************************************************************************************
-// FaultCurve.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 09/06/2017 - Stephen C. Wills
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.ComponentModel.DataAnnotations;
-using Gemstone;
-using Gemstone.Data.Model;
-using Ionic.Zlib;
-
-namespace openXDA.Model
-{
- public class FaultCurve
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int EventID { get; set; }
-
- public int PathNumber { get; set; }
-
- [StringLength(200)]
- public string Algorithm { get; set; }
-
- public byte[] Data { get; set; }
-
- public byte[] AngleData { get; set; }
-
- #region [Private Class]
- private class DataPoint
- {
- public DateTime Time;
- public double Value;
- }
-
- #endregion
-
- #region [Methods]
-
- public void Adjust(Ticks ticks)
- {
- // If the blob contains the GZip header,
- // move from Legacy Compression to normal Compression
- if (this.Data[0] == 0x1F && this.Data[1] == 0x8B)
- {
- this.Data = MigrateCompression(this.Data);
- }
-
- // If the blob contains the GZip header,
- // move from Legacy Compression to normal Compression
- if (this.AngleData[0] == 0x1F && this.AngleData[1] == 0x8B)
- {
- this.AngleData = MigrateCompression(this.AngleData);
- }
-
- this.Data = ChangeTS(this.Data, ticks);
- this.AngleData = ChangeTS(this.AngleData, ticks);
-
-
- }
-
- private static byte[] ChangeTS(byte[] data, Ticks ticks)
- {
- data[0] = 0x1F;
- data[1] = 0x8B;
-
- byte[] uncompressedData = GZipStream.UncompressBuffer(data);
- byte[] resultData = new byte[uncompressedData.Length];
-
- uncompressedData.CopyTo(resultData,0);
-
- int offset = 0;
-
- int m_samples = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- int timeValues = LittleEndian.ToInt32(uncompressedData, offset);
-
- int startTS = offset;
-
- offset += sizeof(int);
-
- long currentValue = LittleEndian.ToInt64(uncompressedData, offset);
-
- DateTime startTime = new DateTime(currentValue);
- startTime = startTime.AddTicks(ticks);
-
- LittleEndian.CopyBytes(startTime.Ticks, resultData, startTS);
-
- resultData = GZipStream.CompressBuffer(resultData);
- resultData[0] = 0x44;
- resultData[1] = 0x33;
- return resultData;
- }
-
- private static byte[] MigrateCompression(byte[] data)
- {
- byte[] uncompressedData;
- int offset;
- DateTime[] times;
- List series;
- int seriesID = 0;
-
- uncompressedData = GZipStream.UncompressBuffer(data);
- offset = 0;
-
- int m_samples = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
- times = new DateTime[m_samples];
-
- for (int i = 0; i < m_samples; i++)
- {
- times[i] = new DateTime(LittleEndian.ToInt64(uncompressedData, offset));
- offset += sizeof(long);
- }
-
- series = new List();
-
- while (offset < uncompressedData.Length)
- {
-
- seriesID = LittleEndian.ToInt32(uncompressedData, offset);
- offset += sizeof(int);
-
-
- for (int i = 0; i < m_samples; i++)
- {
- series.Add(new DataPoint()
- {
- Time = times[i],
- Value = LittleEndian.ToDouble(uncompressedData, offset)
- });
-
- offset += sizeof(double);
- }
- }
-
- var timeSeries = series.Select(dataPoint => new { Time = dataPoint.Time.Ticks, Compressed = false }).ToList();
-
- for (int i = 1; i < timeSeries.Count; i++)
- {
- long previousTimestamp = series[i - 1].Time.Ticks;
- long timestamp = timeSeries[i].Time;
- long diff = timestamp - previousTimestamp;
-
- if (diff >= 0 && diff <= ushort.MaxValue)
- timeSeries[i] = new { Time = diff, Compressed = true };
-
-
- }
-
- int timeSeriesByteLength = timeSeries.Sum(obj => obj.Compressed ? sizeof(ushort) : sizeof(int) + sizeof(long));
- int dataSeriesByteLength = sizeof(int) + (2 * sizeof(double)) + (m_samples * sizeof(ushort));
- int totalByteLength = sizeof(int) + timeSeriesByteLength + dataSeriesByteLength;
-
-
- byte[] result = new byte[totalByteLength];
- offset = 0;
-
- offset += LittleEndian.CopyBytes(m_samples, result, offset);
-
- List uncompressedIndexes = timeSeries
- .Select((obj, Index) => new { obj.Compressed, Index })
- .Where(obj => !obj.Compressed)
- .Select(obj => obj.Index)
- .ToList();
-
- for (int i = 0; i < uncompressedIndexes.Count; i++)
- {
- int index = uncompressedIndexes[i];
- int nextIndex = (i + 1 < uncompressedIndexes.Count) ? uncompressedIndexes[i + 1] : timeSeries.Count;
-
- offset += LittleEndian.CopyBytes(nextIndex - index, result, offset);
- offset += LittleEndian.CopyBytes(timeSeries[index].Time, result, offset);
-
- for (int j = index + 1; j < nextIndex; j++)
- offset += LittleEndian.CopyBytes((ushort)timeSeries[j].Time, result, offset);
- }
-
- const ushort NaNValue = ushort.MaxValue;
- const ushort MaxCompressedValue = ushort.MaxValue - 1;
- double range = series.Select(item => item.Value).Max() - series.Select(item => item.Value).Min();
- double decompressionOffset = series.Select(item => item.Value).Min();
- double decompressionScale = range / MaxCompressedValue;
- double compressionScale = (decompressionScale != 0.0D) ? 1.0D / decompressionScale : 0.0D;
-
- offset += LittleEndian.CopyBytes(seriesID, result, offset);
- offset += LittleEndian.CopyBytes(decompressionOffset, result, offset);
- offset += LittleEndian.CopyBytes(decompressionScale, result, offset);
-
- foreach (DataPoint dataPoint in series)
- {
- ushort compressedValue = (ushort)Math.Round((dataPoint.Value - decompressionOffset) * compressionScale);
-
- if (compressedValue == NaNValue)
- compressedValue--;
-
- if (double.IsNaN(dataPoint.Value))
- compressedValue = NaNValue;
-
- offset += LittleEndian.CopyBytes(compressedValue, result, offset);
- }
-
- byte[] returnArray = GZipStream.CompressBuffer(result);
- returnArray[0] = 0x44;
- returnArray[1] = 0x33;
-
- return returnArray;
-
- }
- #endregion
- }
-
- public class FaultCurveStatistic
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int FaultCurveID { get; set; }
-
- public int FaultNumber { get; set; }
-
- public double Maximum { get; set; }
-
- public double Minimum { get; set; }
-
- public double Average { get; set; }
-
- public double StandardDeviation { get; set; }
- }
-}
diff --git a/Libraries/openXDA.Model/Events/RelayPerformance.cs b/Libraries/openXDA.Model/Events/RelayPerformance.cs
deleted file mode 100644
index 4950235e..00000000
--- a/Libraries/openXDA.Model/Events/RelayPerformance.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//******************************************************************************************************
-// RelayPerformance.cs - Gbtc
-//
-// Copyright © 2019, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
-// file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 07/10/2019 - Christoph Lackner
-// Generated original version of source code.
-// 08/20/2021 - Christoph Lackner
-// Added additional Trip Coil Curve points.
-//
-//******************************************************************************************************
-
-using System.Data;
-using Gemstone.Data;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- public class RelayPerformance
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
- public int EventID { get; set; }
- public int ChannelID { get; set; }
- public double? Imax1 { get; set; }
- public int? Tmax1 { get; set; }
- public double? Imax2 { get; set; }
- public int? TplungerLatch { get; set; }
- public double IplungerLatch { get; set; }
- public double? Idrop { get; set; }
- public int? TiDrop { get; set; }
- public int? Tend { get; set; }
-
- [FieldDataType(DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime? TripInitiate { get; set; }
- public int? TripTime { get; set; }
- public int? PickupTime { get; set; }
- public double? TripTimeCurrent { get; set;}
- public double? PickupTimeCurrent { get; set; }
- public double? TripCoilCondition { get; set; }
- public int TripCoilConditionTime { get; set; }
- public int? ExtinctionTimeA { get; set; }
- public int? ExtinctionTimeB { get; set; }
- public int? ExtinctionTimeC { get; set; }
- public double? I2CA { get; set; }
- public double? I2CB { get; set; }
- public double? I2CC { get; set; }
-
- }
-}
diff --git a/Libraries/openXDA.Model/Files/DataFile.cs b/Libraries/openXDA.Model/Files/DataFile.cs
deleted file mode 100644
index 10b9d4b5..00000000
--- a/Libraries/openXDA.Model/Files/DataFile.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-//******************************************************************************************************
-// DataFile.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using System.Text;
-using Gemstone.Data.Model;
-using Gemstone.IO.Checksums;
-using Newtonsoft.Json;
-
-namespace openXDA.Model
-{
- [Serializable]
- public class DataFile
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int FileGroupID { get; set; }
-
- public string FilePath { get; set; }
-
- public int FilePathHash { get; set; }
-
- public long FileSize { get; set; }
-
- public DateTime CreationTime { get; set; }
-
- public DateTime LastWriteTime { get; set; }
-
- public DateTime LastAccessTime { get; set; }
-
- [NonRecordField]
- [JsonIgnore]
- public FileBlob FileBlob { get; set; }
-
- public static int GetHash(string filePath)
- {
- Encoding utf8 = new UTF8Encoding(false);
- byte[] pathData = utf8.GetBytes(filePath);
- return unchecked((int)Crc32.Compute(pathData, 0, pathData.Length));
- }
- }
-
- [TableName("DataFile")]
- public class DataFileDb : DataFile { }
-
- public static partial class TableOperationsExtensions
- {
- public static DataFile QueryDataFile(this TableOperations dataFileTable, string filePath)
- {
- int hashCode = DataFile.GetHash(filePath);
- DataFile dataFile = QueryDataFile(dataFileTable, filePath, hashCode);
-
- if (dataFile != null)
- return dataFile;
-
- int legacyHashCode = filePath.GetHashCode();
- dataFile = QueryDataFile(dataFileTable, filePath, legacyHashCode);
-
- if (dataFile == null)
- return null;
-
- dataFile.FilePathHash = hashCode;
- dataFileTable.UpdateRecord(dataFile);
- return dataFile;
- }
-
- private static DataFile QueryDataFile(TableOperations dataFileTable, string filePath, int hashCode)
- {
- IEnumerable dataFiles = dataFileTable.QueryRecordsWhere("FilePathHash = {0}", hashCode);
- return dataFiles.FirstOrDefault(dataFile => dataFile.FilePath == filePath);
- }
- }
-}
diff --git a/Libraries/openXDA.Model/Files/FileBlob.cs b/Libraries/openXDA.Model/Files/FileBlob.cs
deleted file mode 100644
index 00beeef8..00000000
--- a/Libraries/openXDA.Model/Files/FileBlob.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-//******************************************************************************************************
-// FileBlob.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [Serializable]
- public class FileBlob
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int DataFileID { get; set; }
-
- public byte[] Blob { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Libraries/openXDA.Model/Files/FileGroup.cs b/Libraries/openXDA.Model/Files/FileGroup.cs
deleted file mode 100644
index d6c50ab2..00000000
--- a/Libraries/openXDA.Model/Files/FileGroup.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-//******************************************************************************************************
-// FileGroup.cs - Gbtc
-//
-// Copyright © 2017, Grid Protection Alliance. All Rights Reserved.
-//
-// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
-// the NOTICE file distributed with this work for additional information regarding copyright ownership.
-// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
-// not use this file except in compliance with the License. You may obtain a copy of the License at:
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless agreed to in writing, the subject software distributed under the License is distributed on an
-// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
-// License for the specific language governing permissions and limitations.
-//
-// Code Modification History:
-// ----------------------------------------------------------------------------------------------------
-// 08/29/2017 - Billy Ernest
-// Generated original version of source code.
-//
-//******************************************************************************************************
-
-using Gemstone.Data;
-using Gemstone.Data.Model;
-
-namespace openXDA.Model
-{
- [Serializable]
- public class FileGroup
- {
- [PrimaryKey(true)]
- public int ID { get; set; }
-
- public int MeterID { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime DataStartTime { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime DataEndTime { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime ProcessingStartTime { get; set; }
-
- [FieldDataType(System.Data.DbType.DateTime2, DatabaseType.SQLServer)]
- public DateTime ProcessingEndTime { get; set; }
-
- public int ProcessingVersion { get; set; }
-
- public int ProcessingStatus { get; set; }
-
- [NonRecordField]
- public List DataFiles { get; set; } = new List();
-
- public void AddFieldValue(AdoDataConnection connection, string name, string value, string description = null)
- {
- TableOperations fileGroupFieldTable = new TableOperations(connection);
- FileGroupField fileGroupField = fileGroupFieldTable.GetOrAdd(name, description);
-
- TableOperations