From 7169561eaafe8fffbb18976a6da37da0b497dd8a Mon Sep 17 00:00:00 2001 From: taywon18 Date: Sun, 22 Sep 2024 16:49:15 +0200 Subject: [PATCH] added basic parsing support --- Tagger/Configuration.cs | 2 + Tagger/Pages/Page.razor | 8 ++- Tagger/Pages/Page.razor.css | 1 + Tagger/Program.cs | 1 + Tagger/RunEnv/Pages/pommier | 7 +- Tagger/Service/ParsingManager.cs | 106 +++++++++++++++++++++++++++++++ Tagger/wwwroot/css/site.css | 14 ++++ 7 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 Tagger/Pages/Page.razor.css create mode 100644 Tagger/Service/ParsingManager.cs diff --git a/Tagger/Configuration.cs b/Tagger/Configuration.cs index 490170d..0c0a3d8 100644 --- a/Tagger/Configuration.cs +++ b/Tagger/Configuration.cs @@ -9,4 +9,6 @@ public class User public class Configuration { public List Users { get; set; } = new(); + public string HomeAssistantUrl { get; set; } = ""; + public string HomeAssistantToken { get; set; } = ""; } diff --git a/Tagger/Pages/Page.razor b/Tagger/Pages/Page.razor index 6547d9f..230246d 100644 --- a/Tagger/Pages/Page.razor +++ b/Tagger/Pages/Page.razor @@ -1,10 +1,13 @@ @page "/page/{*Route}" @inject PageProvider Pages; @inject UserManager Users; +@inject ParsingManager Parser; @inject NavigationManager NavManager; @inject IJSRuntime JS +test + @if (CurrentPage is null) {

Page introuvable

@@ -57,10 +60,9 @@ else StateHasChanged(); } - Task OnMarkdownValueHTMLChanged(string value) + async Task OnMarkdownValueHTMLChanged(string value) { - markdownHtml = value; - return Task.CompletedTask; + markdownHtml = await Parser.Parse(value); } void Save() diff --git a/Tagger/Pages/Page.razor.css b/Tagger/Pages/Page.razor.css new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/Tagger/Pages/Page.razor.css @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Tagger/Program.cs b/Tagger/Program.cs index 64dcb07..63d245e 100644 --- a/Tagger/Program.cs +++ b/Tagger/Program.cs @@ -13,6 +13,7 @@ builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddHttpContextAccessor(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(sp => diff --git a/Tagger/RunEnv/Pages/pommier b/Tagger/RunEnv/Pages/pommier index ff1beaa..06e14df 100644 --- a/Tagger/RunEnv/Pages/pommier +++ b/Tagger/RunEnv/Pages/pommier @@ -1 +1,6 @@ -# turlutu \ No newline at end of file +# turlutu +{{display:number.kalanchoe_max_air_humidity}} + +{{minmax_display:sensor.kalanchoe_air_humidity,number.kalanchoe_min_air_humidity,number.kalanchoe_max_air_humidity}} + +{{minmax_display:sensor.bromelia_soil_moisture,number.kalanchoe_min_air_humidity,number.kalanchoe_max_air_humidity}} diff --git a/Tagger/Service/ParsingManager.cs b/Tagger/Service/ParsingManager.cs new file mode 100644 index 0000000..dcc94b5 --- /dev/null +++ b/Tagger/Service/ParsingManager.cs @@ -0,0 +1,106 @@ +using System.Globalization; +using System.Net.Http.Headers; +using System.Text.RegularExpressions; + +namespace Tagger.Service; + +public class HAResponse +{ + public string state { get; set; } +} + +public class ParsingManager +{ + Configuration Conf; + HttpClient Client; + string Pattern = @"\{\{([a-zA-Z0-9._]+)\:([a-zA-Z0-9._]+)(?:,([a-zA-Z0-9._]+))*\}\}"; + + readonly string SimpleDisplay = "display"; + readonly string MinMaxDisplay = "minmax_display"; + + public ParsingManager(IConfiguration configuration) + { + Conf = configuration.Get() ?? new(); + Client = new(); + Client.BaseAddress = new(Conf.HomeAssistantUrl); + Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Conf.HomeAssistantToken); + } + + public async Task Parse(string input) + { + return Regex.Replace(input, Pattern, (match) => + { + if (match.Groups.Count <= 1) + return ($"(Bad func at {match.Index}, not any func)"); + + var allArgs = match.Groups.Values.Skip(1).ToArray(); + + string func = allArgs[0].ToString().ToLower(); + List args = new(); + foreach (var i in allArgs.Skip(1)) + foreach (var j in i.Captures) + if(j is not null) + args.Add(j.ToString()); + + if(func == SimpleDisplay) + return ParseDisplay(args.ToArray()).Result; + else if(func == MinMaxDisplay) + return ParseMinMaxDisplay(args.ToArray()).Result; + else + return match.Value; + }); + } + + public async Task ParseDisplay(string[] args) + { + if(args.Length < 1) + return ($"(Bad {SimpleDisplay} call, need at least 1 argument)"); + + var r = await Get(args[0]).ConfigureAwait(false); + if (r is null) + return $"(Bad {SimpleDisplay} call, Not any result from call)"; + + return $"{r}"; + } + + public async Task ParseMinMaxDisplay(string[] args) + { + if (args.Length < 3) + return ($"(Bad {SimpleDisplay} call, need at least 3 argument)"); + + var val = await Get(args[0]).ConfigureAwait(false); + if (val is null) + return $"(Bad {SimpleDisplay} call, Not any result from call for main (1st) argument)"; + + var min = await Get(args[1]).ConfigureAwait(false); + if (min is null) + return $"(Bad {SimpleDisplay} call, Not any result from call for min (2nd) argument)"; + + var max = await Get(args[2]).ConfigureAwait(false); + if (max is null) + return $"(Bad {SimpleDisplay} call, Not any result from call for max (3th) argument)"; + + bool isOk = val > min && val < max; + string emoji = isOk ? "✔️" : "❌"; + string tag = isOk ? "numeric-value" : "numeric-value-error"; + return $"{val} {emoji} [{min}, {max}]"; + } + + public async Task Get(string item, CancellationToken tk = default) + { + try + { + var resp = await Client.GetFromJsonAsync(item, tk).ConfigureAwait(false); + if (resp is null) + return null; + + if (float.TryParse(resp.state, CultureInfo.InvariantCulture, out float value)) + return value; + return null; + } + catch(Exception e) + { + return null; + }; + } +} diff --git a/Tagger/wwwroot/css/site.css b/Tagger/wwwroot/css/site.css index 96b0583..f5a1fac 100644 --- a/Tagger/wwwroot/css/site.css +++ b/Tagger/wwwroot/css/site.css @@ -66,3 +66,17 @@ a, .btn-link { .blazor-error-boundary::after { content: "An error has occurred." } + +.numeric-value { + color: blue; +} + +.numeric-value-error { + color: red; + font-weight: bold; +} + +.numeric-value-range{ + +} +