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 Microsoft.Extensions.Logging;
namespace NucuCar.Domain
{
/// <summary>
/// Helper class used for checking arguments and raise exception if the checks don't pass.
/// </summary>
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)
{
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)
{
if (argument == null)

View file

@ -2,10 +2,22 @@ using System.Collections.Generic;
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
{
/// <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();
/* 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();
}
}

View file

@ -6,14 +6,36 @@ using Microsoft.Extensions.Logging;
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
{
/// <summary>
/// Raw connection string that is used to connect to the cloud service. Should be parsed if required.
/// </summary>
protected string ConnectionString { get; set; }
/// <summary>
/// Telemetry source that indicates the source of the telemetry data.
/// </summary>
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;
/// <summary>
/// The logging instance, if it's null then the module won't log anything.
/// </summary>
// ReSharper disable once UnassignedField.Global
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)
{
ConnectionString = opts.ConnectionString;
@ -22,22 +44,42 @@ namespace NucuCar.Domain.Telemetry
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);
/// <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)
{
if (RegisteredTelemeters.Contains(t)) return false;
RegisteredTelemeters.Add(t);
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)
{
if (!RegisteredTelemeters.Contains(t)) return false;
RegisteredTelemeters.Remove(t);
return true;
}
public abstract void Dispose();
}
}

View file

@ -28,13 +28,24 @@ namespace NucuCar.Domain.Telemetry
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)
{
Guard.ArgumentNotNullOrWhiteSpace(nameof(connectionString), connectionString);
return new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{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,
string telemetrySource)
{
@ -43,7 +54,14 @@ namespace NucuCar.Domain.Telemetry
return new TelemetryPublisherAzure(new TelemetryPublisherBuilderOptions()
{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,
string telemetrySource, ILogger logger)
{

View file

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

View file

@ -8,6 +8,10 @@ using NucuCarSensorsProto;
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
{
private readonly bool _serviceEnabled;
@ -54,7 +58,7 @@ namespace NucuCar.Sensors.EnvironmentSensor
await Task.Delay(_measurementDelay, stoppingToken);
}
SensorTelemetryPublisher.Instance.UnRegisterTelemeter(sensor);
}
}

View file

@ -10,6 +10,10 @@ using NucuCarSensorsProto;
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 ILogger Logger;
@ -117,6 +121,7 @@ namespace NucuCar.Sensors.EnvironmentSensor
["voc"] = _lastMeasurement.VolatileOrganicCompound
};
}
return returnValue;
}
}

View file

@ -6,6 +6,10 @@ using NucuCarSensorsProto;
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
{
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)}.");
var sensorMeasurement = _bme680Sensor.GetMeasurement();

View file

@ -25,9 +25,10 @@ namespace NucuCar.Sensors
app.UseRouting();
app.UseHttpsRedirection();
app.UseEndpoints(endpoints =>
{
// Add the gRPC services here.
endpoints.MapGrpcService<EnvironmentSensor.GrpcService>();
endpoints.MapGet("/",

View file

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

View file

@ -9,20 +9,20 @@ namespace NucuCar.Sensors.Telemetry
private static object _palock = new object();
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,
ILogger logger)
{
if (Instance == null)
lock (_palock)
{
lock (_palock)
{
var telemetryPublisher =
TelemetryPublisherAzure.CreateFromConnectionString(connectionString, telemetrySource, logger);
Instance = telemetryPublisher;
}
if (Instance != null) return Instance;
var telemetryPublisher =
TelemetryPublisherAzure.CreateFromConnectionString(connectionString, telemetrySource, logger);
Instance = telemetryPublisher;
return Instance;
}
return Instance;
}
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] Add settings: ~~gRPC enabled~~, Telemetry Enabled, Sensor Enabled, Measurement Delay
- [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.
- [ ] Grpc
- [ ] Telemetry