Add source code docummentation

This commit is contained in:
Denis-Cosmin Nutiu 2019-11-24 15:12:12 +02:00
parent 63d0ea6d4b
commit eee870a360
12 changed files with 138 additions and 20 deletions

View file

@ -1,10 +1,18 @@
using System; using System;
using Microsoft.Extensions.Logging;
namespace NucuCar.Domain namespace NucuCar.Domain
{ {
/// <summary>
/// Helper class used for checking arguments and raise exception if the checks don't pass.
/// </summary>
public static class Guard public static class Guard
{ {
/// <summary>
/// Checks if the argument string is null or whitespace and raises exception on check fail.
/// </summary>
/// <param name="argumentName">The argument name that will be logged in the exception message.</param>
/// <param name="argument">The argument to check if it's null or whitespace.</param>
/// <exception cref="ArgumentNullException">Raised if the argument is null or whitespace.</exception>
internal static void ArgumentNotNullOrWhiteSpace(string argumentName, string argument) internal static void ArgumentNotNullOrWhiteSpace(string argumentName, string argument)
{ {
if (string.IsNullOrWhiteSpace(argument)) if (string.IsNullOrWhiteSpace(argument))
@ -13,6 +21,12 @@ namespace NucuCar.Domain
} }
} }
/// <summary>
/// Checks if the argument is null and raises exception on check fail.
/// </summary>
/// <param name="argumentName">The argument name that will be logged in the exception message.</param>
/// <param name="argument">The argument to check if it's null.</param>
/// <exception cref="ArgumentNullException">Raised if the argument is null.</exception>
public static void ArgumentNotNull(string argumentName, object argument) public static void ArgumentNotNull(string argumentName, object argument)
{ {
if (argument == null) if (argument == null)

View file

@ -2,10 +2,22 @@ using System.Collections.Generic;
namespace NucuCar.Domain.Telemetry namespace NucuCar.Domain.Telemetry
{ {
/// <summary>
/// Interface that specifies that the component implementing it is willing to provide telemetry data and can be
/// registered to a publisher such as <see cref="TelemetryPublisherAzure"/>.
/// </summary>
public interface ITelemeter public interface ITelemeter
{ {
/// <summary>
/// This function should return an identifier that identifies the component providing the telemetry data.
/// </summary>
/// <returns>An identifier for the telemetry source.</returns>
string GetIdentifier(); string GetIdentifier();
/* Dictionary containing the topic and the value */
/// <summary>
/// This function should return a dictionary containing the telemetry data.
/// </summary>
/// <returns>The telemetry data. It should be JSON serializable.</returns>
Dictionary<string, object> GetTelemetryData(); Dictionary<string, object> GetTelemetryData();
} }
} }

View file

@ -6,14 +6,36 @@ using Microsoft.Extensions.Logging;
namespace NucuCar.Domain.Telemetry namespace NucuCar.Domain.Telemetry
{ {
/// <summary>
/// The TelemetryPublisher is an abstract class, which provides a base for implementing telemetry publishers.
/// </summary>
public abstract class TelemetryPublisher : IDisposable public abstract class TelemetryPublisher : IDisposable
{ {
/// <summary>
/// Raw connection string that is used to connect to the cloud service. Should be parsed if required.
/// </summary>
protected string ConnectionString { get; set; } protected string ConnectionString { get; set; }
/// <summary>
/// Telemetry source that indicates the source of the telemetry data.
/// </summary>
protected string TelemetrySource { get; set; } protected string TelemetrySource { get; set; }
/// <summary>
/// A list containing entries to the telemeters that want to publish data to the cloud.
/// </summary>
protected readonly List<ITelemeter> RegisteredTelemeters; protected readonly List<ITelemeter> RegisteredTelemeters;
/// <summary>
/// The logging instance, if it's null then the module won't log anything.
/// </summary>
// ReSharper disable once UnassignedField.Global // ReSharper disable once UnassignedField.Global
protected readonly ILogger Logger; protected readonly ILogger Logger;
/// <summary>
/// Constructor for <see cref="TelemetryPublisher"/>.
/// </summary>
/// <param name="opts">TelemetryPublisher options, see: <see cref="TelemetryPublisherBuilderOptions"/></param>
protected TelemetryPublisher(TelemetryPublisherBuilderOptions opts) protected TelemetryPublisher(TelemetryPublisherBuilderOptions opts)
{ {
ConnectionString = opts.ConnectionString; ConnectionString = opts.ConnectionString;
@ -22,22 +44,42 @@ namespace NucuCar.Domain.Telemetry
RegisteredTelemeters = new List<ITelemeter>(5); RegisteredTelemeters = new List<ITelemeter>(5);
} }
/// <summary>
/// Method that sends all data from the (<see cref="RegisteredTelemeters"/>) to the cloud.
/// </summary>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>A task</returns>
public abstract Task PublishAsync(CancellationToken cancellationToken); public abstract Task PublishAsync(CancellationToken cancellationToken);
/// <summary>
/// Method that releases all managed resources.
/// </summary>
public abstract void Dispose();
/// <summary>
/// Method that adds a telemeter to the <see cref="RegisteredTelemeters"/> collection.
/// The telemeter can register only once.
/// </summary>
/// <param name="t">The <see cref="ITelemeter"/></param>
/// <returns>Returns true if the telemeter has registered successfully and false otherwise.</returns>
public bool RegisterTelemeter(ITelemeter t) public bool RegisterTelemeter(ITelemeter t)
{ {
if (RegisteredTelemeters.Contains(t)) return false; if (RegisteredTelemeters.Contains(t)) return false;
RegisteredTelemeters.Add(t); RegisteredTelemeters.Add(t);
return true; return true;
} }
/// <summary>
/// Method that deletes a telemeter from the <see cref="RegisteredTelemeters"/> collection.
/// </summary>
/// <param name="t">The <see cref="ITelemeter"/></param>
/// <returns>Returns true if the telemeter has unregistered successfully and false otherwise.</returns>
public bool UnRegisterTelemeter(ITelemeter t) public bool UnRegisterTelemeter(ITelemeter t)
{ {
if (!RegisteredTelemeters.Contains(t)) return false; if (!RegisteredTelemeters.Contains(t)) return false;
RegisteredTelemeters.Remove(t); RegisteredTelemeters.Remove(t);
return true; return true;
} }
public abstract void Dispose();
} }
} }

View file

@ -28,6 +28,11 @@ namespace NucuCar.Domain.Telemetry
Logger?.LogInformation("Started the AzureTelemetryPublisher!"); Logger?.LogInformation("Started the AzureTelemetryPublisher!");
} }
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">The device connection string for Microsoft Azure IoT hub device.</param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString) public static TelemetryPublisher CreateFromConnectionString(string connectionString)
{ {
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString); Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
@ -35,6 +40,12 @@ namespace NucuCar.Domain.Telemetry
{ConnectionString = connectionString, TelemetrySource = "TelemetryPublisherAzure"}); {ConnectionString = connectionString, TelemetrySource = "TelemetryPublisherAzure"});
} }
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">Device connection string for Microsoft Azure IoT hub device.</param>
/// <param name="telemetrySource">String that is used to identify the source of the telemetry data.</param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString, public static TelemetryPublisher CreateFromConnectionString(string connectionString,
string telemetrySource) string telemetrySource)
{ {
@ -44,6 +55,13 @@ namespace NucuCar.Domain.Telemetry
{ConnectionString = connectionString, TelemetrySource = telemetrySource}); {ConnectionString = connectionString, TelemetrySource = telemetrySource});
} }
/// <summary>
/// Creates an instance of <see cref="TelemetryPublisher"/> that is used to publish data to Microsoft Azure.
/// </summary>
/// <param name="connectionString">Device connection string for Microsoft Azure IoT hub device.</param>
/// <param name="telemetrySource">String that is used to identify the source of the telemetry data.</param>
/// <param name="logger">An <see cref="ILogger"/> logger instance. </param>
/// <returns>A <see cref="TelemetryPublisher"/> instance.</returns>
public static TelemetryPublisher CreateFromConnectionString(string connectionString, public static TelemetryPublisher CreateFromConnectionString(string connectionString,
string telemetrySource, ILogger logger) string telemetrySource, ILogger logger)
{ {

View file

@ -2,10 +2,24 @@ using Microsoft.Extensions.Logging;
namespace NucuCar.Domain.Telemetry namespace NucuCar.Domain.Telemetry
{ {
/// <summary>
/// This class contains options for the <see cref="TelemetryPublisher"/>.
/// </summary>
public class TelemetryPublisherBuilderOptions public class TelemetryPublisherBuilderOptions
{ {
/// <summary>
/// The ConnectionString used by the publisher to connect to the cloud service.
/// </summary>
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
/// <summary>
/// A string that indicates the source of the telemetry data.
/// </summary>
public string TelemetrySource { get; set; } public string TelemetrySource { get; set; }
/// <summary>
/// The <see cref="ILogger"/> logger instance.
/// </summary>
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
} }
} }

View file

@ -8,6 +8,10 @@ using NucuCarSensorsProto;
namespace NucuCar.Sensors.EnvironmentSensor namespace NucuCar.Sensors.EnvironmentSensor
{ {
/// <summary>
/// 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 BackgroundWorker : BackgroundService
{ {
private readonly bool _serviceEnabled; private readonly bool _serviceEnabled;

View file

@ -10,6 +10,10 @@ using NucuCarSensorsProto;
namespace NucuCar.Sensors.EnvironmentSensor namespace NucuCar.Sensors.EnvironmentSensor
{ {
/// <summary>
/// Abstraction for the BME680 sensor.
/// See: https://www.bosch-sensortec.com/bst/products/all_products/bme680
/// </summary>
public class Bme680Sensor : IDisposable, ITelemeter public class Bme680Sensor : IDisposable, ITelemeter
{ {
public ILogger Logger; public ILogger Logger;
@ -117,6 +121,7 @@ namespace NucuCar.Sensors.EnvironmentSensor
["voc"] = _lastMeasurement.VolatileOrganicCompound ["voc"] = _lastMeasurement.VolatileOrganicCompound
}; };
} }
return returnValue; return returnValue;
} }
} }

View file

@ -6,6 +6,10 @@ using NucuCarSensorsProto;
namespace NucuCar.Sensors.EnvironmentSensor namespace NucuCar.Sensors.EnvironmentSensor
{ {
/// <summary>
/// EnvironmentSensor's gRPC service.
/// It allows reading the sensor's data using remote procedure calls.
/// </summary>
public class GrpcService : EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceBase public class GrpcService : EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceBase
{ {
private readonly ILogger<GrpcService> _logger; private readonly ILogger<GrpcService> _logger;
@ -26,7 +30,8 @@ namespace NucuCar.Sensors.EnvironmentSensor
}); });
} }
public override Task<EnvironmentSensorMeasurement> GetSensorMeasurement(Empty request, ServerCallContext context) public override Task<EnvironmentSensorMeasurement> GetSensorMeasurement(Empty request,
ServerCallContext context)
{ {
_logger?.LogDebug($"Calling {nameof(GetSensorMeasurement)}."); _logger?.LogDebug($"Calling {nameof(GetSensorMeasurement)}.");
var sensorMeasurement = _bme680Sensor.GetMeasurement(); var sensorMeasurement = _bme680Sensor.GetMeasurement();

View file

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

View file

@ -6,6 +6,9 @@ using Microsoft.Extensions.Logging;
namespace NucuCar.Sensors.Telemetry namespace NucuCar.Sensors.Telemetry
{ {
/// <summary>
/// Telemetry service, which pools the telemetry sources and pushes telemetry data to the cloud.
/// </summary>
public class BackgroundWorker : BackgroundService public class BackgroundWorker : BackgroundService
{ {
private readonly bool _serviceEnabled; private readonly bool _serviceEnabled;

View file

@ -9,21 +9,21 @@ namespace NucuCar.Sensors.Telemetry
private static object _palock = new object(); private static object _palock = new object();
public static TelemetryPublisher Instance { get; private set; } public static TelemetryPublisher Instance { get; private set; }
/// <summary>
/// Creates a telemetry publisher instance see <see cref="TelemetryPublisher"/>.
/// </summary>
public static TelemetryPublisher CreateSingleton(string connectionString, string telemetrySource, public static TelemetryPublisher CreateSingleton(string connectionString, string telemetrySource,
ILogger logger) ILogger logger)
{
if (Instance == null)
{ {
lock (_palock) lock (_palock)
{ {
if (Instance != null) return Instance;
var telemetryPublisher = var telemetryPublisher =
TelemetryPublisherAzure.CreateFromConnectionString(connectionString, telemetrySource, logger); TelemetryPublisherAzure.CreateFromConnectionString(connectionString, telemetrySource, logger);
Instance = telemetryPublisher; Instance = telemetryPublisher;
}
}
return Instance; return Instance;
} }
}
private static void ReleaseUnmanagedResources() private static void ReleaseUnmanagedResources()
{ {

View file

@ -32,7 +32,7 @@ dotnet build --runtime linux-arm -p:PublishSingleFile=true
- [X] Make a working BME680 module. ~~(Unit tests?)~~ - [X] Make a working BME680 module. ~~(Unit tests?)~~
- [X] Add settings: ~~gRPC enabled~~, Telemetry Enabled, Sensor Enabled, Measurement Delay - [X] Add settings: ~~gRPC enabled~~, Telemetry Enabled, Sensor Enabled, Measurement Delay
- [X] Make a gRPC test project to test the modules. - [X] Make a gRPC test project to test the modules.
- [ ] Pretty document domain module. - [X] Pretty document domain module.
- [ ] Attempt some unit tests on sensors. - [ ] Attempt some unit tests on sensors.
- [ ] Grpc - [ ] Grpc
- [ ] Telemetry - [ ] Telemetry