Skip to content

Commit

Permalink
Fix issue with unexpected strings returning 0.
Browse files Browse the repository at this point in the history
Closes #9
  • Loading branch information
aholmes committed Jan 31, 2024
1 parent 920d89c commit 29f5d73
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 37 deletions.
51 changes: 46 additions & 5 deletions hubitat2prom.Tests/TestHubitat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Moq;
using Microsoft.Extensions.Logging;
using hubitat2prom.PrometheusExporter;
using OneOf;

namespace hubitat2prom.Tests;

Expand Down Expand Up @@ -260,12 +261,15 @@ public async Task DeviceDetails_Returns_Dynamic_Device_Attribute_Values()
}

[Theory]
[InlineData(123, 123d)]
[InlineData(123.4, 123.4d)]
[InlineData(123d, null, 123d)]
[InlineData(123.4d, null, 123.4d)]
[InlineData(null, "123", 123d)]
[InlineData(null, "123.4", 123.4d)]
public async Task DeviceMetricsExporter_Returns_Dynamic_Device_Attribute_Values(
double jsonValue, double expectedValue
double? jsonDoubleValue, string jsonStringValue, double expectedValue
)
{
var expectedValueFormatted = jsonDoubleValue.HasValue ? jsonDoubleValue.ToString() : ("\"" + jsonStringValue + "\"");
var httpClientFactory = _getAllDeviceDetailsIHttpClientFactory(
(json) =>
{
Expand All @@ -274,7 +278,7 @@ public async Task DeviceMetricsExporter_Returns_Dynamic_Device_Attribute_Values(
StatusCode = HttpStatusCode.OK,
Content = new StringContent(json.Replace(
"\"freeMemory\": 123",
$"\"freeMemory\": {jsonValue}"
$"\"freeMemory\": {expectedValueFormatted}"
))
};
});
Expand All @@ -283,6 +287,43 @@ public async Task DeviceMetricsExporter_Returns_Dynamic_Device_Attribute_Values(
var details = await hubitat.DeviceDetails();
var heMetrics = _env.HE_METRICS.Concat(["freeMemory"]).ToArray();
var deviceAttributes = HubitatDeviceMetrics.Export(details, heMetrics).Single(o => o.MetricName == "freeMemory");
Assert.Equal(expectedValue, deviceAttributes.MetricValue);

if (jsonDoubleValue != null)
{
Assert.Equal(expectedValue, deviceAttributes.MetricValue);
}
else
{
_ = double.TryParse(jsonStringValue, out double value);
Assert.Equal(expectedValue, deviceAttributes.MetricValue);
}
}

[Theory]
[InlineData(123, "123.0")]
[InlineData(123.4, "123.4")]
public async Task GetMetrics_Returns_Dynamic_Device_Attribute_Values(
double jsonValue, string expectedValue
)
{
var httpClientFactory = _getAllDeviceDetailsIHttpClientFactory(
(json) =>
{
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(json.Replace(
"\"freeMemory\": 123",
$"\"freeMemory\": \"{jsonValue}\""
))
};
});
var env = new HubitatEnv(new Uri("http://example.org"), Guid.NewGuid(), ["freeMemory"]);
var hubitat = new Hubitat(env.HE_URI, env.HE_TOKEN, httpClientFactory);
var hubitatController = new HubitatController(hubitat, env, new Mock<ILogger<HubitatController>>().Object);

var metrics = await hubitatController.GetMetrics();

Assert.Equal($"hubitat_freememory{{device_name=\"hub_information\"}} {expectedValue}", metrics.Content?.Trim());
}
}
68 changes: 41 additions & 27 deletions hubitat2prom/HubitatEnv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ public record HubitatEnv
public Guid HE_TOKEN { get; init; }
public string[] HE_METRICS { get; init; }

public static Lazy<HubitatEnv> _instance = new Lazy<HubitatEnv>(() => new HubitatEnv());

