Add gRPC support for NucuCar.Sensors project
This commit is contained in:
parent
6e6f1c6fcd
commit
a557d44c98
15 changed files with 240 additions and 27 deletions
|
@ -4,9 +4,9 @@ namespace NucuCar.Sensors.EnvironmentSensor
|
|||
{
|
||||
public struct Measurement
|
||||
{
|
||||
public Temperature Temperature { get; set; }
|
||||
public double Pressure { get; set; }
|
||||
public double Humidity { get; set; }
|
||||
public Temperature Temperature { get; private set; }
|
||||
public double Pressure { get; private set; }
|
||||
public double Humidity { get; private set; }
|
||||
|
||||
public Measurement(Temperature temperature, double pressure, double humidity) : this()
|
||||
{
|
||||
|
|
|
@ -9,21 +9,52 @@ namespace NucuCar.Sensors.EnvironmentSensor
|
|||
{
|
||||
public class Sensor : IDisposable
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private ILogger _logger;
|
||||
private I2cConnectionSettings _i2CSettings;
|
||||
private I2cDevice _i2CDevice;
|
||||
private Bme680 _bme680;
|
||||
private Measurement _measurement;
|
||||
private SensorState _sensorState;
|
||||
|
||||
public Sensor(ILogger logger)
|
||||
/* Singleton Instance */
|
||||
public static Sensor Instance { get; } = new Sensor();
|
||||
|
||||
static Sensor()
|
||||
{
|
||||
}
|
||||
|
||||
private Sensor()
|
||||
{
|
||||
_sensorState = SensorState.Uninitialized;
|
||||
}
|
||||
|
||||
public Measurement GetMeasurement()
|
||||
{
|
||||
return _measurement;
|
||||
}
|
||||
|
||||
public SensorState GetState()
|
||||
{
|
||||
return _sensorState;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_bme680?.Dispose();
|
||||
}
|
||||
|
||||
internal void SetLogger(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
InitializeSensor();
|
||||
}
|
||||
|
||||
internal void InitializeSensor()
|
||||
{
|
||||
if (_sensorState == SensorState.Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
/* Connect to default i2c address 0x76 */
|
||||
|
@ -70,22 +101,5 @@ namespace NucuCar.Sensors.EnvironmentSensor
|
|||
_logger.LogInformation(
|
||||
$"{temperature.Celsius:N2} \u00B0C | {pressure} hPa | {humidity:N2} %rH");
|
||||
}
|
||||
|
||||
// TODO: Make gRpc accessible.
|
||||
public Measurement GetMeasurement()
|
||||
{
|
||||
return _measurement;
|
||||
}
|
||||
|
||||
// TODO: Make gRpc accessible.
|
||||
public SensorState GetState()
|
||||
{
|
||||
return _sensorState;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_bme680?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
27
NucuCar.Sensors/EnvironmentSensor/Service.cs
Normal file
27
NucuCar.Sensors/EnvironmentSensor/Service.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NucuCarGrpcSensors;
|
||||
|
||||
namespace NucuCar.Sensors.EnvironmentSensor
|
||||
{
|
||||
public class Service : EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceBase
|
||||
{
|
||||
private readonly ILogger<Service> _logger;
|
||||
private readonly Sensor _sensor;
|
||||
|
||||
public Service(ILogger<Service> logger)
|
||||
{
|
||||
_sensor = Sensor.Instance;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new HelloReply
|
||||
{
|
||||
Message = "Hello " + request.Name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,10 @@ namespace NucuCar.Sensors.EnvironmentSensor
|
|||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
using var sensor = new Sensor(_logger);
|
||||
using var sensor = Sensor.Instance;
|
||||
sensor.SetLogger(_logger);
|
||||
sensor.InitializeSensor();
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
if (sensor.GetState() == SensorState.Initialized)
|
||||
|
|
43
NucuCar.Sensors/GrpcStartup.cs
Normal file
43
NucuCar.Sensors/GrpcStartup.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace NucuCar.Sensors
|
||||
{
|
||||
public class GrpcStartup
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddGrpc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGrpcService<EnvironmentSensor.Service>();
|
||||
|
||||
endpoints.MapGet("/",
|
||||
async context =>
|
||||
{
|
||||
await context.Response.WriteAsync(
|
||||
"Communication with gRPC endpoints must be made through a gRPC client. " +
|
||||
"To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.10.1" />
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.25.0" />
|
||||
<PackageReference Include="Grpc.Core" Version="2.25.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.25.0" />
|
||||
<PackageReference Include="Iot.Device.Bindings" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
|
||||
<PackageReference Include="System.Device.Gpio" Version="1.0.0" />
|
||||
|
@ -13,37 +17,62 @@
|
|||
|
||||
<ItemGroup>
|
||||
<_UnmanagedRegistrationCache Remove="obj\NucuCar.Sensors.csproj.UnmanagedRegistration.cache" />
|
||||
<_UnmanagedRegistrationCache Remove="obj\NucuCar.Sensors.csproj.UnmanagedRegistration.cache" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ResolveComReferenceCache Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.csproj.ResolveComReference.cache" />
|
||||
<_ResolveComReferenceCache Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.csproj.ResolveComReference.cache" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<IntermediateAssembly Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll" />
|
||||
<IntermediateAssembly Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_DebugSymbolsIntermediatePath Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.pdb" />
|
||||
<_DebugSymbolsIntermediatePath Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.pdb" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_DeploymentManifestEntryPoint Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll" />
|
||||
<_DeploymentManifestEntryPoint Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ApplicationManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll.manifest" />
|
||||
<ApplicationManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.dll.manifest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DeployManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.application" />
|
||||
<DeployManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.application" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ClsidMap Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.clsidmap" />
|
||||
<ClsidMap Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.clsidmap" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RegFreeComManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.X.manifest" />
|
||||
<RegFreeComManifest Remove="obj\Debug\netcoreapp3.0\NucuCar.Sensors.X.manifest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Services" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Protos\EnvironmentSensor.proto">
|
||||
<GrpcServices>Both</GrpcServices>
|
||||
<Access>Public</Access>
|
||||
<ProtoCompile>True</ProtoCompile>
|
||||
<ProtoRoot></ProtoRoot>
|
||||
<CompileOutputs>True</CompileOutputs>
|
||||
<OutputDir>obj/Debug/netcoreapp3.0/</OutputDir>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Protobuf>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using NucuCar.Sensors.EnvironmentSensor;
|
||||
|
@ -10,9 +11,10 @@ namespace NucuCar.Sensors
|
|||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); });
|
||||
.ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); })
|
||||
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<GrpcStartup>(); });
|
||||
}
|
||||
}
|
19
NucuCar.Sensors/Protos/EnvironmentSensor.proto
Normal file
19
NucuCar.Sensors/Protos/EnvironmentSensor.proto
Normal file
|
@ -0,0 +1,19 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package NucuCarGrpcSensors;
|
||||
|
||||
// The greeting service definition.
|
||||
service EnvironmentSensorGrpcService {
|
||||
// Sends a greeting
|
||||
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||
}
|
||||
|
||||
// The request message containing the user's name.
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
// The response message containing the greetings
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
|
@ -11,5 +11,7 @@ Sensor capabilities:
|
|||
* Humidity
|
||||
* VOC Gas (Currently not implemented in binding)
|
||||
|
||||
Note: Currently using the development certificate for gRpc calls.
|
||||
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ namespace NucuCar.Sensors
|
|||
public enum SensorState
|
||||
{
|
||||
Error,
|
||||
Uninitialized,
|
||||
Initialized
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Grpc": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,16 @@
|
|||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Kestrel": {
|
||||
"EndpointDefaults": {
|
||||
"Protocols": "Http2"
|
||||
},
|
||||
"EndPoints": {
|
||||
"Https":{
|
||||
"Url": "https://localhost:8000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
NucuCar.TestClient/NucuCar.TestClient.csproj
Normal file
17
NucuCar.TestClient/NucuCar.TestClient.csproj
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.Core" Version="2.25.0" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.25.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NucuCar.Sensors\NucuCar.Sensors.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
38
NucuCar.TestClient/Program.cs
Normal file
38
NucuCar.TestClient/Program.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Net.Client;
|
||||
using NucuCarGrpcSensors;
|
||||
|
||||
namespace NucuCar.TestClient
|
||||
{
|
||||
class Program
|
||||
{
|
||||
/* Warning! Before issuing a gRPC call the dev certificate must be trusted or you'll get:
|
||||
* Detail="Error starting gRPC call: The SSL connection could not be established, see inner exception."
|
||||
* See: https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-3.0&tabs=visual-studio#trust-the-aspnet-core-https-development-certificate-on-windows-and-macos
|
||||
*/
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
// Used to allow gRPC calls over unsecured HTTP.
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
|
||||
// Allow untrusted certificates.
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
httpClientHandler.ServerCertificateCustomValidationCallback =
|
||||
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||
var httpClient = new HttpClient(httpClientHandler);
|
||||
|
||||
|
||||
// The port number(5001) must match the port of the gRPC server.
|
||||
var channel = GrpcChannel.ForAddress("https://localhost:8000",
|
||||
new GrpcChannelOptions {HttpClient = httpClient});
|
||||
var client = new EnvironmentSensorGrpcService.EnvironmentSensorGrpcServiceClient(channel);
|
||||
var reply = await client.SayHelloAsync(
|
||||
new HelloRequest {Name = "GreeterClient"});
|
||||
Console.WriteLine("Greeting: " + reply.Message);
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NucuCar.Sensors", "NucuCar.Sensors\NucuCar.Sensors.csproj", "{94C44683-F5AF-4D7D-83AE-1F94A81E1E91}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NucuCar.TestClient", "NucuCar.TestClient\NucuCar.TestClient.csproj", "{402BE859-07C7-4C77-8F3A-E727988CCFAD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -12,5 +14,9 @@ Global
|
|||
{94C44683-F5AF-4D7D-83AE-1F94A81E1E91}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{94C44683-F5AF-4D7D-83AE-1F94A81E1E91}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{94C44683-F5AF-4D7D-83AE-1F94A81E1E91}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{402BE859-07C7-4C77-8F3A-E727988CCFAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{402BE859-07C7-4C77-8F3A-E727988CCFAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{402BE859-07C7-4C77-8F3A-E727988CCFAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{402BE859-07C7-4C77-8F3A-E727988CCFAD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
Loading…
Reference in a new issue