diff --git a/devices/homie/default.nix b/devices/homie/default.nix
index b8c3aa18..399fb54e 100644
--- a/devices/homie/default.nix
+++ b/devices/homie/default.nix
@@ -55,5 +55,6 @@ in {
sshd.enable = true;
};
+ khepri.enable = true;
services.kmscon.enable = true;
}
diff --git a/devices/homie/modules/home-assistant/default.nix b/devices/homie/modules/home-assistant/default.nix
index 8017e55f..5ed36529 100644
--- a/devices/homie/modules/home-assistant/default.nix
+++ b/devices/homie/modules/home-assistant/default.nix
@@ -4,6 +4,7 @@
./bluetooth.nix
./firmware.nix
./frontend.nix
+ ./netdaemon
./spotify.nix
./timer.nix
];
diff --git a/devices/homie/modules/home-assistant/netdaemon/.envrc b/devices/homie/modules/home-assistant/netdaemon/.envrc
new file mode 100644
index 00000000..7ce9ad6f
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/.envrc
@@ -0,0 +1 @@
+use flake "$FLAKE#netdaemon"
diff --git a/devices/homie/modules/home-assistant/netdaemon/.gitignore b/devices/homie/modules/home-assistant/netdaemon/.gitignore
new file mode 100644
index 00000000..7de5508b
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/.gitignore
@@ -0,0 +1,2 @@
+obj
+bin
diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.cs b/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.cs
new file mode 100644
index 00000000..73185228
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.cs
@@ -0,0 +1,19 @@
+namespace AppModel;
+
+///
+/// Showcases how to instance apps with yaml and use automatic configuration population
+///
+[NetDaemonApp]
+public class HelloYamlApp
+{
+ public HelloYamlApp(IHaContext ha, IAppConfig config)
+ {
+ ha.CallService("notify", "persistent_notification",
+ data: new {message = config.Value.HelloMessage, title = "Hello yaml app!"});
+ }
+}
+
+public class HelloConfig
+{
+ public string? HelloMessage { get; set; }
+}
\ No newline at end of file
diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.yaml b/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.yaml
new file mode 100644
index 00000000..d709335c
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/apps/AppModel/YamlConfigApp/YamlConfigApp.yaml
@@ -0,0 +1,2 @@
+AppModel.HelloConfig:
+ HelloMessage: Hello from yaml
\ No newline at end of file
diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/GlobalUsings.cs b/devices/homie/modules/home-assistant/netdaemon/apps/GlobalUsings.cs
new file mode 100644
index 00000000..b2d698e3
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/apps/GlobalUsings.cs
@@ -0,0 +1,6 @@
+// Common usings for NetDaemon apps
+global using System;
+global using System.Reactive.Linq;
+global using Microsoft.Extensions.Logging;
+global using NetDaemon.AppModel;
+global using NetDaemon.HassModel;
diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/HassModel/HelloWorld/HelloWorld.cs b/devices/homie/modules/home-assistant/netdaemon/apps/HassModel/HelloWorld/HelloWorld.cs
new file mode 100644
index 00000000..2b57d13c
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/apps/HassModel/HelloWorld/HelloWorld.cs
@@ -0,0 +1,16 @@
+// Use unique namespaces for your apps if you going to share with others to avoid
+// conflicting names
+
+namespace HassModel;
+
+///
+/// Hello world showcase using the new HassModel API
+///
+[NetDaemonApp]
+public class HelloWorldApp
+{
+ public HelloWorldApp(IHaContext ha)
+ {
+ ha.CallService("notify", "persistent_notification", data: new {message = "Notify me", title = "Hello world!"});
+ }
+}
\ No newline at end of file
diff --git a/devices/homie/modules/home-assistant/netdaemon/appsettings.json b/devices/homie/modules/home-assistant/netdaemon/appsettings.json
new file mode 100644
index 00000000..4d475992
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/appsettings.json
@@ -0,0 +1,17 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "Microsoft": "Warning"
+ },
+ "ConsoleThemeType": "Ansi"
+ },
+ "NetDaemon": {
+ "ApplicationConfigurationFolder": "./apps"
+ },
+ "CodeGeneration": {
+ "Namespace": "HomeAssistantGenerated",
+ "OutputFile": "HomeAssistantGenerated.cs",
+ "UseAttributeBaseClasses" : "false"
+ }
+}
diff --git a/devices/homie/modules/home-assistant/netdaemon/default.nix b/devices/homie/modules/home-assistant/netdaemon/default.nix
new file mode 100644
index 00000000..a7fb97ed
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/default.nix
@@ -0,0 +1,68 @@
+{
+ config,
+ self,
+ pkgs,
+ ...
+}: let
+ inherit (config.sops) secrets;
+
+ compiled = pkgs.callPackage ./package.nix {};
+in {
+ khepri.compositions."netdaemon" = {
+ networks.netdaemon = {external = true;};
+
+ services."netdaemon4" = {
+ image = import ./images/netdaemon.nix pkgs;
+ restart = "always";
+
+ environmentFiles = [secrets.netdaemon.path];
+ environment = {
+ HomeAssistant__Host = "homie.nelim.org";
+ HomeAssistant__Port = "443";
+ HomeAssistant__Ssl = "true";
+ NetDaemon__ApplicationAssembly = "netdaemon.dll";
+ Logging__LogLevel__Default = "Information"; # use Information/Debug/Trace/Warning/Error
+ TZ = "America/New_York";
+ };
+
+ volumes = ["${compiled}/lib/netdaemon-config:/data"];
+ networks = ["netdaemon"];
+ };
+ };
+
+ services.home-assistant = {
+ customComponents = builtins.attrValues {
+ inherit
+ (self.legacyPackages.${pkgs.system}.hass-components)
+ netdaemon
+ ;
+ };
+ };
+
+ environment.systemPackages = [
+ (pkgs.writeShellApplication {
+ name = "updateNuDeps";
+ runtimeInputs = [pkgs.dotnet-sdk_8];
+ text = ''
+ # Update the codegen
+ dotnet tool update -g NetDaemon.HassModel.CodeGen
+
+ # Update all nugets to latest versions
+ regex='PackageReference Include="([^"]*)" Version="([^"]*)"'
+
+ find . -type f -name '*.csproj' | while read -r file; do
+ # Extract unique package names from the .csproj file
+ packages=$(grep -oP "$regex" "$file" | sed -E 's/.*Include="([^"]*)".*/\1/' | sort -u)
+
+ # Loop through each package and update
+ for package in $packages; do
+ echo -e "\033[35mUpdate $file package: $package\033[0m"
+ dotnet add "$file" package "$package"
+ done
+ done
+
+ ${compiled.passthru.fetch-deps} .
+ '';
+ })
+ ];
+}
diff --git a/devices/homie/modules/home-assistant/netdaemon/deps.nix b/devices/homie/modules/home-assistant/netdaemon/deps.nix
new file mode 100644
index 00000000..0aa55661
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/deps.nix
@@ -0,0 +1,304 @@
+# This file was automatically generated by passthru.fetch-deps.
+# Please dont edit it manually, your changes might get overwritten!
+{fetchNuGet}: [
+ (fetchNuGet {
+ pname = "Cronos";
+ version = "0.8.4";
+ hash = "sha256-L9rLcqnQybPoJCcg60h49bjXfqEarM9SFHqOJUMvxz8=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration";
+ version = "8.0.0";
+ hash = "sha256-9BPsASlxrV8ilmMCjdb3TiUcm5vFZxkBnAI/fNBSEyA=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-4eBpDkf7MJozTZnOwQvwcfgRKQGcNXe0K/kF+h5Rl8o=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.Binder";
+ version = "8.0.0";
+ hash = "sha256-GanfInGzzoN2bKeNwON8/Hnamr6l7RTpYLA49CNXD9Q=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.Binder";
+ version = "8.0.2";
+ hash = "sha256-aGB0VuoC34YadAEqrwoaXLc5qla55pswDV2xLSmR7SE=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.CommandLine";
+ version = "8.0.0";
+ hash = "sha256-fmPC/o8S+weTtQJWykpnGHm6AKVU21xYE/CaHYU7zgg=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.EnvironmentVariables";
+ version = "8.0.0";
+ hash = "sha256-+bjFZvqCsMf2FRM2olqx/fub+QwfM1kBhjGVOT5HC48=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.FileExtensions";
+ version = "8.0.0";
+ hash = "sha256-BCxcjVP+kvrDDB0nzsFCJfU74UK4VBvct2JA4r+jNcs=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.Json";
+ version = "8.0.0";
+ hash = "sha256-Fi/ijcG5l0BOu7i96xHu96aN5/g7zO6SWQbTsI3Qetg=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Configuration.UserSecrets";
+ version = "8.0.0";
+ hash = "sha256-/yj5QaEzeRStvOFoBpPRPXlEehGtr2E6/rJb+OEPIK8=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.DependencyInjection";
+ version = "8.0.0";
+ hash = "sha256-+qIDR8hRzreCHNEDtUcPfVHQdurzWPo/mqviCH78+EQ=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.DependencyInjection.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-75KzEGWjbRELczJpCiJub+ltNUMMbz5A/1KQU+5dgP8=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.DependencyInjection.Abstractions";
+ version = "8.0.1";
+ hash = "sha256-lzTYLpRDAi3wW9uRrkTNJtMmaYdtGJJHdBLbUKu60PM=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.DependencyModel";
+ version = "8.0.1";
+ hash = "sha256-m8daXRK1Qn9y2c8SmtWu9ysLHwFJtEWiUQoAnMalw7s=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Diagnostics";
+ version = "8.0.0";
+ hash = "sha256-fBLlb9xAfTgZb1cpBxFs/9eA+BlBvF8Xg0DMkBqdHD4=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Diagnostics.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-USD5uZOaahMqi6u7owNWx/LR4EDrOwqPrAAim7iRpJY=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.FileProviders.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-uQSXmt47X2HGoVniavjLICbPtD2ReQOYQMgy3l0xuMU=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.FileProviders.Physical";
+ version = "8.0.0";
+ hash = "sha256-29y5ZRQ1ZgzVOxHktYxyiH40kVgm5un2yTGdvuSWnRc=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.FileSystemGlobbing";
+ version = "8.0.0";
+ hash = "sha256-+Oz41JR5jdcJlCJOSpQIL5OMBNi+1Hl2d0JUHfES7sU=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Hosting";
+ version = "8.0.0";
+ hash = "sha256-sKHa+w4/pMeQb5RRFqLtMTUJy5H6hSIGWchbH2pxSrg=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Hosting.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-0JBx+wwt5p1SPfO4m49KxNOXPAzAU0A+8tEc/itvpQE=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Http";
+ version = "8.0.0";
+ hash = "sha256-UgljypOLld1lL7k7h1noazNzvyEHIJw+r+6uGzucFSY=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging";
+ version = "8.0.0";
+ hash = "sha256-Meh0Z0X7KyOEG4l0RWBcuHHihcABcvCyfUXgasmQ91o=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.Abstractions";
+ version = "8.0.0";
+ hash = "sha256-Jmddjeg8U5S+iBTwRlVAVLeIHxc4yrrNgqVMOB7EjM4=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.Abstractions";
+ version = "8.0.1";
+ hash = "sha256-TYce3qvMr92JbAZ62ATBsocaH0joJzw0px0tYGZ9N0U=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.Configuration";
+ version = "8.0.0";
+ hash = "sha256-mzmstNsVjKT0EtQcdAukGRifD30T82BMGYlSu8k4K7U=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.Console";
+ version = "8.0.0";
+ hash = "sha256-bdb9YWWVn//AeySp7se87/tCN2E7e8Gx2GPMw28cd9c=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.Debug";
+ version = "8.0.0";
+ hash = "sha256-AJunzYBZM2wCg86hnPnMrBuWIIyW/4PnIVoDSU969cA=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.EventLog";
+ version = "8.0.0";
+ hash = "sha256-vXBm4yhWGP4uow0CqstuqOkxO8yeZEM15JTTenjPbhc=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Logging.EventSource";
+ version = "8.0.0";
+ hash = "sha256-kaR7YOlq5s8W9nZDtH/lKtnfGbrgOuQY4DUPcA2lcj0=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Options";
+ version = "8.0.0";
+ hash = "sha256-n2m4JSegQKUTlOsKLZUUHHKMq926eJ0w9N9G+I3FoFw=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Options.ConfigurationExtensions";
+ version = "8.0.0";
+ hash = "sha256-A5Bbzw1kiNkgirk5x8kyxwg9lLTcSngojeD+ocpG1RI=";
+ })
+ (fetchNuGet {
+ pname = "Microsoft.Extensions.Primitives";
+ version = "8.0.0";
+ hash = "sha256-FU8qj3DR8bDdc1c+WeGZx/PCZeqqndweZM9epcpXjSo=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.AppModel";
+ version = "24.37.1";
+ hash = "sha256-KQKTm0+4itReyulWfYMLKX1uXBv8tMNMxyI+TdOnK/s=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.Client";
+ version = "24.37.1";
+ hash = "sha256-xxOsjKFtD0cSMOr7if+bRQq6y5yR7//FruIVMXSiEww=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.Extensions.Logging";
+ version = "24.37.1";
+ hash = "sha256-JLDREBFhOOtveJu3JtwJR3ZIkQmrwMRrHt7mwmXy7dw=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.Extensions.Scheduling";
+ version = "24.37.1";
+ hash = "sha256-f+IvbPAMfK4yA7bi56SI/+1hol/6oBbz6AMkJ2OCAOc=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.Extensions.Tts";
+ version = "24.37.1";
+ hash = "sha256-R4bFaR2mUct39njcbK2m7xeuDIZeRqHdvsjp3hFBdfQ=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.HassModel";
+ version = "24.37.1";
+ hash = "sha256-eIOk6/LImCTjTC4cwWBpATqxiQUQxbsRXAcR6Mz7LKs=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.HassModel.CodeGen";
+ version = "24.37.0";
+ hash = "sha256-+YSo9/FkkDLfymWrzf4OjMwE31qjAbbFjmF7L5Aj2Bg=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.HassModel.Integration";
+ version = "24.37.1";
+ hash = "sha256-6e7oQFRs15dT0+cQxgyQWwWgmHNdFzlCnyJzmfPe5b8=";
+ })
+ (fetchNuGet {
+ pname = "NetDaemon.Runtime";
+ version = "24.37.1";
+ hash = "sha256-GwMx6f+lIoM1OznORs0Wkoc6HLalILFK1OS6Vcz1BuI=";
+ })
+ (fetchNuGet {
+ pname = "Serilog";
+ version = "3.1.1";
+ hash = "sha256-L263y8jkn7dNFD2jAUK6mgvyRTqFe39i1tRhVZsNZTI=";
+ })
+ (fetchNuGet {
+ pname = "Serilog";
+ version = "4.0.0";
+ hash = "sha256-j8hQ5TdL1TjfdGiBO9PyHJFMMPvATHWN1dtrrUZZlNw=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.AspNetCore";
+ version = "8.0.2";
+ hash = "sha256-cRZHG2bqrESOxPVxq2v+mHx+oZBzZEPksrleGVXO1p0=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Extensions.Hosting";
+ version = "8.0.0";
+ hash = "sha256-OEVkEQoONawJF+SXeyqqgU0OGp9ubtt9aXT+rC25j4E=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Extensions.Logging";
+ version = "8.0.0";
+ hash = "sha256-GoWxCpkdahMvYd7ZrhwBxxTyjHGcs9ENNHJCp0la6iA=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Formatting.Compact";
+ version = "2.0.0";
+ hash = "sha256-c3STGleyMijY4QnxPuAz/NkJs1r+TZAPjlmAKLF4+3g=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Settings.Configuration";
+ version = "8.0.2";
+ hash = "sha256-iHRQt6vDk85/6HpMXiJluAwhkjgwEnL3IKavfDgFX0k=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Sinks.Console";
+ version = "6.0.0";
+ hash = "sha256-QH8ykDkLssJ99Fgl+ZBFBr+RQRl0wRTkeccQuuGLyro=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Sinks.Debug";
+ version = "2.0.0";
+ hash = "sha256-/PLVAE33lTdUEXdahkI5ddFiGZufWnvfsOodQsFB8sQ=";
+ })
+ (fetchNuGet {
+ pname = "Serilog.Sinks.File";
+ version = "5.0.0";
+ hash = "sha256-GKy9hwOdlu2W0Rw8LiPyEwus+sDtSOTl8a5l9uqz+SQ=";
+ })
+ (fetchNuGet {
+ pname = "System.Diagnostics.DiagnosticSource";
+ version = "8.0.0";
+ hash = "sha256-+aODaDEQMqla5RYZeq0Lh66j+xkPYxykrVvSCmJQ+Vs=";
+ })
+ (fetchNuGet {
+ pname = "System.Diagnostics.EventLog";
+ version = "8.0.0";
+ hash = "sha256-rt8xc3kddpQY4HEdghlBeOK4gdw5yIj4mcZhAVtk2/Y=";
+ })
+ (fetchNuGet {
+ pname = "System.IO.Pipelines";
+ version = "8.0.0";
+ hash = "sha256-LdpB1s4vQzsOODaxiKstLks57X9DTD5D6cPx8DE1wwE=";
+ })
+ (fetchNuGet {
+ pname = "System.Reactive";
+ version = "6.0.1";
+ hash = "sha256-Lo5UMqp8DsbVSUxa2UpClR1GoYzqQQcSxkfyFqB/d4Q=";
+ })
+ (fetchNuGet {
+ pname = "System.Text.Encodings.Web";
+ version = "8.0.0";
+ hash = "sha256-IUQkQkV9po1LC0QsqrilqwNzPvnc+4eVvq+hCvq8fvE=";
+ })
+ (fetchNuGet {
+ pname = "System.Text.Json";
+ version = "8.0.0";
+ hash = "sha256-XFcCHMW1u2/WujlWNHaIWkbW1wn8W4kI0QdrwPtWmow=";
+ })
+ (fetchNuGet {
+ pname = "System.Text.Json";
+ version = "8.0.4";
+ hash = "sha256-g5oT7fbXxQ9Iah1nMCr4UUX/a2l+EVjJyTrw3FTbIaI=";
+ })
+ (fetchNuGet {
+ pname = "YamlDotNet";
+ version = "16.1.2";
+ hash = "sha256-J8fZ6rRFiNsAYDxHFskAjC2fP+K2XrewDs50jAKEWTY=";
+ })
+]
diff --git a/devices/homie/modules/home-assistant/netdaemon/images/netdaemon.nix b/devices/homie/modules/home-assistant/netdaemon/images/netdaemon.nix
new file mode 100644
index 00000000..0d641159
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/images/netdaemon.nix
@@ -0,0 +1,8 @@
+pkgs:
+pkgs.dockerTools.pullImage rec {
+ imageName = "netdaemon/netdaemon4";
+ imageDigest = "sha256:2ccb8dce2a7a5bba14bd90030640f09a91adccb472e16168ad06ae1f752430ae";
+ sha256 = "1qj2yrbhcr162ikfv3jbh4qvb17p7vzxva5z3r5vhhimayr24dn4";
+ finalImageName = imageName;
+ finalImageTag = "24.37.1";
+}
diff --git a/devices/homie/modules/home-assistant/netdaemon/netdaemon.csproj b/devices/homie/modules/home-assistant/netdaemon/netdaemon.csproj
new file mode 100644
index 00000000..a98da190
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/netdaemon.csproj
@@ -0,0 +1,37 @@
+
+
+
+ Exe
+ net8.0
+ 12.0
+ enable
+ netdaemon
+
+
+
+
+ Always
+ Never
+
+
+ Always
+
+
+ Always
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/devices/homie/modules/home-assistant/netdaemon/package.nix b/devices/homie/modules/home-assistant/netdaemon/package.nix
new file mode 100644
index 00000000..9adfd66b
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/package.nix
@@ -0,0 +1,22 @@
+{
+ buildDotnetModule,
+ dotnetCorePackages,
+}:
+buildDotnetModule {
+ pname = "netdaemon-config";
+ version = "0.0.0";
+
+ src =
+ builtins.filterSource
+ (file: type:
+ (type != "directory")
+ || (baseNameOf file != "default.nix" && baseNameOf file != "package.nix"))
+ ./.;
+
+ projectFile = "netdaemon.csproj";
+ nugetDeps = ./deps.nix;
+
+ dotnet-sdk = dotnetCorePackages.sdk_8_0;
+ dotnet-runtime = dotnetCorePackages.runtime_8_0;
+ executables = [];
+}
diff --git a/devices/homie/modules/home-assistant/netdaemon/program.cs b/devices/homie/modules/home-assistant/netdaemon/program.cs
new file mode 100644
index 00000000..17a1e227
--- /dev/null
+++ b/devices/homie/modules/home-assistant/netdaemon/program.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using Microsoft.Extensions.Hosting;
+using NetDaemon.Extensions.Logging;
+using NetDaemon.Extensions.Scheduler;
+using NetDaemon.Extensions.Tts;
+using NetDaemon.Runtime;
+// Add next line if using code generator
+//using HomeAssistantGenerated;
+
+#pragma warning disable CA1812
+
+try
+{
+ await Host.CreateDefaultBuilder(args)
+ .UseNetDaemonAppSettings()
+ .UseNetDaemonDefaultLogging()
+ .UseNetDaemonRuntime()
+ .UseNetDaemonTextToSpeech()
+ .ConfigureServices((_, services) =>
+ services
+ .AddAppsFromAssembly(Assembly.GetExecutingAssembly())
+ .AddNetDaemonStateManager()
+ .AddNetDaemonScheduler()
+ // Add next line if using code generator
+ // .AddHomeAssistantGenerated()
+ )
+ .Build()
+ .RunAsync()
+ .ConfigureAwait(false);
+}
+catch (Exception e)
+{
+ Console.WriteLine($"Failed to start host... {e}");
+ throw;
+}
diff --git a/flake.lock b/flake.lock
index 7b6029c8..1310b5c8 100644
Binary files a/flake.lock and b/flake.lock differ
diff --git a/flake.nix b/flake.nix
index 160c1cf9..4894f91d 100644
Binary files a/flake.nix and b/flake.nix differ
diff --git a/inputs.nix b/inputs.nix
index 1203779e..979b71eb 100644
--- a/inputs.nix
+++ b/inputs.nix
@@ -196,6 +196,11 @@ let
owner = "make-all";
repo = "tuya-local";
}
+ {
+ name = "netdaemon-src";
+ owner = "net-daemon";
+ repo = "integration";
+ }
{
name = "spotifyplus-src";
owner = "thlucas1";
diff --git a/legacyPackages/hass-components/default.nix b/legacyPackages/hass-components/default.nix
index 02db5d18..1308e10e 100644
--- a/legacyPackages/hass-components/default.nix
+++ b/legacyPackages/hass-components/default.nix
@@ -4,6 +4,7 @@ pkgs.lib.makeScope pkgs.newScope (hass: let
hass.callPackage file (inputs // extraArgs // {});
in {
extended-ollama-conversation = buildHassComponent ./extended-ollama-conversation {};
+ netdaemon = buildHassComponent ./netdaemon {};
spotifyplus = import ./spotifyplus ({inherit buildHassComponent;} // inputs);
tuya-local = buildHassComponent ./tuya-local {};
})
diff --git a/legacyPackages/hass-components/netdaemon/default.nix b/legacyPackages/hass-components/netdaemon/default.nix
new file mode 100644
index 00000000..91e30fac
--- /dev/null
+++ b/legacyPackages/hass-components/netdaemon/default.nix
@@ -0,0 +1,21 @@
+{
+ netdaemon-src,
+ buildHomeAssistantComponent,
+ python3Packages,
+ ...
+}: let
+ inherit (builtins) fromJSON readFile;
+
+ manifest = fromJSON (readFile "${netdaemon-src}/custom_components/netdaemon/manifest.json");
+in
+ buildHomeAssistantComponent {
+ owner = "net-daemon";
+
+ inherit (manifest) domain version;
+
+ src = netdaemon-src;
+
+ propagatedBuildInputs = with python3Packages; [
+ awesomeversion
+ ];
+ }
diff --git a/outputs.nix b/outputs.nix
index ebcd990f..0ad157ed 100644
--- a/outputs.nix
+++ b/outputs.nix
@@ -157,6 +157,12 @@
];
};
+ netdaemon = pkgs.mkShell {
+ packages = [
+ pkgs.dotnet-sdk_8
+ ];
+ };
+
node = pkgs.mkShell {
packages =
(builtins.attrValues {