Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Source/Applications/SOEService/Configuration/SystemSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ public class SystemSettings
private double m_systemFrequency;
private double m_maxVoltage;
private double m_maxCurrent;
private string m_soeSystemName;

private string m_lengthUnits;
private double m_comtradeMinWaitTime;
private int m_processingThreadCount;
private Guid m_fileProcessorID;
private FileEnumerationStrategy m_fileWatcherEnumerationStrategy;
private int m_fileWatcherMaxFragmentation;
private int m_fileWatcherInternalThreadCount;
private int m_fileWatcherBufferSize;
private string m_fileShares;
Expand Down Expand Up @@ -414,6 +414,24 @@ public string LengthUnits
}
}

/// <summary>
/// Gets or sets the name of the system to which
/// SOE logic will be applied.
/// </summary>
[Setting]
[DefaultValue("12.5")]
public string SOESystemName
{
get
{
return m_soeSystemName;
}
set
{
m_soeSystemName = value;
}
}

/// <summary>
/// Gets or sets the minimum amount of time to wait for additional data
/// files after the system detects the existence of a .D00 COMTRADE file.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
WITH SOELog1 AS
(
SELECT
EventID,
ChannelName,
CONCAT(Circuit, '-', DeviceName, '.', ChannelName) SensorName,
MeasurementTime,
ColorIndexID
FROM SOELog
),
SOELog2 AS
(
SELECT
SOE.ID SOE_ID,
SOELog.EventID,
SOELog.ChannelName,
SOELog.SensorName,
SOE.StartTime SOETime,
SOELog.MeasurementTime,
SOELog.ColorIndexID
FROM
SOELog1 SOELog JOIN
Event ON SOELog.EventID = Event.ID JOIN
SOEIncident ON SOEIncident.IncidentID = Event.IncidentID JOIN
SOE ON SOEIncident.SOEID = SOE.ID
),
Sensor AS
(
SELECT DISTINCT
SOE_ID,
SensorName Name,
ChannelName
FROM SOELog2
),
SOETimeSlot AS
(
SELECT
SOE_ID,
SOETime,
DATEADD(MILLISECOND, -10, MIN(MeasurementTime)) MeasurementTime
FROM SOELog2
GROUP BY SOE_ID, SOETime
UNION ALL

SELECT
SOE_ID,
SOETime,
DATEADD(MILLISECOND, 10, MAX(MeasurementTime)) MeasurementTime
FROM SOELog2
GROUP BY SOE_ID, SOETime
UNION ALL

SELECT DISTINCT
SOE_ID,
SOETime,
MeasurementTime
FROM SOELog2
),
SOELog3 AS
(
SELECT
SOETimeSlot.SOE_ID,
COALESCE(SOELog.EventID, -1) EventID,
Sensor.ChannelName,
Sensor.Name SensorName,
SOETimeSlot.SOETime,
LAG(SOETimeSlot.MeasurementTime) OVER(PARTITION BY SOETimeSlot.SOE_ID ORDER BY SOETimeSlot.MeasurementTime) PreviousMeasurementTime,
SOETimeSlot.MeasurementTime,
COALESCE(SOELog.ColorIndexID, 0) ColorIndexID
FROM
Sensor JOIN
SOETimeSlot ON Sensor.SOE_ID = SOETimeSlot.SOE_ID LEFT OUTER JOIN
SOELog2 SOELog ON
Sensor.Name = SOELog.SensorName AND
SOETimeSlot.SOE_ID = SOELog.SOE_ID AND
SOETimeSlot.MeasurementTime = SOELog.MeasurementTime
),
SOELog4 AS
(
SELECT
SOE_ID,
EventID,
ChannelName,
SensorName,
SOETime,
MIN(PreviousMeasurementTime) OVER(PARTITION BY SOE_ID, MeasurementTime) PreviousMeasurementTime,
MeasurementTime,
ColorIndexID
FROM SOELog3
)
INSERT INTO SOEDataPoint
(
SOE_ID,
TSx,
TSxUnits,
EventID,
NLTDataTypeID,
SensorTypeID,
SensorName,
SensorOrder,
TimeSlot,
Time,
Value,
ElapsMS,
ElapsSEC,
CycleNum,
TimeGap,
MapDisplay
)
SELECT
SOE_ID,
1 TSx,
'mSec' TSxUnits,
EventID,
1 NLTDataTypeID,
CASE WHEN ChannelName LIKE '%I123%'
THEN 2
ELSE 1
END SensorTypeID,
SensorName,
DENSE_RANK() OVER(PARTITION BY SOE_ID ORDER BY SensorName) SensorOrder,
DENSE_RANK() OVER(PARTITION BY SOE_ID ORDER BY MeasurementTime) TimeSlot,
MeasurementTime Time,
ColorIndexID Value,
DATEDIFF(MILLISECOND, SOETime, MeasurementTime) ElapsMS,
DATEDIFF(SECOND, SOETime, MeasurementTime) ElapsSEC,
DATEDIFF(MILLISECOND, SOETime, MeasurementTime) * 60.0 / 1000.0 CycleNum,
COALESCE(
DATEDIFF(MILLISECOND, PreviousMeasurementTime, MeasurementTime),
0) TimeGap,
CASE WHEN ChannelName LIKE '%I123%'
THEN 1
ELSE 0
END MapDisplay
FROM SOELog4
WHERE SOE_ID = {0}
ORDER BY TimeSlot, SensorOrder
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,49 @@
//
//******************************************************************************************************

