Skip to content

Commit 74d03a9

Browse files
authored
Api support read only (#165)
1 parent 7052e03 commit 74d03a9

File tree

9 files changed

+247
-67
lines changed

9 files changed

+247
-67
lines changed

.devcontainer/devcontainer.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@
2525
"NETDAEMON__SOURCEFOLDER": "${localEnv:NETDAEMON__SOURCEFOLDER}"
2626
},
2727
"postCreateCommand": "dotnet restore && .devcontainer/install_prettyprompt.sh",
28-
// Uncomment the next line if you want to publish any ports.
29-
"appPort": [
30-
5001
31-
],
28+
// Uncomment the next line if you want to publish or forward any ports.
29+
// "forwardPorts": [
30+
// 5000
31+
// ],
32+
// "appPort": [
33+
// 5000
34+
// ],
3235
// Uncomment the next line to run commands after the container is created.
3336
// "postCreateCommand": "dotnet restore",
3437
// Uncomment the next line to use a non-root user. On Linux, this will prevent

exampleapps/apps/test2.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
my_app:
22
class: BatteryManager
33
# HelloWorldSecret: !secret test_secret
4-
# dependencies:
5-
# - global_app
4+
dependencies:
5+
- global_app

src/Daemon/NetDaemon.Daemon/Daemon/NetDaemonHost.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public class NetDaemonHost : INetDaemonHost, IAsyncDisposable
6969

7070
private readonly ConcurrentDictionary<string, INetDaemonAppBase> _runningAppInstances =
7171
new ConcurrentDictionary<string, INetDaemonAppBase>();
72+
private readonly ConcurrentDictionary<string, INetDaemonAppBase> _allAppInstances =
73+
new ConcurrentDictionary<string, INetDaemonAppBase>();
7274

7375
private readonly Scheduler _scheduler;
7476

@@ -131,6 +133,8 @@ public IHttpHandler Http
131133

132134
public IEnumerable<INetDaemonAppBase> RunningAppInstances => _runningAppInstances.Values;
133135

136+
public IEnumerable<INetDaemonAppBase> AllAppInstances => _allAppInstances.Values;
137+
134138
public IScheduler Scheduler => _scheduler;
135139

136140
public IEnumerable<EntityState> State => InternalState.Select(n => n.Value);
@@ -428,6 +432,7 @@ public async Task Run(string host, short port, bool ssl, string token, Cancellat
428432
await _hassClient.SubscribeToEvents().ConfigureAwait(false);
429433

430434
Connected = true;
435+
_stopped = false;
431436

432437
Logger.LogInformation(
433438
hassioToken != null
@@ -593,6 +598,7 @@ public async Task UnloadAllApps()
593598
await app.Value.DisposeAsync().ConfigureAwait(false);
594599
}
595600
_runningAppInstances.Clear();
601+
_allAppInstances.Clear();
596602
}
597603

