Skip to content

Commit

Permalink
-Fix Get-SensorHistory not taking into consideration channel scaling …
Browse files Browse the repository at this point in the history
…multiplication and division values when figuring numeric display value from unknown culture via ConvertUtilities.ToDynamicDouble (Fix #241)

-Fix Get-SensorHistory failing to retry creating format XML after an exception previously occurred during the first generation attempt
  • Loading branch information
lordmilko committed Sep 16, 2021
1 parent e3c737e commit 720b323
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ private void ProcessSensorHistory()
{
IEnumerable<PSObject> records;

//Get the channels in case a Scaling Division was specified on the Channel properties; if so, ConvertUtilities.ToDynamicDouble will explode
//without taking this into consideration
List<Channel> channels = Raw ? null : client.GetChannels(Id);

var average = Average;

if (average == null)
Expand Down Expand Up @@ -216,17 +220,17 @@ private void ProcessSensorHistory()
if (EndDate != null)
{
StreamProvider.ForceStream = true;
records = StreamProvider.StreamResultsWithProgress(parameters, Count, () => GetFormattedRecords(parameters));
records = StreamProvider.StreamResultsWithProgress(parameters, Count, () => GetFormattedRecords(parameters, channels));

if (Count != null)
records = records.Take(Count.Value);
}
else if (ProgressManager.GetRecordsWithVariableProgress)
records = GetResultsWithVariableProgress(() => GetFormattedRecords(parameters));
records = GetResultsWithVariableProgress(() => GetFormattedRecords(parameters, channels));
else if (ProgressManager.GetResultsWithProgress)
records = GetResultsWithProgress(() => GetFormattedRecords(parameters));
records = GetResultsWithProgress(() => GetFormattedRecords(parameters, channels));
else
records = GetFormattedRecords(parameters);
records = GetFormattedRecords(parameters, channels);

WriteList(records);
}
Expand Down Expand Up @@ -257,7 +261,7 @@ private void AdjustCountPeriod(SensorHistoryParameters parameters, int average)
parameters.EndDate = requiredEnd;
}

private IEnumerable<PSObject> GetFormattedRecords(SensorHistoryParameters parameters)
private IEnumerable<PSObject> GetFormattedRecords(SensorHistoryParameters parameters, List<Channel> channels)
{
IEnumerable<SensorHistoryRecord> records;

Expand All @@ -268,7 +272,7 @@ private IEnumerable<PSObject> GetFormattedRecords(SensorHistoryParameters parame
records = StreamProvider.StreamRecords<SensorHistoryRecord>(parameters, null);
}

var formatter = new SensorHistoryFormatter(this);
var formatter = new SensorHistoryFormatter(this, channels);

return formatter.Format(records, EndDate != null, Count);
}
Expand Down
2 changes: 2 additions & 0 deletions src/PrtgAPI.PowerShell/PowerShell/FormatGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class TypeNameRecord

internal int Impurity { get; set; }

internal bool XmlGenerated { get; set; }

public TypeNameRecord(int index, int impurity)
{
Index = index;
Expand Down
48 changes: 38 additions & 10 deletions src/PrtgAPI.PowerShell/PowerShell/SensorHistoryFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ class SensorHistoryFormatter
private int readCount;

private GetSensorHistory cmdlet;
private List<Channel> channels;

private bool xmlLoaded = false;

private static Dictionary<string, TypeNameRecord> typeNameMap = new Dictionary<string, TypeNameRecord>();
private static int mapCount;

public SensorHistoryFormatter(GetSensorHistory cmdlet)
public SensorHistoryFormatter(GetSensorHistory cmdlet, List<Channel> channels)
{
this.cmdlet = cmdlet;
this.channels = channels;
}

private PSObject PrepareObject(SensorHistoryRecord data, bool isNew = false)
Expand Down Expand Up @@ -123,7 +125,7 @@ private void GetChannelUnitMap(List<SensorHistoryRecord> firstResponse)
}
else
{
if (unitValue.ToCharArray().Count(c => c == ' ') <= 1 && !IsTimeSpan(unitValueChannel))
if (unitValue.ToCharArray().Count(c => c == ' ') <= 1 && !IsTimeSpan(unitValueChannel, unitValueChannel.Value))
{
unitValue = unitValue.Substring(unitValue.IndexOf(' ') + 1).Trim();
}
Expand All @@ -138,7 +140,7 @@ private void GetChannelUnitMap(List<SensorHistoryRecord> firstResponse)
}
}

