111111
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Evergreen.Health.Application.Health.Integrations.HomeAssistant;
|
||||
|
||||
public sealed class HomeAssistantClient
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly HomeAssistantOptions _options;
|
||||
|
||||
public HomeAssistantClient(HttpClient httpClient, IOptions<HomeAssistantOptions> options)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_options = options.Value;
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(Math.Clamp(_options.TimeoutSeconds, 3, 60));
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<HomeAssistantState>> GetStatesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var request = CreateRequest(HttpMethod.Get, "api/states");
|
||||
using var response = await _httpClient.SendAsync(request, cancellationToken);
|
||||
await EnsureSuccessAsync(response, cancellationToken);
|
||||
return await response.Content.ReadFromJsonAsync<List<HomeAssistantState>>(cancellationToken: cancellationToken) ?? [];
|
||||
}
|
||||
|
||||
public async Task CallServiceAsync(
|
||||
string domain,
|
||||
string service,
|
||||
IReadOnlyDictionary<string, object?> data,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var request = CreateRequest(HttpMethod.Post, $"api/services/{domain}/{service}");
|
||||
request.Content = JsonContent.Create(data);
|
||||
using var response = await _httpClient.SendAsync(request, cancellationToken);
|
||||
await EnsureSuccessAsync(response, cancellationToken);
|
||||
}
|
||||
|
||||
private HttpRequestMessage CreateRequest(HttpMethod method, string path)
|
||||
{
|
||||
if (!_options.Enabled)
|
||||
throw new InvalidOperationException("Home Assistant 接入未启用");
|
||||
if (string.IsNullOrWhiteSpace(_options.BaseUrl))
|
||||
throw new InvalidOperationException("Home Assistant 地址未配置");
|
||||
if (string.IsNullOrWhiteSpace(_options.AccessToken))
|
||||
throw new InvalidOperationException("Home Assistant 访问令牌未配置");
|
||||
|
||||
var baseUrl = _options.BaseUrl.TrimEnd('/') + "/";
|
||||
var request = new HttpRequestMessage(method, new Uri(new Uri(baseUrl), path));
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _options.AccessToken);
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
return request;
|
||||
}
|
||||
|
||||
private static async Task EnsureSuccessAsync(HttpResponseMessage response, CancellationToken cancellationToken)
|
||||
{
|
||||
if (response.IsSuccessStatusCode) return;
|
||||
var body = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
var message = body.Length > 300 ? body[..300] : body;
|
||||
throw new HttpRequestException($"Home Assistant 返回 {(int)response.StatusCode}: {message}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Evergreen.Health.Application.Health.Integrations.HomeAssistant;
|
||||
|
||||
public sealed class HomeAssistantState
|
||||
{
|
||||
[JsonPropertyName("entity_id")]
|
||||
public string EntityId { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("state")]
|
||||
public string State { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("attributes")]
|
||||
public JsonElement Attributes { get; set; }
|
||||
|
||||
[JsonPropertyName("last_updated")]
|
||||
public DateTimeOffset? LastUpdated { get; set; }
|
||||
|
||||
public string? GetStringAttribute(string name)
|
||||
{
|
||||
if (!Attributes.TryGetProperty(name, out var value)) return null;
|
||||
return value.ValueKind == JsonValueKind.String ? value.GetString() : value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class HomeAssistantActionResult
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string EntityId { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using Furion.ConfigurableOptions;
|
||||
|
||||
namespace Evergreen.Health.Application.Health.Integrations.HomeAssistant;
|
||||
|
||||
public sealed class HomeAssistantOptions : IConfigurableOptions
|
||||
{
|
||||
public bool Enabled { get; set; } = true;
|
||||
public string BaseUrl { get; set; } = string.Empty;
|
||||
public string AccessToken { get; set; } = string.Empty;
|
||||
public int TimeoutSeconds { get; set; } = 15;
|
||||
public HomeAssistantEntityOptions Entities { get; set; } = new();
|
||||
public HomeAssistantSleepSceneOptions SleepScene { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class HomeAssistantEntityOptions
|
||||
{
|
||||
public string Dehumidifier { get; set; } = string.Empty;
|
||||
public string DehumidifierFanLevel { get; set; } = string.Empty;
|
||||
public string DehumidifierUv { get; set; } = string.Empty;
|
||||
public string FragranceSwitch { get; set; } = string.Empty;
|
||||
public string FragranceLight { get; set; } = string.Empty;
|
||||
public string AmbientLight { get; set; } = string.Empty;
|
||||
public string Speaker { get; set; } = string.Empty;
|
||||
public string SpeakerSleepMode { get; set; } = string.Empty;
|
||||
public string Temperature { get; set; } = string.Empty;
|
||||
public string Humidity { get; set; } = string.Empty;
|
||||
public string Pm25 { get; set; } = string.Empty;
|
||||
public string Co2 { get; set; } = string.Empty;
|
||||
public string Formaldehyde { get; set; } = string.Empty;
|
||||
public string Tvoc { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class HomeAssistantSleepSceneOptions
|
||||
{
|
||||
public int TargetHumidity { get; set; } = 55;
|
||||
public string DehumidifierMode { get; set; } = "睡眠";
|
||||
public string FanLevel { get; set; } = "1挡";
|
||||
public int LightBrightnessPercent { get; set; } = 20;
|
||||
public int LightColorTemperatureKelvin { get; set; } = 2700;
|
||||
public bool EnableFragrance { get; set; } = true;
|
||||
public bool EnableSpeakerSleepMode { get; set; }
|
||||
public bool EnableUv { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user