← All source files

V17 / d6d373561692

HomeModels.cs

Lilith/Core/HomeAutomation/HomeModels.cs

Unchanged from the preceding version
CS
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;
    }
}