📄
src/Integrations/HomeAssistant/HomeAssistantClient.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System; using System.Globalization; using System.Linq; using System.Net.Http; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Options; namespace MMirror.Integrations.HomeAssistant; public sealed class HomeAssistantClient(HttpClient httpClient, IOptions<HomeAssistantOptions> options) { public async Task<Temperatures> GetTemperatures(CancellationToken cancellationToken) { var states = await httpClient.GetFromJsonAsync( "/api/states", HomeAssistantJsonSerializerContext.Default.EntityStateArray, cancellationToken ) ?? throw new Exception("Received literal null from Home Assistant states endpoint."); return new Temperatures( FindTemperature(states, options.Value.InsideTemperatureEntityId), FindTemperature(states, options.Value.OutsideTemperatureEntityId) ); } private static double FindTemperature(EntityState[] states, string entityId) { var state = states.FirstOrDefault(entry => entry.EntityId == entityId)?.State ?? throw new Exception($"Home Assistant state not found for entity '{entityId}'."); if ( !double.TryParse(state, NumberStyles.Float, CultureInfo.InvariantCulture, out var temperature) || double.IsNaN(temperature) || double.IsInfinity(temperature) ) { throw new Exception($"Home Assistant state '{state}' for entity '{entityId}' is not a valid temperature."); } return temperature; } } public sealed record Temperatures(double InsideCelsius, double OutsideCelsius);