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}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user