using GSF.Data;
using GSF.Data.Model;
using SOE.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web.Http;
using System.IO;
using GSF.Data;
using GSF.Data.Model;
using SOE.Model;
using DbSOE = SOE.Model.SOE;
using AnalyticModel = SOE.Model.MATLABAnalytic;
using SOE.MATLAB;
using SOE.Model.Events;

namespace SOEService.Controllers
{
[RoutePrefix("api/SOE")]
public class SOEController: ApiController
{

[HttpGet, Route("{id:int}/{status}")]
public IHttpActionResult ChangeStatus(int id, string status)
{
try
{
using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
{
int record = connection.ExecuteNonQuery("UPDATE SOE SET Status={0} WHERE ID = {1}", status, id);
AnalyticModel makeReplay = new TableOperations<AnalyticModel>(connection).QueryRecordWhere("MethodName = {0}", "MakeReplay");
string soeLogPath = connection.ExecuteScalar<string>("SELECT Value FROM SETTING WHERE Name = 'SOELogPath'");
string replayPath = connection.ExecuteScalar<string>("SELECT Value FROM SETTING WHERE Name = 'ReplayPath'");
connection.ExecuteNonQuery("DELETE FROM SOEDataPoint WHERE SOE_ID = {0}", id);

SOE.MATLAB.MATLABAnalytic analytic = ToAnalytic(makeReplay);
List<MATLABAnalyticSettingField> settings = new List<MATLABAnalyticSettingField>
if (status == "Complete")
{
new MATLABAnalyticSettingField("SOELogPath", soeLogPath),
new MATLABAnalyticSettingField("SOE_ID", id),
new MATLABAnalyticSettingField("ReplayPath", replayPath)
};
analytic.Execute(settings);
ProcessReplayResult(replayPath);
string makeReplayScript = new Func<string>(() =>
{
const string ResourceName = "AggregateWaveformViewBySOE.MakeReplay.sql";
using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(typeof(SOEController), ResourceName))
using (TextReader resourceReader = new StreamReader(resourceStream))
{
return resourceReader.ReadToEnd();
}
})();

connection.ExecuteNonQuery(makeReplayScript, id);
}

int record = connection.ExecuteNonQuery("UPDATE SOE SET Status={0} WHERE ID = {1}", status, id);
return Ok(record);
}
}
Expand Down Expand Up @@ -236,40 +237,36 @@ public IHttpActionResult GetOtherDevices(int id, string startTime, string endTim
DataTable record = connection.RetrieveData(@"
SELECT
Incident.ID as IncidentID,
System.Name as System,
Circuit.Name as PrefCkt,
AltCircuit.Name as AltCkt,
Meter.Name as Device,
IncidentAttribute.FaultType,
COUNT(DISTINCT Event.ID) as Waveforms
Circuit.Name as PrefCkt,
AltCircuit.Name as AltCkt,
Meter.Name as Device,
IncidentAttribute.FaultType,
COUNT(DISTINCT Event.ID) as Waveforms
FROM
Incident JOIN
Event ON Event.IncidentID = Incident.ID JOIN
IncidentAttribute ON Incident.ID = IncidentAttribute.IncidentID JOIN
Meter ON Incident.MeterID = Meter.ID JOIN
Circuit ON Meter.CircuitID = Circuit.ID JOIN
System ON Circuit.SystemID = System.ID LEFT JOIN
Meter AS AltParent ON AltParent.ID = Meter.ParentAlternateID LEFT JOIN
Circuit AS AltCircuit ON AltCircuit.ID = AltParent.CircuitID
Incident JOIN
Event ON Event.IncidentID = Incident.ID JOIN
IncidentAttribute ON Incident.ID = IncidentAttribute.IncidentID JOIN
Meter ON Incident.MeterID = Meter.ID JOIN
Circuit ON Meter.CircuitID = Circuit.ID JOIN
System ON Circuit.SystemID = System.ID LEFT OUTER JOIN
Meter AS AltParent ON AltParent.ID = Meter.ParentAlternateID LEFT OUTER JOIN
Circuit AS AltCircuit ON AltCircuit.ID = AltParent.CircuitID LEFT OUTER JOIN
Setting SOESystemNameSetting ON SOESystemNameSetting.Name = 'SOESystemName'
WHERE
Incident.ID NOT IN (
SELECT
SOEIncident.IncidentID
FROM
SOEIncident
WHERE
SOEIncident.SOEID = {0}

) AND
Incident.StartTime >= {1} AND
Incident.EndTime <= {2}
System.Name = SOESystemNameSetting.Value AND
Incident.ID NOT IN (
SELECT SOEIncident.IncidentID
FROM SOEIncident
WHERE SOEIncident.SOEID = {0}
) AND
Incident.StartTime >= {1} AND
Incident.EndTime <= {2}
GROUP BY
Incident.ID,
System.Name,
Circuit.Name,
AltCircuit.Name,
Meter.Name,
IncidentAttribute.FaultType
Incident.ID,
Circuit.Name,
AltCircuit.Name,
Meter.Name,
IncidentAttribute.FaultType
", id, startTime, endTime);
return Ok(record);
}
Expand Down Expand Up @@ -330,72 +327,5 @@ public IHttpActionResult PostNewSOE( [FromBody] PostData postData)
return BadRequest(ex.Message);
}
}
private SOE.MATLAB.MATLABAnalytic ToAnalytic(AnalyticModel model)
{
string assemblyName = model.AssemblyName;
string methodName = model.MethodName;
MATLABAnalysisFunctionInvokerFactory invokerFactory = AnalysisFunctionFactory.GetAnalysisFunctionInvokerFactory(assemblyName, methodName);
return new SOE.MATLAB.MATLABAnalytic(invokerFactory);
}

