I have a service, that is uploading to firestore
async Task LoadOrInitializeTurbineAsync() {
var turbinesRef = _firestoreDb!.Collection(collectionName);
var snapshot = await turbinesRef.GetSnapshotAsync();
if (snapshot.Count == 0) {
var turbine = new Turbine {
Id = "EC-G-SB",
Country = "Ecuador",
Name = "Estación Ciudadela Simón Bolívar",
Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
Latitude = -2.151993,
Longitude = -79.886109,
InstalationDateTime = new DateTime(2024, 8, 2, 0, 0, 0, DateTimeKind.Utc),
StringifyInstalationDate = DateTime.UtcNow.ToString("D"),
ImagesURL = [],
};
turbine.RemovedCo2Kilograms = Math.Round(turbine.EnergyProduced * turbine.Co2EmissionOffset, 5);
await AddTurbineImages(turbine);
var turbineDocRef = turbinesRef.Document(turbine.Id);
await turbineDocRef.SetAsync(turbine);
// Add to observable collection if necessary
AddToObservable(turbine);
}
else {
foreach (var document in snapshot.Documents) {
var turbine = document.ConvertTo<Turbine>();
turbine.Id = document.Id;
await AddTurbineImages(turbine);
AddToObservable(turbine);
}
}
}
private async Task AddTurbineImages(Turbine turbine) {
turbine.ImagesURL!.Clear();
var containerClient = _blobServiceClient.GetBlobContainerClient(turbine.Country!.ToLower());
await foreach (var item in containerClient.GetBlobsAsync()) {
var blobClient = containerClient.GetBlobClient(item.Name);
turbine.ImagesURL!.Add(blobClient.Uri.ToString());
}
}
private void AddToObservable(Turbine turbine) {
TurbinePins.Add(new TurbinePin { Turbine = turbine });
}
public ObservableCollection<TurbinePin> GetTurbinePinsForUI(ICommand pinClickedCommand) {
foreach (var pin in TurbinePins.OrderBy(t => t.Turbine?.InstalationDateTime)) {
pin.PinClickedCommand = pinClickedCommand;
}
return TurbinePins;
}
private void InitializeTimer() {
_timer = new System.Timers.Timer(1000); // 1000 milliseconds = 1 second
_timer.Elapsed += async (sender, e) => await UpdateCO2ValueAsync();
_timer.AutoReset = true;
_timer.Enabled = true;
}
private async Task UpdateCO2ValueAsync() {
var turbineRef = _firestoreDb!.Collection("turbines").Document("EC-G-SB");
var snapshot = await turbineRef.GetSnapshotAsync();
var turbine = snapshot.ConvertTo<Turbine>();
// Check initial value before update
var beforeUpdate = turbine.RemovedCo2Kilograms;
// Increment and round
turbine.RemovedCo2Kilograms = Math.Round(beforeUpdate + 0.0007, 5);
turbine.FinalCo2Removed = turbine.RemovedCo2Kilograms;
// Debug the values
Debug.WriteLine($"Before Update: {beforeUpdate}, After Update: {turbine.RemovedCo2Kilograms}");
await turbineRef.SetAsync(turbine, SetOptions.Overwrite);
}
}
I have my model
[FirestoreProperty]
public string? Id { get; set; }
[FirestoreProperty]
public string? Country { get; set; }
[FirestoreProperty]
public string? Name { get; set; }
[FirestoreProperty]
public string? Address { get; set; }
[FirestoreProperty]
public double Power { get; set; } = 0.37;
[FirestoreProperty]
public double Co2EmissionOffset { get; set; } = 0.45;
[FirestoreProperty]
public double CapacityFactor { get; set; } = 0.25;
[FirestoreProperty]
public double Latitude { get; set; }
[FirestoreProperty]
public double Longitude { get; set; }
[FirestoreProperty]
public DateTime InstalationDateTime { get; set; }
[FirestoreProperty]
public List<string>? ImagesURL { get; set; }
[FirestoreProperty]
public string? StringifyInstalationDate { get; set; }
public string? Label => Name; // Keeps the display label for the map
public Location Location => new(Latitude, Longitude);
[FirestoreProperty]
public double EnergyPerDay => RoundToDecimals(Power * CapacityFactor * 24);
[FirestoreProperty]
public double EnergyPerHour => RoundToDecimals(EnergyPerDay / 24, 4);
[FirestoreProperty]
public double EnergyPerSecond => RoundToDecimals(EnergyPerHour / 60, 5);
[FirestoreProperty]
public double RemovedCo2PerSecond => RoundToDecimals(EnergyPerSecond * Co2EmissionOffset, 5);
[FirestoreProperty]
public double DaysPassedSinceInstallation => (DateTime.Today - InstalationDateTime).Days;
[FirestoreProperty]
public double EnergyProduced => RoundToDecimals(EnergyPerDay * DaysPassedSinceInstallation);
[FirestoreProperty]
public double RemovedCo2Kilograms { get; set; }
[ObservableProperty]
public double finalCo2Removed;
private static double RoundToDecimals(double value, int decimals = 2) {
return Math.Round(value, decimals);
}
So, I bound this to a custom control
namespace METROWIND.Controls;
public partial class TurbineData : ContentView {
public TurbineData() {
InitializeComponent();
}
public static readonly BindableProperty TurbineNameProperty = BindableProperty.Create(
nameof(TurbineName), typeof(string), typeof(TurbineData));
public string TurbineName {
get => (string)GetValue(TurbineNameProperty);
set => SetValue(TurbineNameProperty, value);
}
public static readonly BindableProperty TurbineAddresProperty = BindableProperty.Create(
nameof(TurbineAddres), typeof(string), typeof(TurbineData));
public string TurbineAddres {
get => (string)GetValue(TurbineAddresProperty);
set => SetValue(TurbineAddresProperty, value);
}
public static readonly BindableProperty TurbineCreationDateProperty = BindableProperty.Create(
nameof(TurbineCreationDate), typeof(string), typeof(TurbineData));
public string TurbineCreationDate {
get => (string)GetValue(TurbineCreationDateProperty);
set => SetValue(TurbineCreationDateProperty, value);
}
public static readonly BindableProperty Co2KgRemovedProperty = BindableProperty.Create(
nameof(Co2KgRemoved), typeof(string), typeof(TurbineData));
public string Co2KgRemoved {
get => (string)GetValue(Co2KgRemovedProperty);
set => SetValue(Co2KgRemovedProperty, value);
}
public static readonly BindableProperty TapCommandProperty = BindableProperty.Create(
nameof(TapCommand), typeof(ICommand), typeof(TurbineData));
public ICommand TapCommand {
get => (ICommand)GetValue(TapCommandProperty);
set => SetValue(TapCommandProperty, value);
}
public static readonly BindableProperty TapCommandParameterProperty = BindableProperty.Create(
nameof(TapCommandParameter), typeof(object), typeof(TurbineData));
public object TapCommandParameter {
get => GetValue(TapCommandParameterProperty);
set => SetValue(TapCommandParameterProperty, value);
}
}
<Border Style="{x:StaticResource CommonBorderStyle}">
<VerticalStackLayout
BackgroundColor="#4D9B9B"
BindingContext="{x:Reference TurbineInfo}"
Spacing="-10">
<Label
FontAttributes="Bold"
Style="{x:StaticResource TurbineDataLabelStyleStyle}"
Text="{x:Binding TurbineName}" />
<Label
Style="{x:StaticResource TurbineDataLabelStyleStyle}"
Text="{x:Binding TurbineAddres}" />
<Label
Style="{x:StaticResource TurbineDataLabelStyleStyle}"
Text="{x:Binding TurbineCreationDate}" />
<Label
Style="{x:StaticResource C02LabelStyle}"
Text="{x:Binding Co2KgRemoved, StringFormat='{0:F5} kg CO₂'}" />
I use it here
<DataTemplate x:Key="turbineTemplte" x:DataType="model:TurbinePin">
<controls:TurbineData
Grid.ColumnSpan="2"
TapCommand="{x:Binding OnPinMarkerClickedCommand,
Source={x:RelativeSource AncestorType={x:Type vm:TurbinesCollectionPageViewModel}}}"
TapCommandParameter="{x:Binding Turbine}"
TurbineAddres="{x:Binding Turbine.Address}"
Co2KgRemoved="{x:Binding Turbine.FinalCo2Removed}"
TurbineCreationDate="{x:Binding Turbine.StringifyInstalationDate}"
TurbineName="{x:Binding Turbine.Name}" />
</DataTemplate>
I want to show the update on realtime, bit it dosent work
the change in the co2 in the Ui in my collection view that is using tat template
https://reccloud.com/u/kr1pptr