private static object _lock = new object();
private static HubitatEnv _instanceOverride = null;
public static Lazy<HubitatEnv> _instance = new Lazy<HubitatEnv>(() => _instanceOverride ?? new HubitatEnv());
public static HubitatEnv Instance => _instance.Value;

private HubitatEnv()
Expand All @@ -28,34 +31,45 @@ public HubitatEnv(string he_uri, string he_token, string[] metrics = default)

public HubitatEnv(Uri he_uri, Guid he_token, string[] metrics = default)
{
string errors = "";
if (he_uri == default) errors += "\n`HE_URI` is empty";
if (he_token == default) errors += "\n`HE_TOKEN` is empty";
if (errors != "") throw new Exception($"Both `HE_URI` and `HE_TOKEN` must be set in the application's environment variables, or as non-empty parameters to HubitatEnv.{errors}");
lock (_lock)
{
string errors = "";
if (he_uri == default) errors += "\n`HE_URI` is empty";
if (he_token == default) errors += "\n`HE_TOKEN` is empty";
if (errors != "") throw new Exception($"Both `HE_URI` and `HE_TOKEN` must be set in the application's environment variables, or as non-empty parameters to HubitatEnv.{errors}");

var he_metrics = metrics
?? new[] {
"battery",
"humidity",
"illuminance",
"level",
"switch",
"temperature",
"heatingSetpoint",
"thermostatSetpoint",
"thermostatFanMode",
"thermostatOperatingState",
"thermostatMode",
"coolingSetpoint",
"power",
"energy",
"current",
"voltage"
};

var he_metrics = metrics
?? new[] {
"battery",
"humidity",
"illuminance",
"level",
"switch",
"temperature",
"heatingSetpoint",
"thermostatSetpoint",
"thermostatFanMode",
"thermostatOperatingState",
"thermostatMode",
"coolingSetpoint",
"power",
"energy",
"current",
"voltage"
};
HE_URI = he_uri;
HE_TOKEN = he_token;
HE_METRICS = he_metrics;

HE_URI = he_uri;
HE_TOKEN = he_token;
HE_METRICS = he_metrics;
// Bit of a hack to work around originally using
// envvars in this class's instantiation.
// This will allow anything instantiating the class
// with specific values to override the instance
// rather than relying on envvars.
// Useful for tests.
_instanceOverride = this;
}
}

private static Uri _parseHeUri(string he_uri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ private class SerializerSetMemberBinder : SetMemberBinder
{
public SerializerSetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase) { }

public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject? errorSuggestion)
public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
=> throw new NotImplementedException();
}

Expand Down Expand Up @@ -128,9 +128,9 @@ private object ReadObject(JsonElement jsonElement)
}
return expandoObject;
}
private object? ReadValue(JsonElement jsonElement)
private object ReadValue(JsonElement jsonElement)
{
object? result = null;
object result = null;
switch (jsonElement.ValueKind)
{
case JsonValueKind.Object:
Expand Down Expand Up @@ -171,9 +171,9 @@ private object ReadObject(JsonElement jsonElement)
return result;
}

private object? ReadList(JsonElement jsonElement)
private object ReadList(JsonElement jsonElement)
{
IList<object?> list = new List<object?>();
IList<object> list = new List<object>();
foreach (var item in jsonElement.EnumerateArray())
{
list.Add(ReadValue(item));
Expand Down
2 changes: 2 additions & 0 deletions hubitat2prom/PrometheusExporter/HubitatDeviceMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public static IEnumerable<ExporterHubitatDeviceMetric> Export(IEnumerable<Device
if (name == "thermostatmode" && TryGetThermostatMode(@string, out value)) return value;
if (name == "contact") return @string == "closed" ? 1 : 0;
if (double.TryParse(@string, out double result)) return result;
return 0d;
},
stringArray => 0d,
Expand Down

0 comments on commit 29f5d73

Please sign in to comment.