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; Error = 0;
Uninitialized = 1; Uninitialized = 1;
Initialized = 2; Initialized = 2;
Disabled = 3;
} }
// Environment Sensor // Environment Sensor

View file

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

View file

@ -4,6 +4,7 @@ using System.Device.I2c;
using System.Threading.Tasks; using System.Threading.Tasks;
using Iot.Device.Bmxx80; using Iot.Device.Bmxx80;
using Iot.Device.Bmxx80.PowerMode; using Iot.Device.Bmxx80.PowerMode;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NucuCar.Domain.Telemetry; using NucuCar.Domain.Telemetry;
using NucuCarSensorsProto; using NucuCarSensorsProto;
@ -16,23 +17,26 @@ namespace NucuCar.Sensors.EnvironmentSensor
/// </summary> /// </summary>
public class Bme680Sensor : IDisposable, ITelemeter public class Bme680Sensor : IDisposable, ITelemeter
{ {
public ILogger Logger; private readonly ILogger _logger;
private I2cConnectionSettings _i2CSettings; private I2cConnectionSettings _i2CSettings;
private I2cDevice _i2CDevice; private I2cDevice _i2CDevice;
private Bme680 _bme680; private Bme680 _bme680;
private EnvironmentSensorMeasurement _lastMeasurement; private EnvironmentSensorMeasurement _lastMeasurement;
private SensorStateEnum _sensorStateEnum; private SensorStateEnum _sensorStateEnum;
/* Singleton Instance */ public Bme680Sensor(ILogger<Bme680Sensor> logger, IConfiguration configuration)
public static Bme680Sensor Instance { get; } = new Bme680Sensor();
static Bme680Sensor()
{
}
private Bme680Sensor()
{ {
_sensorStateEnum = SensorStateEnum.Uninitialized; _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() public EnvironmentSensorMeasurement GetMeasurement()
@ -72,12 +76,12 @@ namespace NucuCar.Sensors.EnvironmentSensor
_bme680.SetPressureSampling(Sampling.UltraLowPower); _bme680.SetPressureSampling(Sampling.UltraLowPower);
_sensorStateEnum = SensorStateEnum.Initialized; _sensorStateEnum = SensorStateEnum.Initialized;
Logger?.LogInformation($"{DateTimeOffset.Now}:BME680 Sensor initialization OK."); _logger?.LogInformation($"{DateTimeOffset.Now}:BME680 Sensor initialization OK.");
} }
catch (System.IO.IOException e) catch (System.IO.IOException e)
{ {
Logger?.LogError($"{DateTimeOffset.Now}:BME680 Sensor initialization FAIL."); _logger?.LogError($"{DateTimeOffset.Now}:BME680 Sensor initialization FAIL.");
Logger?.LogTrace(e.Message); _logger?.LogTrace(e.Message);
_sensorStateEnum = SensorStateEnum.Error; _sensorStateEnum = SensorStateEnum.Error;
} }
} }
@ -86,7 +90,7 @@ namespace NucuCar.Sensors.EnvironmentSensor
{ {
if (_sensorStateEnum != SensorStateEnum.Initialized) if (_sensorStateEnum != SensorStateEnum.Initialized)
{ {
Logger?.LogWarning( _logger?.LogWarning(
$"{DateTimeOffset.Now}:BME680: Attempting to take measurement while sensor is not initialized!"); $"{DateTimeOffset.Now}:BME680: Attempting to take measurement while sensor is not initialized!");
return; return;
} }
@ -98,8 +102,8 @@ namespace NucuCar.Sensors.EnvironmentSensor
_lastMeasurement.Pressure = await _bme680.ReadPressureAsync(); _lastMeasurement.Pressure = await _bme680.ReadPressureAsync();
_lastMeasurement.Humidity = await _bme680.ReadHumidityAsync(); _lastMeasurement.Humidity = await _bme680.ReadHumidityAsync();
Logger?.LogInformation($"{DateTimeOffset.Now}:BME680: reading"); _logger?.LogInformation($"{DateTimeOffset.Now}:BME680: reading");
Logger?.LogInformation( _logger?.LogInformation(
$"{_lastMeasurement.Temperature:N2} \u00B0C | {_lastMeasurement.Pressure:N2} hPa | {_lastMeasurement.Humidity:N2} %rH"); $"{_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. /// EnvironmentSensor's background service worker.
/// It does periodic reads from the sensors and publishes telemetry data if the option is enabled. /// It does periodic reads from the sensors and publishes telemetry data if the option is enabled.
/// </summary> /// </summary>
public class BackgroundWorker : BackgroundService public class Bme680Worker : BackgroundService
{ {
private readonly bool _serviceEnabled; private readonly bool _serviceEnabled;
private readonly bool _telemetryEnabled; private readonly bool _telemetryEnabled;
private readonly int _measurementDelay; private readonly int _measurementDelay;
private readonly ILogger<BackgroundWorker> _logger; private readonly ILogger<Bme680Worker> _logger;
private readonly TelemetryPublisher _telemetryPublisher; private readonly TelemetryPublisher _telemetryPublisher;
private readonly Bme680Sensor _bme680Sensor;
public BackgroundWorker(ILogger<BackgroundWorker> logger, IConfiguration config, public Bme680Worker(ILogger<Bme680Worker> logger, IConfiguration config,
SensorTelemetry sensorTelemetry) SensorTelemetry sensorTelemetry, Bme680Sensor bme680Sensor)
{ {
_logger = logger; _logger = logger;
_serviceEnabled = config.GetValue<bool>("EnvironmentSensor:Enabled"); _serviceEnabled = config.GetValue<bool>("EnvironmentSensor:Enabled");
_telemetryEnabled = config.GetValue<bool>("EnvironmentSensor:Telemetry"); _telemetryEnabled = config.GetValue<bool>("EnvironmentSensor:Telemetry");
_measurementDelay = config.GetValue<int>("EnvironmentSensor:MeasurementInterval"); _measurementDelay = config.GetValue<int>("EnvironmentSensor:MeasurementInterval");
_telemetryPublisher = sensorTelemetry.Publisher; _telemetryPublisher = sensorTelemetry.Publisher;
_bme680Sensor = bme680Sensor;
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
@ -39,32 +41,29 @@ namespace NucuCar.Sensors.EnvironmentSensor
return; return;
} }
using var sensor = Bme680Sensor.Instance;
sensor.Logger = _logger;
sensor.InitializeSensor();
if (_telemetryEnabled) if (_telemetryEnabled)
{ {
_telemetryPublisher?.RegisterTelemeter(sensor); _telemetryPublisher?.RegisterTelemeter(_bme680Sensor);
} }
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
/* If sensor is ok attempt to read. */ /* 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 attempt to re-initialize. */
else else
{ {
await Task.Delay(10000, stoppingToken); await Task.Delay(10000, stoppingToken);
sensor.InitializeSensor(); _bme680Sensor.InitializeSensor();
} }
await Task.Delay(_measurementDelay, stoppingToken); await Task.Delay(_measurementDelay, stoppingToken);
} }
_telemetryPublisher?.UnRegisterTelemeter(sensor); _telemetryPublisher?.UnRegisterTelemeter(_bme680Sensor);
} }
} }
} }

View file

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

View file

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

View file

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