diff --git a/Source/Libraries/Adapters/PowerCalculations/PhasorAddition.cs b/Source/Libraries/Adapters/PowerCalculations/PhasorAddition.cs
new file mode 100644
index 0000000000..4aa79c9507
--- /dev/null
+++ b/Source/Libraries/Adapters/PowerCalculations/PhasorAddition.cs
@@ -0,0 +1,247 @@
+//******************************************************************************************************
+// PhasorAddition.cs - Gbtc
+//
+// Copyright © 2012, 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://www.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/14/2025 - C. Lackner
+// Generated original version of source code.
+//
+//******************************************************************************************************
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using GSF;
+using GSF.Collections;
+using GSF.TimeSeries;
+using GSF.TimeSeries.Adapters;
+using GSF.Units;
+using GSF.Units.EE;
+using PhasorProtocolAdapters;
+
+namespace PowerCalculations;
+
+///
+/// Calculates sum or difference between two voltages or currents.
+///
+[Description("Phasor Addition: Computes the sum or difference between two phasors")]
+public class PhasorAddition : CalculatedMeasurementBase
+{
+ #region [ Members ]
+
+ // Constants
+ private const double Rad120 = 2.0D * Math.PI / 3.0D;
+ private const bool DefaultDifference = false;
+ // Fields
+ private MeasurementKey[] m_angles;
+ private MeasurementKey[] m_magnitudes;
+ private double m_lastMagnitudeResult;
+ private Angle m_lastAngleResult;
+
+ ///
+ /// Defines the output measurements for the .
+ ///
+ ///
+ /// One output measurement should be defined for each enumeration value, in order:
+ ///
+ public enum Output
+ {
+ ///
+ /// Magnitude measurement.
+ ///
+ Magnitude,
+ ///
+ /// Angle measurement.
+ ///
+ Phase
+ }
+
+ #endregion
+
+ #region [ Properties ]
+
+ ///
+ /// Gets or sets flag that determines if the second phasor should be subtracted.
+ ///
+ [ConnectionStringParameter]
+ [Description("Flag that determines if the second phasor should be subtracted.")]
+ [DefaultValue(DefaultDifference)]
+ public bool Difference { get; set; } = DefaultDifference;
+
+ ///
+ /// Gets the flag indicating if this adapter supports temporal processing.
+ ///
+ public override bool SupportsTemporalProcessing => true;
+
+ ///
+ /// Returns the detailed status of the .
+ ///
+ public override string Status
+ {
+ get
+ {
+ StringBuilder status = new();
+
+ status.Append(base.Status);
+
+ status.AppendLine($" Phasor 1 magnitude: {m_magnitudes[0]}");
+ status.AppendLine($" Phasor 2 magnitude: {m_magnitudes[1]}");
+ status.AppendLine($" Phase 1 angle: {m_angles[0]}");
+ status.AppendLine($" Phase 2 angle: {m_angles[1]}");
+ status.AppendLine($" Difference: {Difference}");
+
+ status.AppendLine();
+ status.Append(" Last calculated angle: ");
+
+ status.Append(!double.IsNaN(m_lastAngleResult) ? $"{m_lastAngleResult.ToDegrees():0.00}°" : "No values calculated yet...");
+
+ status.AppendLine();
+ status.Append(" Last calculated magnitude: ");
+
+ status.Append(!double.IsNaN(m_lastMagnitudeResult) ? $"{m_lastMagnitudeResult:0.00}" :
+ "No values calculated yet...");
+
+ status.AppendLine();
+ status.AppendLine();
+
+ return status.ToString();
+ }
+ }
+
+ #endregion
+
+ #region [ Methods ]
+
+ ///
+ /// Initializes the .
+ ///
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ Dictionary settings = Settings;
+
+ // Load parameters
+ if (settings.TryGetValue(nameof(Difference), out string setting))
+ Difference = setting.ParseBoolean();
+
+ // Load needed phase angle measurement keys from defined InputMeasurementKeys
+ m_angles = InputMeasurementKeys.Where((_, index) => InputMeasurementKeyTypes[index] == SignalType.VPHA || InputMeasurementKeyTypes[index] == SignalType.IPHA).ToArray();
+
+ if (m_angles.Length != 2)
+ {
+ throw new InvalidOperationException("Exactly 2 angle input measurements are required.");
+ }
+
+ // Load needed phase magnitude measurement keys from defined InputMeasurementKeys
+ m_magnitudes = InputMeasurementKeys.Where((_, index) => InputMeasurementKeyTypes[index] == SignalType.VPHM || InputMeasurementKeyTypes[index] == SignalType.IPHM).ToArray();
+
+ if (m_magnitudes.Length != 2)
+ {
+ throw new InvalidOperationException("Exactly 2 magnitude input measurements are required.");
+ }
+
+
+ // Make sure only these phasor measurements are used as input
+ InputMeasurementKeys = m_angles.Concat(m_magnitudes).ToArray();
+
+ // Validate output measurements
+ if (OutputMeasurements.Length < 2)
+ throw new InvalidOperationException("Not enough output measurements were specified for the phasor addition, expecting measurements for the \"Magnitude\", and \"Angle\" - in this order.");
+
+ m_lastMagnitudeResult = double.NaN;
+ m_lastAngleResult = double.NaN;
+
+ }
+
+ ///
+ /// Publish frame of time-aligned collection of measurement values that arrived within the defined lag time.
+ ///
+ /// Frame of measurements with the same timestamp that arrived within lag time that are ready for processing.
+ /// Index of frame within a second ranging from zero to frames per second - 1.
+ protected override void PublishFrame(IFrame frame, int index)
+ {
+ ComplexNumber result = nanSeq;
+
+ try
+ {
+ ConcurrentDictionary measurements = frame.Measurements;
+ double m1 = 0.0D, a1 = 0.0D, m2 = 0.0D, a2 = 0.0D;
+ bool allInputsReceived = false;
+
+ // Get all needed measurement values from this frame
+ if (measurements.TryGetValue(m_magnitudes[0], out IMeasurement measurement))
+ {
+ // Get first magnitude value
+ m1 = measurement.AdjustedValue;
+
+ if (measurements.TryGetValue(m_angles[0], out measurement))
+ {
+ // Get first angle value
+ a1 = measurement.AdjustedValue;
+
+ if (measurements.TryGetValue(m_magnitudes[1], out measurement))
+ {
+ // Get second magnitude value
+ m2 = measurement.AdjustedValue;
+
+ if (measurements.TryGetValue(m_angles[1], out measurement))
+ {
+ // Get second angle value
+ a2 = measurement.AdjustedValue;
+ }
+ }
+ }
+ }
+
+ if (!allInputsReceived)
+ return;
+
+ ComplexNumber phasor1 = new(Angle.FromDegrees(a1), m1);
+ ComplexNumber phasor2 = new(Angle.FromDegrees(a2), m2);
+
+ if (Difference)
+ result = phasor1 - phasor2;
+ else
+ result = phasor1 + phasor2;
+ }
+ finally
+ {
+ IMeasurement[] outputMeasurements = OutputMeasurements;
+
+ // Provide calculated measurements for external consumption
+ OnNewMeasurements(new IMeasurement[]
+ {
+ Measurement.Clone(outputMeasurements[0], result.Magnitude, frame.Timestamp),
+ Measurement.Clone(outputMeasurements[1], result.Angle.ToDegrees(), frame.Timestamp)
+ });
+ }
+ }
+
+ #endregion
+
+ #region [ Static ]
+
+ // Static Fields
+
+ // a = e^((2/3) * pi * i)
+ private static readonly ComplexNumber nanSeq = new(double.NaN, double.NaN);
+
+ #endregion
+}
\ No newline at end of file
diff --git a/Source/Libraries/Adapters/PowerCalculations/PowerCalculations.csproj b/Source/Libraries/Adapters/PowerCalculations/PowerCalculations.csproj
index faea7b5ab7..fb86af1069 100755
--- a/Source/Libraries/Adapters/PowerCalculations/PowerCalculations.csproj
+++ b/Source/Libraries/Adapters/PowerCalculations/PowerCalculations.csproj
@@ -71,6 +71,7 @@
+