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._]+))*\}\}"; Dictionary Buffer = new(); readonly string SimpleDisplay = "display"; readonly string MinMaxDisplay = "minmax_display"; readonly string MinMaxEmoji = "minmax_emoji"; 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) { lock (Buffer) Buffer.Clear(); 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 if(func == MinMaxEmoji) return ParseMinMaxEmoji(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 tag = isOk ? "numeric-value-ok" : "numeric-value-error"; return $" {val}"; } public async Task ParseMinMaxEmoji(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 ? "✅" : "⚠️"; return emoji; } public async Task Get(string item, CancellationToken tk = default) { try { lock(Buffer) { if(Buffer.ContainsKey(item)) return (float?)Buffer[item]; var resp = Client.GetFromJsonAsync(item, tk).Result; if (resp is null) return null; if (float.TryParse(resp.state, CultureInfo.InvariantCulture, out float value)) { Buffer.Add(item, value ); return value; } return null; } } catch(Exception e) { return null; }; } }