mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-02 07:15:31 +00:00
Added temperature offset parameters to all HDD temperature sensors. Fixed issue 271.
This commit is contained in:
@@ -169,7 +169,8 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
if (!sensorTypeAndChannels.Contains(pair)) {
|
if (!sensorTypeAndChannels.Contains(pair)) {
|
||||||
Sensor sensor = new Sensor(attribute.Name,
|
Sensor sensor = new Sensor(attribute.Name,
|
||||||
attribute.SensorChannel, attribute.DefaultHiddenSensor,
|
attribute.SensorChannel, attribute.DefaultHiddenSensor,
|
||||||
attribute.SensorType.Value, this, null, settings);
|
attribute.SensorType.Value, this, attribute.ParameterDescriptions,
|
||||||
|
settings);
|
||||||
|
|
||||||
sensors.Add(attribute, sensor);
|
sensors.Add(attribute, sensor);
|
||||||
ActivateSensor(sensor);
|
ActivateSensor(sensor);
|
||||||
@@ -199,7 +200,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
foreach (DriveAttributeValue value in values) {
|
foreach (DriveAttributeValue value in values) {
|
||||||
if (value.Identifier == attribute.Identifier) {
|
if (value.Identifier == attribute.Identifier) {
|
||||||
Sensor sensor = keyValuePair.Value;
|
Sensor sensor = keyValuePair.Value;
|
||||||
sensor.Value = attribute.ConvertValue(value);
|
sensor.Value = attribute.ConvertValue(value, sensor.Parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,7 +262,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
if (a.Identifier == value.Identifier) {
|
if (a.Identifier == value.Identifier) {
|
||||||
description = a.Name;
|
description = a.Name;
|
||||||
if (a.HasRawValueConversion | a.SensorType.HasValue)
|
if (a.HasRawValueConversion | a.SensorType.HasValue)
|
||||||
physical = a.ConvertValue(value);
|
physical = a.ConvertValue(value, null);
|
||||||
else
|
else
|
||||||
physical = null;
|
physical = null;
|
||||||
}
|
}
|
||||||
@@ -295,7 +296,9 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
return r.ToString();
|
return r.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static float RawToInt(byte[] raw, byte value) {
|
protected static float RawToInt(byte[] raw, byte value,
|
||||||
|
IReadOnlyArray<IParameter> parameters)
|
||||||
|
{
|
||||||
return (raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0];
|
return (raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using OpenHardwareMonitor.Collections;
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.HDD {
|
namespace OpenHardwareMonitor.Hardware.HDD {
|
||||||
|
|
||||||
@@ -82,9 +83,19 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
new SmartAttribute(0xFE, SmartNames.FreeFallProtection),
|
new SmartAttribute(0xFE, SmartNames.FreeFallProtection),
|
||||||
|
|
||||||
new SmartAttribute(0xC2, SmartNames.Temperature,
|
new SmartAttribute(0xC2, SmartNames.Temperature,
|
||||||
(byte[] r, byte v) => { return r[0]; }, SensorType.Temperature, 0),
|
(byte[] r, byte v, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return r[0] + (p == null ? 0 : p[0].Value); },
|
||||||
|
SensorType.Temperature, 0, false,
|
||||||
|
new[] { new ParameterDescription("Offset [°C]",
|
||||||
|
"Temperature offset of the thermal sensor.\n" +
|
||||||
|
"Temperature = Value + Offset.", 0) }),
|
||||||
new SmartAttribute(0xE7, SmartNames.Temperature,
|
new SmartAttribute(0xE7, SmartNames.Temperature,
|
||||||
(byte[] r, byte v) => { return r[0]; }, SensorType.Temperature, 0),
|
(byte[] r, byte v, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return r[0] + (p == null ? 0 : p[0].Value); },
|
||||||
|
SensorType.Temperature, 0, false,
|
||||||
|
new[] { new ParameterDescription("Offset [°C]",
|
||||||
|
"Temperature offset of the thermal sensor.\n" +
|
||||||
|
"Temperature = Value + Offset.", 0) }),
|
||||||
new SmartAttribute(0xBE, SmartNames.TemperatureDifferenceFrom100,
|
new SmartAttribute(0xBE, SmartNames.TemperatureDifferenceFrom100,
|
||||||
null, SensorType.Temperature, 0)
|
null, SensorType.Temperature, 0)
|
||||||
};
|
};
|
||||||
|
@@ -10,8 +10,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.HDD {
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using OpenHardwareMonitor.Collections;
|
||||||
|
|
||||||
|
namespace OpenHardwareMonitor.Hardware.HDD {
|
||||||
|
|
||||||
[NamePrefix("INTEL SSD"),
|
[NamePrefix("INTEL SSD"),
|
||||||
RequireSmart(0xE1), RequireSmart(0xE8), RequireSmart(0xE9)]
|
RequireSmart(0xE1), RequireSmart(0xE8), RequireSmart(0xE9)]
|
||||||
@@ -32,16 +34,19 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
new SmartAttribute(0xB8, SmartNames.EndToEndError),
|
new SmartAttribute(0xB8, SmartNames.EndToEndError),
|
||||||
new SmartAttribute(0xC0, SmartNames.UnsafeShutdownCount),
|
new SmartAttribute(0xC0, SmartNames.UnsafeShutdownCount),
|
||||||
new SmartAttribute(0xE1, SmartNames.HostWrites,
|
new SmartAttribute(0xE1, SmartNames.HostWrites,
|
||||||
(byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
|
(byte[] r, byte v, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return RawToInt(r, v, p) / 0x20; },
|
||||||
SensorType.Data, 0),
|
SensorType.Data, 0),
|
||||||
new SmartAttribute(0xE8, SmartNames.RemainingLife,
|
new SmartAttribute(0xE8, SmartNames.RemainingLife,
|
||||||
null, SensorType.Level, 0),
|
null, SensorType.Level, 0),
|
||||||
new SmartAttribute(0xE9, SmartNames.MediaWearOutIndicator),
|
new SmartAttribute(0xE9, SmartNames.MediaWearOutIndicator),
|
||||||
new SmartAttribute(0xF1, SmartNames.HostWrites,
|
new SmartAttribute(0xF1, SmartNames.HostWrites,
|
||||||
(byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
|
(byte[] r, byte v, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return RawToInt(r, v, p) / 0x20; },
|
||||||
SensorType.Data, 0),
|
SensorType.Data, 0),
|
||||||
new SmartAttribute(0xF2, SmartNames.HostReads,
|
new SmartAttribute(0xF2, SmartNames.HostReads,
|
||||||
(byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
|
(byte[] r, byte v, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return RawToInt(r, v, p) / 0x20; },
|
||||||
SensorType.Data, 1),
|
SensorType.Data, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.HDD {
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using OpenHardwareMonitor.Collections;
|
||||||
|
|
||||||
|
namespace OpenHardwareMonitor.Hardware.HDD {
|
||||||
|
|
||||||
[NamePrefix(""), RequireSmart(0xAA), RequireSmart(0xAB), RequireSmart(0xAC),
|
[NamePrefix(""), RequireSmart(0xAA), RequireSmart(0xAB), RequireSmart(0xAC),
|
||||||
RequireSmart(0xAD), RequireSmart(0xAE), RequireSmart(0xCA)]
|
RequireSmart(0xAD), RequireSmart(0xAE), RequireSmart(0xCA)]
|
||||||
@@ -28,7 +30,8 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
new SmartAttribute(0xAD, SmartNames.WearLevelingCount, RawToInt),
|
new SmartAttribute(0xAD, SmartNames.WearLevelingCount, RawToInt),
|
||||||
new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount, RawToInt),
|
new SmartAttribute(0xAE, SmartNames.UnexpectedPowerLossCount, RawToInt),
|
||||||
new SmartAttribute(0xB5, SmartNames.Non4kAlignedAccess,
|
new SmartAttribute(0xB5, SmartNames.Non4kAlignedAccess,
|
||||||
(byte[] raw, byte value) => { return 6e4f * ((raw[5] << 8) | raw[4]); }),
|
(byte[] raw, byte value, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return 6e4f * ((raw[5] << 8) | raw[4]); }),
|
||||||
new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt),
|
new SmartAttribute(0xB7, SmartNames.SataDownshiftErrorCount, RawToInt),
|
||||||
new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt),
|
new SmartAttribute(0xBB, SmartNames.ReportedUncorrectableErrors, RawToInt),
|
||||||
new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt),
|
new SmartAttribute(0xBC, SmartNames.CommandTimeout, RawToInt),
|
||||||
@@ -38,10 +41,12 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
new SmartAttribute(0xC6, SmartNames.OffLineUncorrectableErrorCount, RawToInt),
|
new SmartAttribute(0xC6, SmartNames.OffLineUncorrectableErrorCount, RawToInt),
|
||||||
new SmartAttribute(0xC7, SmartNames.UltraDmaCrcErrorCount, RawToInt),
|
new SmartAttribute(0xC7, SmartNames.UltraDmaCrcErrorCount, RawToInt),
|
||||||
new SmartAttribute(0xCA, SmartNames.RemainingLife,
|
new SmartAttribute(0xCA, SmartNames.RemainingLife,
|
||||||
(byte[] raw, byte value) => { return 100 - RawToInt(raw, value); },
|
(byte[] raw, byte value, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return 100 - RawToInt(raw, value, p); },
|
||||||
SensorType.Level, 0),
|
SensorType.Level, 0),
|
||||||
new SmartAttribute(0xCE, SmartNames.WriteErrorRate,
|
new SmartAttribute(0xCE, SmartNames.WriteErrorRate,
|
||||||
(byte[] raw, byte value) => { return 6e4f * ((raw[1] << 8) | raw[0]); }),
|
(byte[] raw, byte value, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return 6e4f * ((raw[1] << 8) | raw[0]); }),
|
||||||
};
|
};
|
||||||
|
|
||||||
public SSDMicron(ISmart smart, string name, string firmwareRevision,
|
public SSDMicron(ISmart smart, string name, string firmwareRevision,
|
||||||
|
@@ -9,8 +9,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.HDD {
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using OpenHardwareMonitor.Collections;
|
||||||
|
|
||||||
|
namespace OpenHardwareMonitor.Hardware.HDD {
|
||||||
|
|
||||||
[NamePrefix(""), RequireSmart(0xAB), RequireSmart(0xB1)]
|
[NamePrefix(""), RequireSmart(0xAB), RequireSmart(0xB1)]
|
||||||
internal class SSDSandforce : AbstractHarddrive {
|
internal class SSDSandforce : AbstractHarddrive {
|
||||||
@@ -28,8 +30,13 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
new SmartAttribute(0xB5, SmartNames.AlternativeProgramFailCount, RawToInt),
|
new SmartAttribute(0xB5, SmartNames.AlternativeProgramFailCount, RawToInt),
|
||||||
new SmartAttribute(0xB6, SmartNames.AlternativeEraseFailCount, RawToInt),
|
new SmartAttribute(0xB6, SmartNames.AlternativeEraseFailCount, RawToInt),
|
||||||
new SmartAttribute(0xBB, SmartNames.UncorrectableErrorCount, RawToInt),
|
new SmartAttribute(0xBB, SmartNames.UncorrectableErrorCount, RawToInt),
|
||||||
new SmartAttribute(0xC2, SmartNames.Temperature, (byte[] raw, byte value)
|
new SmartAttribute(0xC2, SmartNames.Temperature,
|
||||||
=> { return value; }, SensorType.Temperature, 0, true),
|
(byte[] raw, byte value, IReadOnlyArray<IParameter> p)
|
||||||
|
=> { return value + (p == null ? 0 : p[0].Value); },
|
||||||
|
SensorType.Temperature, 0, true,
|
||||||
|
new[] { new ParameterDescription("Offset [°C]",
|
||||||
|
"Temperature offset of the thermal sensor.\n" +
|
||||||
|
"Temperature = Value + Offset.", 0) }),
|
||||||
new SmartAttribute(0xC3, SmartNames.UnrecoverableEcc),
|
new SmartAttribute(0xC3, SmartNames.UnrecoverableEcc),
|
||||||
new SmartAttribute(0xC4, SmartNames.ReallocationEventCount, RawToInt),
|
new SmartAttribute(0xC4, SmartNames.ReallocationEventCount, RawToInt),
|
||||||
new SmartAttribute(0xE7, SmartNames.RemainingLife, null,
|
new SmartAttribute(0xE7, SmartNames.RemainingLife, null,
|
||||||
@@ -59,10 +66,10 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
float? hostWritesToController = null;
|
float? hostWritesToController = null;
|
||||||
foreach (DriveAttributeValue value in values) {
|
foreach (DriveAttributeValue value in values) {
|
||||||
if (value.Identifier == 0xE9)
|
if (value.Identifier == 0xE9)
|
||||||
controllerWritesToNAND = RawToInt(value.RawValue, value.AttrValue);
|
controllerWritesToNAND = RawToInt(value.RawValue, value.AttrValue, null);
|
||||||
|
|
||||||
if (value.Identifier == 0xEA)
|
if (value.Identifier == 0xEA)
|
||||||
hostWritesToController = RawToInt(value.RawValue, value.AttrValue);
|
hostWritesToController = RawToInt(value.RawValue, value.AttrValue, null);
|
||||||
}
|
}
|
||||||
if (controllerWritesToNAND.HasValue && hostWritesToController.HasValue) {
|
if (controllerWritesToNAND.HasValue && hostWritesToController.HasValue) {
|
||||||
if (hostWritesToController.Value > 0)
|
if (hostWritesToController.Value > 0)
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using OpenHardwareMonitor.Collections;
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.HDD {
|
namespace OpenHardwareMonitor.Hardware.HDD {
|
||||||
internal class SmartAttribute {
|
internal class SmartAttribute {
|
||||||
@@ -49,9 +50,12 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
/// the same sensor channel and type, then a sensor is created only for the
|
/// the same sensor channel and type, then a sensor is created only for the
|
||||||
/// first attribute.</param>
|
/// first attribute.</param>
|
||||||
/// <param name="defaultHiddenSensor">True to hide the sensor initially.</param>
|
/// <param name="defaultHiddenSensor">True to hide the sensor initially.</param>
|
||||||
|
/// <param name="parameterDescriptions">Description for the parameters of the sensor
|
||||||
|
/// (or null).</param>
|
||||||
public SmartAttribute(byte identifier, string name,
|
public SmartAttribute(byte identifier, string name,
|
||||||
RawValueConversion rawValueConversion, SensorType? sensorType,
|
RawValueConversion rawValueConversion, SensorType? sensorType,
|
||||||
int sensorChannel, bool defaultHiddenSensor = false)
|
int sensorChannel, bool defaultHiddenSensor = false,
|
||||||
|
ParameterDescription[] parameterDescriptions = null)
|
||||||
{
|
{
|
||||||
this.Identifier = identifier;
|
this.Identifier = identifier;
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
@@ -59,6 +63,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
this.SensorType = sensorType;
|
this.SensorType = sensorType;
|
||||||
this.SensorChannel = sensorChannel;
|
this.SensorChannel = sensorChannel;
|
||||||
this.DefaultHiddenSensor = defaultHiddenSensor;
|
this.DefaultHiddenSensor = defaultHiddenSensor;
|
||||||
|
this.ParameterDescriptions = parameterDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -74,20 +79,25 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
|||||||
|
|
||||||
public bool DefaultHiddenSensor { get; private set; }
|
public bool DefaultHiddenSensor { get; private set; }
|
||||||
|
|
||||||
|
public ParameterDescription[] ParameterDescriptions { get; private set; }
|
||||||
|
|
||||||
public bool HasRawValueConversion {
|
public bool HasRawValueConversion {
|
||||||
get {
|
get {
|
||||||
return rawValueConversion != null;
|
return rawValueConversion != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float ConvertValue(DriveAttributeValue value) {
|
public float ConvertValue(DriveAttributeValue value,
|
||||||
|
IReadOnlyArray<IParameter> parameters)
|
||||||
|
{
|
||||||
if (rawValueConversion == null) {
|
if (rawValueConversion == null) {
|
||||||
return value.AttrValue;
|
return value.AttrValue;
|
||||||
} else {
|
} else {
|
||||||
return rawValueConversion(value.RawValue, value.AttrValue);
|
return rawValueConversion(value.RawValue, value.AttrValue, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate float RawValueConversion(byte[] rawValue, byte value);
|
public delegate float RawValueConversion(byte[] rawValue, byte value,
|
||||||
|
IReadOnlyArray<IParameter> parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user