598604
/// <summary>
@@ -857,7 +863,7 @@ protected virtual async Task HandleNewEvent(HassEvent hassEvent, CancellationTok
857863
// Todo: Make it timeout! Maybe it should be handling in it's own task like scheduler
858864
if (tasks.Count > 0)
859865
{
860-
866+
861867
await tasks.WhenAll(token).ConfigureAwait(false);
862868

863869
await tasks.WhenAll(token).ConfigureAwait(false);
@@ -1208,6 +1214,7 @@ private async Task LoadAllApps()
12081214
{
12091215
_runningAppInstances[appInstance.Id!] = appInstance;
12101216
}
1217+
_allAppInstances[appInstance.Id!] = appInstance;
12111218
}
12121219

12131220
// Now run initialize on all sorted by dependencies

src/DaemonRunner/DaemonRunner/DaemonRunner.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@
2222

2323
<ItemGroup>
2424
<PackageReference Include="JoySoftware.HassClient" Version="0.6.0-beta" />
25+
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
26+
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
27+
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
28+
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
2529
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.6.0" />
30+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
2631
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.6" />
2732
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.6" />
2833
<PackageReference Include="YamlDotNet" Version="8.1.2" />

src/DaemonRunner/DaemonRunner/NetDaemonExtensions.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
using System.IO;
2+
using System.Net;
3+
using JoySoftware.HomeAssistant.Client;
4+
using Microsoft.AspNetCore.Hosting;
5+
using Microsoft.Extensions.DependencyInjection;
26
using Microsoft.Extensions.Hosting;
7+
using Microsoft.Extensions.Options;
8+
using NetDaemon.Daemon;
9+
using NetDaemon.Daemon.Storage;
310
using NetDaemon.Service;
411
using NetDaemon.Service.Configuration;
512

@@ -14,8 +21,13 @@ public static IHostBuilder UseNetDaemon(this IHostBuilder hostBuilder)
1421
services.Configure<HomeAssistantSettings>(context.Configuration.GetSection("HomeAssistant"));
1522
services.Configure<NetDaemonSettings>(context.Configuration.GetSection("NetDaemon"));
1623

17-
services.AddHttpClient();
18-
services.AddHostedService<RunnerService>();
24+
}).ConfigureWebHostDefaults(webbuilder =>
25+
{
26+
webbuilder.UseKestrel(options =>
27+
{
28+
options.Listen(IPAddress.Loopback, 5000); //HTTP port
29+
});
30+
webbuilder.UseStartup<ApiStartup>();
1931
});
2032
}
2133
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.Extensions.Logging;
7+
using Microsoft.Extensions.Options;
8+
using NetDaemon.Common;
9+
using NetDaemon.Daemon;
10+
using NetDaemon.Service.Configuration;
11+
12+
namespace NetDaemon.Service.Api
13+
{
14+
15+
[ApiController]
16+
[Route("api")]
17+
public class ApiController : ControllerBase
18+
{
19+
private readonly ILogger<ApiController> _logger;
20+
private readonly NetDaemonSettings? _netdaemonSettings;
21+
private readonly HomeAssistantSettings? _homeassistantSettings;
22+
23+
private readonly NetDaemonHost? _host;
24+
public ApiController(
25+
IOptions<NetDaemonSettings> netDaemonSettings,
26+
IOptions<HomeAssistantSettings> homeAssistantSettings,
27+
ILoggerFactory? loggerFactory = null,
28+
NetDaemonHost? host = null
29+
)
30+
{
31+
_logger = loggerFactory.CreateLogger<ApiController>();
32+
_host = host;
33+
_netdaemonSettings = netDaemonSettings.Value;
34+
_homeassistantSettings = homeAssistantSettings.Value;
35+
}
36+
37+
[Route("settings")]
38+
[HttpGet]
39+
public ApiConfig? Config()
40+
{
41+
var tempResult = new ApiConfig
42+
{
43+
DaemonSettings = _netdaemonSettings,
44+
HomeAssistantSettings = _homeassistantSettings
45+
};
46+
// For first release we do not expose the token
47+
if (tempResult.HomeAssistantSettings is object)
48+
{
49+
tempResult.HomeAssistantSettings.Token = "";
50+
}
51+
return tempResult;
52+
}
53+
54+
[HttpGet]
55+
[Route("apps")]
56+
public IEnumerable<ApiApplication>? Apps()
57+
{
58+
return _host?.AllAppInstances.Select(n => new ApiApplication()
59+
{
60+
Id = n.Id,
61+
Dependencies = n.Dependencies,
62+
IsEnabled = n.IsEnabled
63+
});
64+
}
65+
66+
67+
}
68+
69+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Collections.Generic;
2+
using NetDaemon.Service.Configuration;
3+
4+
namespace NetDaemon.Service.Api
5+
{
6+
7+
public class ApiApplication
8+
{
9+
public string? Id { get; set; }
10+
public IEnumerable<string>? Dependencies { get; set; }
11+
12+
public bool IsEnabled { get; set; }
13+
14+
}
15+
16+
public class ApiConfig
17+
{
18+
public NetDaemonSettings? DaemonSettings { get; set; }
19+
public HomeAssistantSettings? HomeAssistantSettings { get; set; }
20+
21+
}
22+
23+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.Reflection;
2+
using JoySoftware.HomeAssistant.Client;
3+
using Microsoft.AspNetCore.Builder;
4+
using Microsoft.AspNetCore.Hosting;
5+
using Microsoft.AspNetCore.Mvc.ApplicationParts;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using NetDaemon.Daemon;
9+
using NetDaemon.Daemon.Storage;
10+
using NetDaemon.Service.Configuration;
11+
using NetDaemon.Service;
12+
using Microsoft.Extensions.Options;
13+
using System.IO;
14+
using Microsoft.Extensions.Hosting;
15+
using NetDaemon.Common;
16+
17+
namespace NetDaemon.Service
18+
{
19+
public class ApiStartup
20+
{
21+
public ApiStartup(IConfiguration configuration)
22+
{
23+
Configuration = configuration;
24+
}
25+
26+
public IConfiguration Configuration { get; }
27+
28+
public void ConfigureServices(IServiceCollection services)
29+
{
30+
// services.Configure<HomeAssistantSettings>(Context.Configuration.GetSection("HomeAssistant"));
31+
// services.Configure<NetDaemonSettings>(context.Configuration.GetSection("NetDaemon"));
32+
services.AddHostedService<RunnerService>();
33+
services.AddTransient<IHassClient, HassClient>();
34+
services.AddTransient<IDataRepository>(n => new DataRepository(Path.Combine(n.GetRequiredService<IOptions<NetDaemonSettings>>().Value.SourceFolder!, ".storage")));
35+
services.AddTransient<IHttpHandler, NetDaemon.Daemon.HttpHandler>();
36+
services.AddSingleton<NetDaemonHost>();
37+
services.AddHttpClient();
38+
services.AddControllers().PartManager.ApplicationParts.Add(new AssemblyPart(Assembly.GetExecutingAssembly()));
39+
services.AddRouting();
40+
}
41+
42+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
43+
{
44+
if (env.IsDevelopment())
45+
{
46+
app.UseDeveloperExceptionPage();
47+
}
48+
49+
// app.UseHttpsRedirection();
50+
51+
app.UseRouting();
52+
53+
// app.UseAuthorization();
54+
55+
app.UseEndpoints(endpoints =>
56+
{
57+
endpoints.MapControllers();
58+
});
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)