realtime uppdate

Eduardo Gomez Romero 825 Reputation points
2024-10-01T20:29:59.3+00:00

I have a service that start a timer

    public class TurbinesService(DeviceLanguageService deviceLanguageService) {

        private const int HoursDay = 24;
        private const int MinutesDay = 60;
        private const double IncrementValue = 0.0007;
        private readonly DeviceLanguageService _deviceLanguageService = deviceLanguageService;
        private bool isRunning;
        private ObservableCollection<TurbinePin> _turbinePins = [];

        public ObservableCollection<TurbinePin> GetTurbinePins(ICommand pinClickedCommand) {
            _turbinePins = [
                new() {
                Turbine = new Turbine(_deviceLanguageService) {
                    Id = 1,
                    Name = "Solar Generator",
                    Label = "Charge station",
                    Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
                    Location = new Location(-2.151993, -79.886109),
                    InstalationDateTime = new DateTime(2024, 8, 2),
                    Images = ["charge_station.png", "wind_turbine.png"]
                },
                PinClickedCommand = pinClickedCommand
            }
            ];

            foreach (var pin in _turbinePins) {
                CalculateAndSetValues(pin.Turbine!);
            }

            return _turbinePins;
        }

        public void StartIncrementingAllTurbines() {
            if (!isRunning) {
                isRunning = true;
                foreach (var pin in _turbinePins) {
                    StartIncrementingRemovedCo2Kilograms(pin.Turbine!);
                }
            }
        }

        private void CalculateAndSetValues(Turbine turbine) {
            var energyPerDay = RoundToDecimals(turbine.TurbinePower * turbine.TurbineCapacityFactor * HoursDay);
            var energyPerHour = RoundToDecimals(energyPerDay / HoursDay, 4);
            var energyPerSecond = RoundToDecimals(energyPerHour / MinutesDay, 5);
            var removedCo2PerSecond = RoundToDecimals(energyPerSecond * turbine.TurbineEmissionOffset, 5);
            var daysPassedSinceInstallation = (DateTime.Today - turbine.InstalationDateTime).Days;
            var energyProduced = RoundToDecimals(energyPerDay * daysPassedSinceInstallation);
            var removedCo2Kilograms = RoundToDecimals(turbine.CalculatedRemovedCo2Kilograms, 3);

            turbine.RemovedCo2Kilograms = removedCo2Kilograms;
            Debug.WriteLine($"Initial RemovedCo2Kilograms: {turbine.RemovedCo2Kilograms}");
        }

        private async void StartIncrementingRemovedCo2Kilograms(Turbine turbine) {
            while (isRunning) {
                await Task.Delay(1000);  // Increment every second

                // Increment RemovedCo2Kilograms by 0.0007
                UpdateRemovedCo2Kilograms(turbine, IncrementValue);
            }
        }

        private void UpdateRemovedCo2Kilograms(Turbine turbine, double increment) {
            turbine.RemovedCo2Kilograms += increment;

            // Round to 3 decimal places
            turbine.RemovedCo2Kilograms = RoundToDecimals(turbine.RemovedCo2Kilograms, 3);
            Debug.WriteLine($"Updated RemovedCo2Kilograms: {turbine.RemovedCo2Kilograms}");
        }

        private double RoundToDecimals(double value, int decimals = 2) {
            return Math.Round(value, decimals);
        }
    }
}


And I call this OnAppStart so it will start the timer

 public App(AppShell appShell, TurbinesService _turbinesService) {
     Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(AppConstants.SYNCFUSION_KEY);

     InitializeComponent();

     MainPage = appShell;

     turbinesService = _turbinesService;
 }

 protected override void OnStart() {
     base.OnStart();
     // Start the incrementation logic here
     turbinesService.StartIncrementingAllTurbines();
 }

I want to use this in two places

    public partial class TurbinesCollectionPageViewModel(TurbinesService turbinesService)
        : ChargingStationsMapPageViewModel(turbinesService) {

    }

  <CollectionView.ItemTemplate>
      <DataTemplate x:DataType="model:TurbinePin">
          <Grid>
              <Border Style="{StaticResource CommonBorderStyle}">
                  <Grid
                      ColumnDefinitions="Auto,*"
                      RowDefinitions="30,*,*">
                      <Label
                          Style="{StaticResource CommonLabelStyle}"
                          Text="{Binding Turbine.Name}" />
                      <Label
                          Grid.Row="1"
                          Style="{StaticResource CommonLabelStyle}"
                          Text="{Binding Turbine.Address}" />
                      <Label
                          Grid.Row="2"
                          Style="{StaticResource CommonLabelStyle}"
                          Text="{Binding Turbine.LocalizedInstalationDateTime}" />

                      <Label
                          Grid.RowSpan="3"
                          Grid.Column="1"
                          Grid.ColumnSpan="2"
                          Text="{Binding Turbine.RemovedCo2Kilograms}"
                          VerticalOptions="Center"
                          VerticalTextAlignment="Center" />

