Refactor NucuCar.Sensors Bme680Sensor singleton class to use dependency injection

This commit is contained in:
Denis-Cosmin Nutiu 2019-11-24 18:03:46 +02:00
parent fa6ca8d226
commit 118dbd0086
7 changed files with 50 additions and 38 deletions

View file

@ -8,6 +8,7 @@ enum SensorStateEnum {
Error = 0;
Uninitialized = 1;
Initialized = 2;
Disabled = 3;
}
// Environment Sensor

View file

@ -10,14 +10,14 @@ namespace NucuCar.Sensors.EnvironmentSensor
/// EnvironmentSensor's gRPC service.
/// It allows reading the sensor's data using remote procedure calls.
/// </summary>
public class GrpcService : EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceBase
public class Bme680GrpcService : EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceBase
{
private readonly ILogger<GrpcService> _logger;
private readonly ILogger<Bme680GrpcService> _logger;
private readonly Bme680Sensor _bme680Sensor;
public GrpcService(ILogger<GrpcService> logger)
public Bme680GrpcService(ILogger<Bme680GrpcService> logger, Bme680Sensor bme680Sensor)
{
_bme680Sensor = Bme680Sensor.Instance;
_bme680Sensor = bme680Sensor;
_logger = logger;
}

View file

@ -4,6 +4,7 @@ using System.Device.I2c;
using System.Threading.Tasks;
using Iot.Device.Bmxx80;
using Iot.Device.Bmxx80.PowerMode;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry;
using NucuCarSensorsProto;
@ -16,23 +17,26 @@ namespace NucuCar.Sensors.EnvironmentSensor
/// </summary>
public class Bme680Sensor : IDisposable, ITelemeter
{
public ILogger Logger;
private readonly ILogger _logger;
private I2cConnectionSettings _i2CSettings;
private I2cDevice _i2CDevice;
private Bme680 _bme680;
private EnvironmentSensorMeasurement _lastMeasurement;
private SensorStateEnum _sensorStateEnum;
/* Singleton Instance */
public static Bme680Sensor Instance { get; } = new Bme680Sensor();
static Bme680Sensor()
{
}
private Bme680Sensor()
public Bme680Sensor(ILogger<Bme680Sensor> logger, IConfiguration configuration)
{
_sensorStateEnum = SensorStateEnum.Uninitialized;
_logger = logger;
if (configuration.GetValue<bool>("EnvironmentSensor:Enabled"))
{
InitializeSensor();
}
else
{
_logger?.LogInformation("BME680 Sensor is disabled!");
_sensorStateEnum = SensorStateEnum.Disabled;
}
}
public EnvironmentSensorMeasurement GetMeasurement()
@ -72,12 +76,12 @@ namespace NucuCar.Sensors.EnvironmentSensor
_bme680.SetPressureSampling(Sampling.UltraLowPower);
_sensorStateEnum = SensorStateEnum.Initialized;
Logger?.LogInformation($"{DateTimeOffset.Now}:BME680 Sensor initialization OK.");
_logger?.LogInformation($"{DateTimeOffset.Now}:BME680 Sensor initialization OK.");
}
catch (System.IO.IOException e)
{
Logger?.LogError($"{DateTimeOffset.Now}:BME680 Sensor initialization FAIL.");
Logger?.LogTrace(e.Message);
_logger?.LogError($"{DateTimeOffset.Now}:BME680 Sensor initialization FAIL.");
_logger?.LogTrace(e.Message);
_sensorStateEnum = SensorStateEnum.Error;
}
}
@ -86,7 +90,7 @@ namespace NucuCar.Sensors.EnvironmentSensor
{
if (_sensorStateEnum != SensorStateEnum.Initialized)
{
Logger?.LogWarning(
_logger?.LogWarning(
$"{DateTimeOffset.Now}:BME680: Attempting to take measurement while sensor is not initialized!");
return;
}
@ -98,8 +102,8 @@ namespace NucuCar.Sensors.EnvironmentSensor
_lastMeasurement.Pressure = await _bme680.ReadPressureAsync();
_lastMeasurement.Humidity = await _bme680.ReadHumidityAsync();
Logger?.LogInformation($"{DateTimeOffset.Now}:BME680: reading");
Logger?.LogInformation(
_logger?.LogInformation($"{DateTimeOffset.Now}:BME680: reading");
_logger?.LogInformation(
$"{_lastMeasurement.Temperature:N2} \u00B0C | {_lastMeasurement.Pressure:N2} hPa | {_lastMeasurement.Humidity:N2} %rH");
}

View file

@ -13,23 +13,25 @@ namespace NucuCar.Sensors.EnvironmentSensor
/// EnvironmentSensor's background service worker.
/// It does periodic reads from the sensors and publishes telemetry data if the option is enabled.
/// </summary>
public class BackgroundWorker : BackgroundService
public class Bme680Worker : BackgroundService
{
private readonly bool _serviceEnabled;
private readonly bool _telemetryEnabled;
private readonly int _measurementDelay;
private readonly ILogger<BackgroundWorker> _logger;
private readonly ILogger<Bme680Worker> _logger;
private readonly TelemetryPublisher _telemetryPublisher;
private readonly Bme680Sensor _bme680Sensor;
public BackgroundWorker(ILogger<BackgroundWorker> logger, IConfiguration config,
SensorTelemetry sensorTelemetry)
public Bme680Worker(ILogger<Bme680Worker> logger, IConfiguration config,
SensorTelemetry sensorTelemetry, Bme680Sensor bme680Sensor)
{
_logger = logger;
_serviceEnabled = config.GetValue<bool>("EnvironmentSensor:Enabled");
_telemetryEnabled = config.GetValue<bool>("EnvironmentSensor:Telemetry");
_measurementDelay = config.GetValue<int>("EnvironmentSensor:MeasurementInterval");
_telemetryPublisher = sensorTelemetry.Publisher;
_bme680Sensor = bme680Sensor;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
@ -38,33 +40,30 @@ namespace NucuCar.Sensors.EnvironmentSensor
{
return;
}
using var sensor = Bme680Sensor.Instance;
sensor.Logger = _logger;
sensor.InitializeSensor();
if (_telemetryEnabled)
{
_telemetryPublisher?.RegisterTelemeter(sensor);
_telemetryPublisher?.RegisterTelemeter(_bme680Sensor);
}
while (!stoppingToken.IsCancellationRequested)
{
/* If sensor is ok attempt to read. */
if (sensor.GetState() == SensorStateEnum.Initialized)
if (_bme680Sensor.GetState() == SensorStateEnum.Initialized)
{
await sensor.TakeMeasurement();
await _bme680Sensor.TakeMeasurement();
}
/* Else attempt to re-initialize. */
else
{
await Task.Delay(10000, stoppingToken);
sensor.InitializeSensor();
_bme680Sensor.InitializeSensor();
}
await Task.Delay(_measurementDelay, stoppingToken);
}
_telemetryPublisher?.UnRegisterTelemeter(sensor);
_telemetryPublisher?.UnRegisterTelemeter(_bme680Sensor);
}
}
}

View file

@ -29,7 +29,7 @@ namespace NucuCar.Sensors
app.UseEndpoints(endpoints =>
{
// Add the gRPC services here.
endpoints.MapGrpcService<EnvironmentSensor.GrpcService>();
endpoints.MapGrpcService<EnvironmentSensor.Bme680GrpcService>();
endpoints.MapGet("/",
async context =>

View file

@ -20,15 +20,23 @@ namespace NucuCar.Sensors
// Singletons
services.AddSingleton<Telemetry.SensorTelemetry>();
services.AddSingleton<EnvironmentSensor.Bme680Sensor>();
// Workers
if (config.GetValue<bool>("Telemetry:Enabled"))
{
services.AddHostedService<Telemetry.TelemetryBackgroundWorker>();
services.AddHostedService<Telemetry.TelemetryWorker>();
}
services.AddHostedService<EnvironmentSensor.BackgroundWorker>();
if (config.GetValue<bool>("EnvironmentSensor:Enabled"))
{
services.AddHostedService<EnvironmentSensor.Bme680Worker>();
}
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<GrpcStartup>(); });
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<GrpcStartup>();
});
}
}

View file

@ -10,13 +10,13 @@ namespace NucuCar.Sensors.Telemetry
/// <summary>
/// Telemetry service, which pools the telemetry sources and pushes telemetry data to the cloud.
/// </summary>
public class TelemetryBackgroundWorker : BackgroundService
public class TelemetryWorker : BackgroundService
{
private readonly int _interval;
private readonly ILogger _logger;
private readonly TelemetryPublisher _telemetryPublisher;
public TelemetryBackgroundWorker(ILogger<TelemetryBackgroundWorker> logger, IConfiguration configuration,
public TelemetryWorker(ILogger<TelemetryWorker> logger, IConfiguration configuration,
SensorTelemetry sensorTelemetry)
{
_logger = logger;