private async Task PerformUpdate(CancellationToken stoppingToken) { DateTime lastAutomaticMeasurement = DateTime.MinValue; DateTime lastMeasurement = DateTime.MinValue; TimeSpan?measureInterval = null; List <SwimmingPoolLastMeasurementsGetResponse> measurements = new List <SwimmingPoolLastMeasurementsGetResponse>(); SwimmingPool pool = _pool; _updateManager.Process(pool, pool); _logger.LogDebug("Fetching blue devices for {Id} ({Name})", pool.SwimmingPoolId, pool.Name); SwimmingPoolBlueDevicesGetResponse blueDevices = await _blueClient.GetSwimmingPoolBlueDevices(pool.SwimmingPoolId, stoppingToken); bool anyBlueDeviceIsAwake = false; foreach (SwimmingPoolDevice blueDevice in blueDevices.Data) { _logger.LogDebug("Fetching measurements for {Id}, blue {Serial} ({Name})", pool.SwimmingPoolId, blueDevice.BlueDeviceSerial, pool.Name); _updateManager.Process(pool, blueDevice); SwimmingPoolLastMeasurementsGetResponse blueMeasurement = await _blueClient.GetBlueLastMeasurements(pool.SwimmingPoolId, blueDevice.BlueDeviceSerial, token : stoppingToken); if (blueDevice.BlueDevice.WakePeriod > 0) { measureInterval = ComparisonHelper.GetMin(measureInterval, TimeSpan.FromSeconds(blueDevice.BlueDevice.WakePeriod)); } measurements.Add(blueMeasurement); // Track the last measurement time in order to calculate the next expected measurement. // For now, this includes Gateway & sigfox measurements, as these are automated. // Manual bluetooth measurements do not affect the interval lastAutomaticMeasurement = ComparisonHelper.GetMax(lastAutomaticMeasurement, blueDevice.BlueDevice.LastMeasureMessageSigfox, blueDevice.BlueDevice.LastMeasureMessageGateway).GetValueOrDefault(); lastMeasurement = ComparisonHelper.GetMax(lastMeasurement, blueDevice.BlueDevice.LastMeasureMessage, blueDevice.BlueDevice.LastMeasureMessageBle, blueDevice.BlueDevice.LastMeasureMessageSigfox).GetValueOrDefault(); // Track sleep states anyBlueDeviceIsAwake |= blueDevice.BlueDevice.SleepState == "awake"; } _logger.LogDebug("Fetching guidance for {Id} ({Name})", pool.SwimmingPoolId, pool.Name); SwimmingPoolGuidanceGetResponse guidance = await _blueClient.GetSwimmingPoolGuidance(pool.SwimmingPoolId, _config.Language, token : stoppingToken); _updateManager.Process(pool, guidance); _logger.LogDebug("Fetching measurements for {Id} ({Name})", pool.SwimmingPoolId, pool.Name); SwimmingPoolLastMeasurementsGetResponse measurement = await _blueClient.GetSwimmingPoolLastMeasurements(pool.SwimmingPoolId, stoppingToken); measurements.Add(measurement); lastMeasurement = ComparisonHelper.GetMax(lastMeasurement, measurement.LastStripTimestamp, measurement.LastBlueMeasureTimestamp).GetValueOrDefault(); _updateManager.Process(pool, measurements); _logger.LogDebug("Fetching weather for {Id} ({Name})", pool.SwimmingPoolId, pool.Name); SwimmingPoolWeatherGetResponse weather = await _blueClient.GetSwimmingPoolWeather(pool.SwimmingPoolId, _config.Language, stoppingToken); _updateManager.Process(pool, weather.Data); //_logger.LogDebug("Fetching status for {Id} ({Name})", pool.SwimmingPoolId, pool.Name); //SwimmingPoolStatusGetResponse status = await _blueClient.GetSwimmingPoolStatus(pool.SwimmingPoolId, stoppingToken); //_updateManager.Update(pool, status); _delayCalculator.TrackMeasureInterval(measureInterval); _delayCalculator.TrackLastAutoMeasurement(lastAutomaticMeasurement); _delayCalculator.TrackSleepState(anyBlueDeviceIsAwake); if (lastMeasurement > _lastMeasurement) { _lastMeasurement = lastMeasurement; if (_config.ReportUnchangedValues) { // A new measurement was made, report potentially unchanged values _hassMqttManager.MarkAllValuesDirty(); } } }