Skip to content

Commit

Permalink
Merge pull request #11 from timia2109/feature/quartz-scheduler
Browse files Browse the repository at this point in the history
Feature/quartz scheduler
  • Loading branch information
timia2109 authored Apr 28, 2024
2 parents a03e6b3 + c1001ce commit bf12a42
Show file tree
Hide file tree
Showing 80 changed files with 501 additions and 278 deletions.
19 changes: 11 additions & 8 deletions .github/workflows/containerize.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,26 @@ jobs:
runs-on: ubuntu-22.04
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
defaults:
run:
working-directory: ./DisplayUtil
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3.2.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8"
cache: true
cache-dependency-path: DisplayUtil.csproj
cache-dependency-path: DisplayUtil/DisplayUtil.csproj
- name: Restore NuGet dependencies
run: dotnet restore --locked-mode
- name: Build server
run: dotnet publish -c Release --no-restore
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: backend-artifacts
path: bin/Release/net8.0/publish/
path: DisplayUtil/bin/Release/net8.0/publish/
build-docker-image:
runs-on: ubuntu-22.04
permissions:
Expand All @@ -37,23 +40,23 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3.0.2
uses: actions/download-artifact@v4
with:
name: backend-artifacts
path: build/
- name: Docker Login
uses: docker/login-action@v3.0.0
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Metadata action
id: docker_metadata
uses: docker/metadata-action@v5.0.0
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}
- name: Build and push Docker image
uses: docker/build-push-action@v5.1.0
uses: docker/build-push-action@v5
with:
context: .
push: true
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -483,4 +483,5 @@ $RECYCLE.BIN/
# Vim temporary swap files
*.swp
appsettings.Local.json
Resources/*
Resources/*
*.ttf
14 changes: 10 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
{
"configurations": [
{
"name": "C#: DisplayUtil [https]",
"type": "dotnet",
"name": "C#: DisplayUtil Server",
"type": "coreclr",
"request": "launch",
"projectPath": "${workspaceFolder}\\DisplayUtil.csproj",
"launchConfigurationId": "TargetFramework=;https",
"preLaunchTask": "build_webserver",
"program": "${workspaceFolder}/DisplayUtil/bin/Debug/net8.0/DisplayUtil.dll",
"args": [],
"cwd": "${workspaceFolder}/DisplayUtil",
"stopAtEntry": false,
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"logging": {
"moduleLoad": false
}
Expand Down
17 changes: 17 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build_webserver",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DisplayUtil/DisplayUtil.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
2 changes: 1 addition & 1 deletion DisplayUtil.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisplayUtil", "DisplayUtil.csproj", "{2DF5E15B-3151-4106-A8C2-2EB2302B2958}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisplayUtil", "DisplayUtil/DisplayUtil.csproj", "{2DF5E15B-3151-4106-A8C2-2EB2302B2958}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
57 changes: 29 additions & 28 deletions DisplayUtil.csproj → DisplayUtil/DisplayUtil.csproj
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="NetDaemon.Client" Version="24.8.0" />
<PackageReference Include="NetDaemon.HassModel" Version="24.8.0" />
<PackageReference Include="Scriban" Version="5.9.1" />
<PackageReference Include="SkiaSharp" Version="2.88.7" />
<PackageReference Include="SkiaSharp.Extended" Version="1.60.0" />
<PackageReference Include="SkiaSharp.Svg" Version="1.60.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
</ItemGroup>

<!--<ItemGroup>
<Content Include="Resources\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>-->

<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="NetDaemon.Client" Version="24.16.0" />
<PackageReference Include="NetDaemon.HassModel" Version="24.16.0" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.8.1" />
<PackageReference Include="Scriban" Version="5.9.1" />
<PackageReference Include="SkiaSharp" Version="2.88.7" />
<PackageReference Include="SkiaSharp.Extended" Version="1.60.0" />
<PackageReference Include="SkiaSharp.Svg" Version="1.60.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
</ItemGroup>

<!--<ItemGroup>
<Content Include="Resources\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>-->

</Project>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
using Microsoft.Extensions.Options;
using NetDaemon.Client;
using NetDaemon.Client.HomeAssistant.Model;
using Quartz;

namespace DisplayUtil.HomeAssistant.Calendar;

public partial class HassCalendarWorker(
public partial class HassCalendarImportJob(
IHomeAssistantConnection client,
HassAppointmentStore store,
IOptions<HassCalendarSettings> options,
ILogger<HassCalendarWorker> logger
)
ILogger<HassCalendarImportJob> logger
) : IJob
{
private readonly ILogger _logger = logger;

Expand All @@ -20,7 +21,7 @@ public async Task RefreshAsync()
store.Appointments = appointments ?? [];
}

public async Task<HassEvent[]?> FetchAsync(CancellationToken cancellation)
private async Task<HassEvent[]?> FetchAsync(CancellationToken cancellation)
{
LogFetch();

Expand Down Expand Up @@ -65,6 +66,10 @@ public async Task RefreshAsync()
[LoggerMessage(LogLevel.Warning, "Error fetching appointments")]
private partial void LogError(Exception e);

public Task Execute(IJobExecutionContext context)
{
return RefreshAsync();
}
}

internal record GetEventsPayload : CommandMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NetDaemon.Client.Extensions;
using NetDaemon.Client.Settings;
using NetDaemon.HassModel;
using Quartz;

namespace DisplayUtil.HomeAssistant;

Expand All @@ -21,17 +22,8 @@ public static IHostApplicationBuilder AddHassSupport(this IHostApplicationBuilde

builder.Services
.AddHomeAssistantClient()
.AddScoped<ITemplateExtender, HassTemplateExtender>();

// Hack: Initialize Hass Model
var extensionType = typeof(DependencyInjectionSetup);
var methodInfo = extensionType.GetMethod("AddScopedHaContext",
System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Static
)
?? throw new Exception("Error injecting Hass Model");

methodInfo.Invoke(null, [builder.Services]);
.AddScoped<ITemplateExtender, HassTemplateExtender>()
.AddScopedHaContext();

// Background Connection
builder.Services.AddHostedService<HassHostedService>();
Expand All @@ -44,8 +36,19 @@ public static IHostApplicationBuilder AddHassSupport(this IHostApplicationBuilde
builder.Services
.AddSingleton<HassAppointmentStore>()
.AddSingleton<ITemplateExtender>(s => s.GetRequiredService<HassAppointmentStore>())
.AddScoped<HassCalendarWorker>()
.AddHostedService<HassCalendarJob>();
.AddScoped<HassCalendarImportJob>();

builder.Services.Configure<QuartzOptions>(o =>
{
var jobKey = new JobKey(nameof(HassCalendarImportJob));
o.AddJob<HassCalendarImportJob>(j => j.WithIdentity(jobKey));

o.AddTrigger(t => t
.ForJob(jobKey)
.WithSecurityTimeout()
.WithSimpleSchedule(s => s.WithIntervalInHours(1))
);
});

return builder;
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void Enrich(ScriptObject context, EnrichScope scope)
hassObject.Import("get_state", GetState);
hassObject.Import("get_attribute", GetAttribute);
hassObject.Import("get_float_state", GetFloatState);
hassObject.Import("get_datetime", GetDateTime);
hassObject.Import("get_datetime_state", GetDateTime);
context.Add("hass", hassObject);
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using DisplayUtil.Template;
using DisplayUtil.Utils;
using MQTTnet;
using MQTTnet.Client;
Expand All @@ -19,12 +20,7 @@ public static IHostApplicationBuilder AddMqttWriter(this IHostApplicationBuilder
else
builder.Services.AddSingleton<MqttExporter>();

if (
settings.ScreenDetectTemplate is null
|| settings.RefreshInterval is null
) return builder;

builder.Services.AddHostedService<MqttExportJob>();
builder.Services.AddScoped<ITemplateExtender, MqttTemplateExtender>();

return builder;
}
Expand Down Expand Up @@ -61,23 +57,4 @@ MqttSettings settings

return true;
}

public static WebApplication UseMqttWriter(this WebApplication app)
{
if (app.Services.GetService<MqttExporter>() is null) return app;

app.MapGet("/mqtt/uri", async (MqttUrlRenderer renderer) =>
{
return Results.Ok(await renderer.GetMqttTemplateUriAsync());
})
.WithName("Get MQTT URI")
.WithOpenApi();

app.MapGet("/mqtt/template", async (MqttUrlRenderer renderer)
=> Results.Ok(await renderer.GetMqttTemplateAsync()))
.WithName("Get MQTT Template")
.WithOpenApi();

return app;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ public record MqttSettings
/// </summary>
public string? Topic { get; init; }

/// <summary>
/// Template used, to detect the MQTT Template
/// </summary>
public string? ScreenDetectTemplate { get; init; }

/// <summary>
/// Interval for rerendering the Template
/// </summary>
public TimeSpan? RefreshInterval { get; init; }

/// <summary>
/// Should the message only be updated, when the value changes?
/// </summary>
Expand Down
32 changes: 32 additions & 0 deletions DisplayUtil/MqttExport/MqttTemplateExtender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using DisplayUtil.Template;
using Scriban.Runtime;

namespace DisplayUtil.MqttExport;

/// <summary>
/// Provides the publish_mqtt_template function to Jobs
/// </summary>
/// <param name="setter"></param>
public class MqttTemplateExtender(
MqttUrlRenderer setter
) : ITemplateExtender
{
public void Enrich(
ScriptObject scriptObject,
EnrichScope scope)
{
if (scope != EnrichScope.Job) return;

scriptObject.Import("publish_mqtt_template", SetMqttTemplate);
}

private void SetMqttTemplate(string templateId)
{
_ = SetMqttTemplateAsync(templateId.Trim());
}

private async Task SetMqttTemplateAsync(string templateId)
{
await setter.GenerateUrlAndPublish(templateId);
}
}
Loading

0 comments on commit bf12a42

Please sign in to comment.