private bool IsTimeSpan(ChannelHistoryRecord record)
private bool IsTimeSpan(ChannelHistoryRecord record, double? rawValue)
{
if (record.DisplayValue != null)
{
Expand All @@ -164,15 +166,15 @@ private bool IsTimeSpan(ChannelHistoryRecord record)
}

//With large units (such as days) the display value will almost never be the same as the raw value
if (total == record.Value)
if (total == rawValue)
return true;

var largestUnit = GetSecondsForTimeSpanUnit(split[1]);

//If we elapse the next hour or day, etc and it turns out we're bigger,
//then perhaps we are in fact a TimeSpan. Otherwise, whatever our units mean they don't
//relate to TimeSpans
if(total < record.Value && total + largestUnit > record.Value)
if(total < rawValue && total + largestUnit > rawValue)
return true;
}
}
Expand Down Expand Up @@ -264,7 +266,7 @@ private PSObject CreateObject(SensorHistoryRecord date)

foreach (var channel in date.ChannelRecords)
{
if (!cmdlet.Raw && (channelUnitMap[channel.Name] != null || IsTimeSpan(channel)))
if (!cmdlet.Raw && (channelUnitMap[channel.Name] != null || IsTimeSpan(channel, channel.Value)))
{
//Implicitly not Raw if we have a channel unit
var value = GetChannelValue(channel);
Expand All @@ -290,8 +292,12 @@ private object GetChannelValue(ChannelHistoryRecord channel)

if (channel.DisplayValue != null)
{
if (channel.Value != null && IsTimeSpan(channel))
return TimeSpan.FromSeconds(channel.Value.Value);
var rawValue = channel.Value;

rawValue = ApplyScaling(channel.ChannelId, rawValue);

if (rawValue != null && IsTimeSpan(channel, rawValue))
return TimeSpan.FromSeconds(rawValue.Value);

if (IsValueLookup(channel.DisplayValue))
return channel.DisplayValue;
Expand All @@ -315,12 +321,31 @@ private object GetChannelValue(ChannelHistoryRecord channel)
valueStr = channel.DisplayValue.Substring(first, second - first);
}

value = ConvertUtilities.ToDynamicDouble(valueStr, channel.Value);
value = ConvertUtilities.ToDynamicDouble(valueStr, rawValue);
}

return value;
}

private double? ApplyScaling(int channelId, double? rawValue)
{
if (rawValue == null)
return null;

var match = channels.FirstOrDefault(c => c.Id == channelId);

if (match != null)
{
if (match.ScalingDivision != null)
rawValue /= match.ScalingDivision;

if (match.ScalingMultiplication != null)
rawValue *= match.ScalingMultiplication;
}

return rawValue;
}

private void LoadFormat(PSObject obj, bool isNew)
{
var columns = obj.Properties.Where(p => p is PSNoteProperty).Select(n => n.Name).ToList();
Expand All @@ -331,8 +356,11 @@ private void LoadFormat(PSObject obj, bool isNew)
var index = tuples.IndexOf(coverage);
tuples[index] = Tuple.Create(coverage.Item1, $"{coverage.Item1}(%)");

if (isNew)
if (isNew || !typeNameRecord.XmlGenerated)
{
FormatGenerator.Generate(typeNameRecord.TypeName, tuples, typeNameRecord.Index);
typeNameRecord.XmlGenerated = true;
}

FormatGenerator.LoadXml(cmdlet);
}
Expand Down
Loading

0 comments on commit 720b323

Please sign in to comment.