private static MATLABAnalysisFunctionFactory AnalysisFunctionFactory { get; } = new MATLABAnalysisFunctionFactory();

private void ProcessReplayResult(string replayPath)
{
using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
{
string[] soeLines = File.ReadAllLines(replayPath);
for (int i = 0; i < soeLines.Length; i++)
{
string[] splitLine = soeLines[i].Split("\t".ToCharArray());
int soeID = Int32.Parse(splitLine[0]);
int TSx = Int32.Parse(splitLine[1]);
string TSxUnits = splitLine[2];
int eventID = Int32.Parse(splitLine[3]);
int nltDataTypeID = Int32.Parse(splitLine[4]);
int sensorTypeID = Int32.Parse(splitLine[5]);
string sensorName = splitLine[6];
int sensorOrder = Int32.Parse(splitLine[7]);
int timeSlot = Int32.Parse(splitLine[8]);
DateTime time = DateTime.Parse(splitLine[9]);
int colorMapIndex = Int32.Parse(splitLine[10]);
int elapsMS = Int32.Parse(splitLine[11]);
int elapsSEC = Int32.Parse(splitLine[12]);
int cyclesNum = Int32.Parse(splitLine[13]);
int timeGap = Int32.Parse(splitLine[14]);
int mapDisplay = Int32.Parse(splitLine[15]);

SOEDataPoint soeDataPoint = new SOEDataPoint
{
EventID = eventID,
SOE_ID = soeID,
TSx = TSx,
TSxUnits = TSxUnits,
NLTDataTypeID = nltDataTypeID,
SensorTypeID = sensorTypeID,
SensorName = sensorName,
SensorOrder = sensorOrder,
TimeSlot = timeSlot,
Time = time,
Value = colorMapIndex,
ElapsMS = elapsMS,
ElapsSEC = elapsSEC,
CycleNum = cyclesNum,
TimeGap = timeGap,
MapDisplay = mapDisplay,
};

if (eventID != -1)
{
SOEDataPoint exisitingSOEDataPoint = new TableOperations<SOEDataPoint>(connection).QueryRecordWhere("Time = {0} AND SensorName = {1} and EventID = {2} AND SOE_ID = {3} AND ElapsMS = {4} AND TimeGap = {5}", time, sensorName, eventID, soeID, elapsMS, timeGap);
if (exisitingSOEDataPoint == null)
{
new TableOperations<SOEDataPoint>(connection).AddNewOrUpdateRecord(soeDataPoint);
}
}
}
}
}

}
}
Loading