@page "/consumables"
@inject ConsumableService ConsumablesSvc
@using MudBlazor
MeterVault — Consumables
Oil / consumables
Last 12 months
Last 24 months
Last 5 years
All time
@if (_items is null)
{
}
else if (_items.Count == 0)
{
No consumable meters found. Add a meter with mode ConsumableBalance and a tank, or load the reference
data from Import.
}
else
{
@foreach (var item in _items)
{
@item.Name
Tank level
@(item.CurrentLevel is { } l ? $"{Format.Number(l, 0)} {item.Unit}" : "—")
@Format.Number(item.FillFraction * 100, 0)% of @Format.Number(item.Capacity, 0) @item.Unit
@if (item.PhysicalLevel is { } cm && item.PhysicalUnit is "cm")
{
· @Format.Number(cm, 0) cm
}
@if (item.LevelAsOf is { } asOf)
{
· as of @asOf.ToString("yyyy-MM-dd")
}
Used (range)
@Format.Number(item.ConsumptionInRange, 0) @item.Unit
Burner runtime
@(item.BurnerHours is { } h ? $"{Format.Number(h, 0)} h" : "—")
Effective rate
@if (item.FixedRate is { } fr)
{
@Format.Number(fr, 2) @item.Unit/h
}
else if (item.EffectiveRate is { } er)
{
@Format.Number(er, 2) @item.Unit/h
}
else
{
—
}
@(item.RateMode)
Cost (range)
@Format.Euro(item.CostInRange)
Forecast to empty
@(item.ForecastEmpty is { } fe ? fe.ToString("yyyy-MM-dd") : "—")
@if (item.AveragePerDay is { } apd)
{
(@Format.Number(apd, 1) @item.Unit/day)
}
Consumption by month
Deliveries (@item.Deliveries.Count)
@if (item.Deliveries.Count == 0)
{
No deliveries recorded.
}
else
{
| Date | Amount |
@foreach (var delivery in item.Deliveries)
{
| @delivery.Time.ToString("yyyy-MM-dd") |
@Format.Number(delivery.Amount, 0) @(delivery.Unit ?? item.Unit) |
}
}
}
}
@code {
private int _months = 60;
private bool _loading;
private IReadOnlyList? _items;
protected override Task OnInitializedAsync() => LoadAsync();
private async Task OnRangeChanged(int months)
{
_months = months;
await LoadAsync();
}
private async Task LoadAsync()
{
if (_loading)
{
return;
}
_loading = true;
_items = null;
try
{
var asOf = DateOnly.FromDateTime(DateTime.UtcNow);
var from = asOf.AddMonths(-_months);
_items = await ConsumablesSvc.GetConsumablesAsync(new DateOnly(from.Year, from.Month, 1), asOf.AddMonths(1));
}
finally
{
_loading = false;
}
}
private static IReadOnlyList ChartFor(ConsumableSummary item)
{
var points = item.Months
.Select(m => new SeriesChart.Point(m.Period.ToString("MMM yy", System.Globalization.CultureInfo.InvariantCulture), m.Consumption))
.ToList();
return [new SeriesChart.SeriesDef($"{item.Unit} used", ApexCharts.SeriesType.Bar, points)];
}
private static Color FillColor(double fraction) => fraction switch
{
< 0.15 => Color.Error,
< 0.30 => Color.Warning,
_ => Color.Success,
};
}