@page "/"
@using InverterMon.Shared.Models
@using System.Text.Json
@implements IDisposable
Dashboard
@if (status is not null)
{
@if (status.GridUsageWatts > 100)
{
}
Charging
@status.BatteryChargeWatts
W
@status.BatteryChargeCurrent
A
@GetChargeMode()
@status.BatteryVoltage
V
@GetCRate() C
Discharging
@status.BatteryDischargeWatts
W
@status.BatteryDischargeCurrent
A
}
@code{
private static event Action? onStatusUpdated;
private static event Action? onStatusRetrievalError;
private static InverterStatus? status;
protected override void OnInitialized()
{
onStatusUpdated += UpdateState;
onStatusRetrievalError += NullifyStatus;
}
private void NullifyStatus()
{
status = null;
StateHasChanged();
}
private void UpdateState(InverterStatus? s)
{
status = s;
StateHasChanged();
}
public void Dispose()
{
onStatusUpdated -= UpdateState;
onStatusRetrievalError -= NullifyStatus;
}
public static async Task StartStatusStreaming(string basePath)
{
//note: only reason we have a full-time stream download is because there's a bug in
// blazor-wasm that doesn't close the fetch http requests when streaming is involved.
// and it leads to a new stream download being created everytime a page is initialized.
// which leads to a memory leak/ connection exhaustion.
using var client = new HttpClient();
client.BaseAddress = new(basePath);
client.Timeout = TimeSpan.FromSeconds(5);
var retryDelay = 1000;
while (true)
{
try
{
using var request = new HttpRequestMessage(HttpMethod.Get, "api/status");
request.SetBrowserResponseStreamingEnabled(true);
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
await foreach (var s in
JsonSerializer.DeserializeAsyncEnumerable(
stream,
new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
DefaultBufferSize = 64
}))
{
onStatusUpdated?.Invoke(s);
retryDelay = 1000;
}
}
catch (Exception)
{
onStatusRetrievalError?.Invoke();
await Task.Delay(retryDelay);
retryDelay += 500;
}
}
}
private static double GetCRate()
{
if (status?.BatteryChargeCRate > 0)
return status.BatteryChargeCRate;
if (status?.BatteryDischargeCRate > 0)
return status.BatteryDischargeCRate;
return 0;
}
private static string GetChargeMode()
=> status?.ChargeMode is ChargeMode.NONE
? "VOLTAGE"
: status?.ChargeMode.ToString() ?? string.Empty;
}