V15 / 313404a015e8
HomeModels.cs
Lilith/Core/HomeAutomation/HomeModels.cs
Changed in this versionCS
using System.Net;
using System.Text.Json;
namespace Lilith.Core.HomeAutomation;
public sealed record HomeDevice(string Id, string Name, string Transport, string[] Capabilities, string? Endpoint = null, string? TokenEnvironment = null);
public sealed record LightState(bool Power = true, int Brightness = 100, string Color = "#FFFFFF");
public sealed record HomeProposal(string Id, string Device, string ConfigHash, string Action, JsonElement Value);
public sealed record HomeResult(string Status, string Message, string? ProposalId = null, object? Data = null, bool Mutation = false)
{
public string ToReply() => Message;
}
public sealed record HomeOptions(string RootDirectory, Lilith.Core.Workspace.WorkspaceAccessMode Mode, HomeDevice[] Devices)
{
public static HomeDevice[] DemoDevices => [new("living_room_light", "Living room light", "dummy", ["power", "brightness", "color"])];
public static HomeOptions Load(string root, Lilith.Core.Workspace.WorkspaceAccessMode mode)
{
string? path = Environment.GetEnvironmentVariable("LILITH_HOME_CONFIG");
HomeDevice[] devices = path is null ? [] : JsonSerializer.Deserialize<HomeDevice[]>(File.ReadAllText(path), new JsonSerializerOptions(JsonSerializerDefaults.Web)) ?? throw new InvalidDataException("Invalid home device configuration.");
return new(root, mode, devices);
}
internal static Uri ValidateEndpoint(string? endpoint)
{
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var uri) || uri.Scheme != "http" || uri.AbsolutePath != "/" || uri.Query.Length != 0 || uri.Fragment.Length != 0 || uri.UserInfo.Length != 0 || !IPAddress.TryParse(uri.Host, out var ip) || ip.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
throw new ArgumentException("Device endpoint must be an explicit private IPv4 HTTP base URL.");
byte[] b = ip.GetAddressBytes();
if (!(b[0] == 10 || b[0] == 172 && b[1] is >= 16 and <= 31 || b[0] == 192 && b[1] == 168 || b[0] == 127)) throw new ArgumentException("Only configured LAN or loopback device IPs are supported.");
return uri;
}
}