NUC-32: Implement PMS5003 Sensor

This commit is contained in:
Denis-Cosmin Nutiu 2021-04-24 21:44:54 +03:00
parent 1034087553
commit 7bf36ed53a
13 changed files with 191 additions and 33 deletions

View file

@ -0,0 +1,11 @@
namespace NucuCar.Sensors
{
public class BaseSensorConfig
{
public bool Enabled { get; set; } = false;
public bool Telemetry { get; set; } = false;
public bool Grpc { get; set; } = false;
public int MeasurementInterval { get; set; } = 3000;
}
}

View file

@ -2,10 +2,7 @@
namespace NucuCar.Sensors.Modules.Environment
{
public class Bme680Config
public class Bme680Config : BaseSensorConfig
{
public bool Enabled { get; set; }
public bool Telemetry { get; set; }
public bool Grpc { get; set; }
}
}

View file

@ -1,14 +1,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NucuCar.Sensors.Abstractions;
namespace NucuCar.Sensors.Modules.Environment
{
public class Bme680Worker : SensorWorker
{
public Bme680Worker(ILogger<Bme680Worker> logger, Telemetry.Telemetry telemetry, ISensor<Bme680Sensor> sensor)
public Bme680Worker(ILogger<Bme680Worker> logger, Telemetry.Telemetry telemetry, ISensor<Bme680Sensor> sensor,
IOptions<Bme680Config> options)
{
Logger = logger;
MeasurementInterval = 3000;
MeasurementInterval = options.Value.MeasurementInterval;
TelemetryPublisher = telemetry.Publisher;
Sensor = sensor.Object;
}

View file

@ -1,10 +1,7 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace NucuCar.Sensors.Modules.Health
{
public class CpuTempConfig
public class CpuTempConfig : BaseSensorConfig
{
public bool Enabled { get; set; }
public bool Telemetry { get; set; }
public bool Grpc { get; set; }
}
}

View file

@ -1,14 +1,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NucuCar.Sensors.Abstractions;
namespace NucuCar.Sensors.Modules.Health
{
public class CpuTempWorker : SensorWorker
{
public CpuTempWorker(ILogger<CpuTempWorker> logger, Telemetry.Telemetry telemetry, ISensor<CpuTempSensor> sensor)
public CpuTempWorker(ILogger<CpuTempWorker> logger, Telemetry.Telemetry telemetry,
ISensor<CpuTempSensor> sensor, IOptions<CpuTempConfig> options)
{
Logger = logger;
MeasurementInterval = 3000;
MeasurementInterval = options.Value.MeasurementInterval;
TelemetryPublisher = telemetry.Publisher;
Sensor = sensor.Object;
}

View file

@ -1,9 +1,7 @@
namespace NucuCar.Sensors.Modules.Heartbeat
{
public class HeartbeatConfig
public class HeartbeatConfig : BaseSensorConfig
{
public bool Enabled { get; set; }
public bool Telemetry { get; set; }
public bool Grpc { get; } = false;
}
}

View file

@ -1,14 +1,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NucuCar.Sensors.Abstractions;
namespace NucuCar.Sensors.Modules.Heartbeat
{
public class HeartbeatWorker : SensorWorker
{
public HeartbeatWorker(ILogger<HeartbeatWorker> logger, Telemetry.Telemetry telemetry, ISensor<HeartbeatSensor> sensor)
public HeartbeatWorker(ILogger<HeartbeatWorker> logger, Telemetry.Telemetry telemetry,
ISensor<HeartbeatSensor> sensor, IOptions<HeartbeatConfig> options)
{
Logger = logger;
MeasurementInterval = 3000;
MeasurementInterval = options.Value.MeasurementInterval;
TelemetryPublisher = telemetry.Publisher;
Sensor = sensor.Object;
}

View file

@ -0,0 +1,6 @@
namespace NucuCar.Sensors.Modules.PMS5003
{
public class Pms5003Config : BaseSensorConfig
{
}
}

View file

@ -0,0 +1,7 @@
namespace NucuCar.Sensors.Modules.PMS5003
{
public class Pms5003GrpcService
{
}
}

View file

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NucuCar.Sensors.Abstractions;
using NucuCarSensorsProto;
using PMS5003;
using PMS5003.Exceptions;
namespace NucuCar.Sensors.Modules.PMS5003
{
public class Pms5003Sensor : GenericTelemeterSensor, IDisposable, ISensor<Pms5003Sensor>
{
private Pms5003 _pms5003;
private Pms5003Data _pms5003Data;
public Pms5003Sensor()
{
}
public Pms5003Sensor(ILogger<Pms5003Sensor> logger, IOptions<Pms5003Config> options)
{
CurrentState = SensorStateEnum.Uninitialized;
Logger = logger;
if (!options.Value.Enabled)
{
Logger?.LogDebug("Pms5003 Sensor is disabled!");
CurrentState = SensorStateEnum.Disabled;
}
TelemetryEnabled = options.Value.Telemetry;
}
public override void Initialize()
{
_pms5003 = new Pms5003(23, 24);
}
public override Task TakeMeasurementAsync()
{
try
{
_pms5003Data = _pms5003.ReadData();
}
catch (ReadFailedException e)
{
Logger?.LogError("{message}", e.Message);
}
return Task.CompletedTask;
}
public override NucuCarSensorResponse GetMeasurement()
{
string jsonResponse = null;
jsonResponse = _pms5003Data != null ? JsonConvert.SerializeObject(_pms5003Data) : "{}";
return new NucuCarSensorResponse()
{
State = GetState(),
JsonData = jsonResponse
};
}
public override SensorStateEnum GetState()
{
return CurrentState;
}
public override string GetIdentifier()
{
return "Pms5003";
}
public override Dictionary<string, object> GetTelemetryData()
{
Dictionary<string, object> returnValue = null;
if (_pms5003Data != null && TelemetryEnabled)
{
returnValue = new Dictionary<string, object>
{
["sensor_state"] = GetState(),
["Pm1Atmospheric"] = _pms5003Data.Pm1Atmospheric,
["Pm1Standard"] = _pms5003Data.Pm1Standard,
["Pm10Atmospheric"] = _pms5003Data.Pm10Atmospheric,
["Pm10Standard"] = _pms5003Data.Pm10Standard,
["Pm2Dot5Atmospheric"] = _pms5003Data.Pm2Dot5Atmospheric,
["Pm2Dot5Standard"] = _pms5003Data.Pm2Dot5Standard,
["ParticlesDiameterBeyond0Dot3"] = _pms5003Data.ParticlesDiameterBeyond0Dot3,
["ParticlesDiameterBeyond0Dot5"] = _pms5003Data.ParticlesDiameterBeyond0Dot5,
["ParticlesDiameterBeyond1Dot0"] = _pms5003Data.ParticlesDiameterBeyond1Dot0,
["ParticlesDiameterBeyond2Dot5"] = _pms5003Data.ParticlesDiameterBeyond2Dot5,
["ParticlesDiameterBeyond5Dot0"] = _pms5003Data.ParticlesDiameterBeyond5Dot0,
["ParticlesDiameterBeyond10Dot0"] = _pms5003Data.ParticlesDiameterBeyond10Dot0,
};
}
return returnValue;
}
public override bool IsTelemetryEnabled()
{
return TelemetryEnabled;
}
public void Dispose()
{
_pms5003 = null;
}
public Pms5003Sensor Object => this;
}
}

View file

@ -0,0 +1,18 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NucuCar.Sensors.Abstractions;
namespace NucuCar.Sensors.Modules.PMS5003
{
public class Pms5003Worker : SensorWorker
{
public Pms5003Worker(ILogger<Pms5003Worker> logger, Telemetry.Telemetry telemetry,
ISensor<Pms5003Sensor> sensor, IOptions<Pms5003Config> options)
{
Logger = logger;
MeasurementInterval = options.Value.MeasurementInterval;
TelemetryPublisher = telemetry.Publisher;
Sensor = sensor.Object;
}
}
}

View file

@ -6,12 +6,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.25.0" />
<PackageReference Include="Iot.Device.Bindings" Version="1.2.0" />
<PackageReference Include="jose-jwt" Version="2.5.0" />
<PackageReference Include="libgrpc_csharp_ext.arm7" Version="1.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.3" />
<PackageReference Include="System.Device.Gpio" Version="1.2.0" />
<PackageReference Include="Grpc.AspNetCore" Version="2.37.0" />
<PackageReference Include="Iot.Device.Bindings" Version="1.4.0" />
<PackageReference Include="jose-jwt" Version="3.1.1" />
<PackageReference Include="libgrpc_csharp_ext.arm7" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-preview.3.21201.4" />
<PackageReference Include="PMS5003" Version="1.0.4" />
<PackageReference Include="System.Device.Gpio" Version="1.4.0" />
</ItemGroup>
<ItemGroup>

View file

@ -43,7 +43,8 @@ namespace NucuCar.UnitTests.NucuCar.Sensors.Tests
{
Enabled = true,
});
var service = new Bme680Worker(_mockLogger.Object, _mockSensorTelemetry.Object, _mockBme680ISensor.Object);
var service = new Bme680Worker(_mockLogger.Object, _mockSensorTelemetry.Object, _mockBme680ISensor.Object,
new OptionsWrapper<Bme680Config>(new Bme680Config()));
await service.StartAsync(_cts.Token);
_mockTestBme680Sensor.Verify(s => s.Initialize(), Times.AtLeastOnce);
@ -59,7 +60,8 @@ namespace NucuCar.UnitTests.NucuCar.Sensors.Tests
});
_mockTestBme680Sensor.Setup(s => s.GetState()).Returns(SensorStateEnum.Initialized);
var service = new Bme680Worker(_mockLogger.Object, _mockSensorTelemetry.Object, _mockBme680ISensor.Object);
var service = new Bme680Worker(_mockLogger.Object, _mockSensorTelemetry.Object, _mockBme680ISensor.Object,
new OptionsWrapper<Bme680Config>(new Bme680Config()));
await service.StartAsync(_cts.Token);
_mockTestBme680Sensor.Verify(s => s.Initialize(), Times.AtLeastOnce);
_mockTestBme680Sensor.Verify(s => s.TakeMeasurementAsync(), Times.AtLeastOnce);