and here

 [QueryProperty(nameof(SelectedTurbine), "SelectedTurbine")]
 public partial class TurbineDetailPageViewModel : ObservableObject {
     [ObservableProperty]
     Turbine? selectedTurbine;
     [RelayCommand]
     void Appear() {
         if (SelectedTurbine == null) {
             return;
         }
     }
<Border
    Grid.Row="4"
    Grid.Column="1"
    Padding="5">
    <Label
        BackgroundColor="Yellow"
        FontAttributes="Bold"
        HorizontalTextAlignment="Center"
        Text="{Binding SelectedTurbine.RemovedCo2Kilograms, StringFormat='{0} kg Co2'}" />
</Border>


but it doesn't update in real time, is not incrementing (I just see a static number)

User's image

Net 8

Maui 8.0.9

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,581 questions
{count} votes

Accepted answer
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 32,306 Reputation points Microsoft Vendor
    2024-10-02T07:25:00.0666667+00:00

    Hello,

    As you said, you have resolved the problem.

    I was using this

    private async void StartIncrementingRemovedCo2Kilograms(Turbine turbine) {
                while (isRunning) {
                    await Task.Delay(1000);  // Increment every second
    
                    // Increment RemovedCo2Kilograms by 0.0007
                    UpdateRemovedCo2Kilograms(turbine, IncrementValue);
                }
            }
    
            private void UpdateRemovedCo2Kilograms(Turbine turbine, double increment) {
                turbine.RemovedCo2Kilograms += increment;
    
                // Round to 3 decimal places
                turbine.RemovedCo2Kilograms = RoundToDecimals(turbine.RemovedCo2Kilograms, 3);
                Debug.WriteLine($"Updated RemovedCo2Kilograms: {turbine.RemovedCo2Kilograms}");
            }
    
            private double RoundToDecimals(double value, int decimals = 2) {
                return Math.Round(value, decimals);
            }
        }
    
    
    

    What I should have done is

           public TurbinesService(DeviceLanguageService deviceLanguageService, IDispatcher application) {
               _deviceLanguageService = deviceLanguageService;
               _dispatcher = application;
               InitializeTimer(); // Just initialize the timer, do not start it here
    
           }
    
           // Initialize the timer
           private void InitializeTimer() {
               _timer = _dispatcher.CreateTimer(); // Use the injected dispatcher
               _timer.Interval = TimeSpan.FromSeconds(1);
               _timer.Tick += (s, e) => UpdateTurbinesCo2();
           }
    
           public ObservableCollection<TurbinePin> GetTurbinePins(ICommand pinClickedCommand) {
               _turbinePins = [
                   new() {
                       Turbine = new Turbine(_deviceLanguageService) {
                           Id = 1,
                           Name = "Estación Ciudadela Simón Bolívar",
                           Label = "Charge station",
                           Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
                           Location = new Location(-2.151993, -79.886109),
                           InstalationDateTime = new DateTime(2024, 8, 2),
                           Images = ["charge_station.png", "wind_turbine.png"]
                       },
                       PinClickedCommand = pinClickedCommand
                   }
               ];
    
               foreach (var pin in _turbinePins) {
                   CalculateAndSetValues(pin.Turbine!);
               }
    
               // Do not start the timer here
               return _turbinePins;
           }
    
           // Start the timer explicitly
           public void StartTimer() {
               if (!isTimerRunning) {
                   _timer!.Start();
                   isTimerRunning = true;
               }
           }
    
           // Method to handle updating CO2 every second
           private void UpdateTurbinesCo2() {
               foreach (var pin in _turbinePins) {
                   var turbine = pin.Turbine;
                   if (turbine != null) {
                       turbine.RemovedCo2Kilograms += turbine.RemovedCo2PerSecond;  // Update CO2 every second
                       turbine.RemovedCo2Kilograms = RoundToDecimals(turbine.RemovedCo2Kilograms, 3);
                   }
               }
           }
    
    

    and register a dispatcher as a dependency

    Thanks for your sharing.

    Best Regards,

    Wenyan Zhang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.