├── .gitattributes ├── .gitignore ├── HTM.Communication ├── Actors │ └── CommunicationActor.cs ├── Extensions │ ├── DeviceTypeExtensions.cs │ ├── SerialPortMessageExtensions.cs │ ├── SerialPortMessageTypeExtensions.cs │ └── TemperatureMeasurementExtensions.cs ├── HTM.Communication.csproj ├── Services │ ├── GrpcHostedService.cs │ └── HtmMethodsServer.cs └── google │ └── api │ ├── BUILD.gn │ ├── README.md │ ├── annotations.proto │ ├── auth.proto │ ├── backend.proto │ ├── billing.proto │ ├── config_change.proto │ ├── consumer.proto │ ├── context.proto │ ├── control.proto │ ├── distribution.proto │ ├── documentation.proto │ ├── endpoint.proto │ ├── experimental │ ├── authorization_config.proto │ └── experimental.proto │ ├── http.proto │ ├── httpbody.proto │ ├── label.proto │ ├── log.proto │ ├── logging.proto │ ├── metric.proto │ ├── monitored_resource.proto │ ├── monitoring.proto │ ├── quota.proto │ ├── service.proto │ ├── servicecontrol │ ├── README.md │ └── v1 │ │ ├── check_error.proto │ │ ├── distribution.proto │ │ ├── log_entry.proto │ │ ├── metric_value.proto │ │ ├── operation.proto │ │ ├── quota_controller.proto │ │ └── service_controller.proto │ ├── servicemanagement │ ├── README.md │ └── v1 │ │ ├── resources.proto │ │ └── servicemanager.proto │ ├── source_info.proto │ ├── system_parameter.proto │ └── usage.proto ├── HTM.Core.Tests ├── Actors │ ├── RequestHandlerActorTests.cs │ └── TemperatureMeasurementActorTests.cs └── HTM.Core.Tests.csproj ├── HTM.Core ├── Actors │ ├── DevicesHealthMonitorActor.cs │ ├── HtmActor.cs │ ├── RequestHandlerActor.cs │ ├── TemperatureMeasurementActor.cs │ └── TemperatureMonitorActor.cs ├── Adapters │ └── ITemperatureMeasurementDao.cs ├── Devices │ └── Arduino │ │ └── Actors │ │ ├── ArduinoActor.cs │ │ ├── ArduinoBridgeActor.cs │ │ ├── ArduinoMessengerActor.cs │ │ └── GetMessageByCommandActor.cs ├── HTM.Core.csproj └── Services │ └── AppService.cs ├── HTM.Database ├── Configurations │ └── TemperatureMeasurementConfiguration.cs ├── Dao │ └── TemperatureMeasurementDao.cs ├── DatabaseInitializer.cs ├── Entities │ ├── EntityBase.cs │ └── TemperatureMeasurementDb.cs ├── Extensions │ └── ServiceCollectionExtensions.cs ├── HTM.Database.csproj ├── HtmContext.cs └── Migrations │ ├── 20220215201721_Initial.Designer.cs │ ├── 20220215201721_Initial.cs │ └── HtmContextModelSnapshot.cs ├── HTM.Devices.Arduino ├── Configurations │ └── ArduinoOptions.cs ├── Extensions │ └── ServiceCollectionExtensions.cs ├── HTM.Devices.Arduino.csproj ├── Services │ ├── ArduinoEmulatorService.cs │ └── ArduinoService.cs └── Sketch │ ├── Sketch.ino │ └── libraries │ ├── DallasTemperature │ ├── DallasTemperature.cpp │ ├── DallasTemperature.h │ ├── README.md │ ├── change.txt │ ├── keywords.txt │ ├── library.json │ └── library.properties │ └── OneWire │ ├── OneWire.cpp │ ├── OneWire.h │ ├── keywords.txt │ ├── library.json │ └── library.properties ├── HTM.Infrastructure ├── Adapters │ └── IPersistenceInitializer.cs ├── Akka │ ├── BaseActor.cs │ └── HtmActorBridge.cs ├── Communication │ └── Protos │ │ ├── common.proto │ │ ├── events.proto │ │ └── methods.proto ├── Constants │ └── Application.cs ├── Devices │ ├── Adapters │ │ ├── IDevice.cs │ │ └── ISerialPortDevice.cs │ ├── Enums │ │ └── DeviceType.cs │ └── Messages │ │ ├── Events │ │ ├── DeviceConnectionChangedEvent.cs │ │ └── SerialPortMessageReceivedEvent.cs │ │ ├── InitializationResultMessage.cs │ │ └── Requests │ │ ├── GetDeviceConnectionStateRequest.cs │ │ ├── GetDeviceConnectionStateResponse.cs │ │ ├── GetMessageByCommandRequest.cs │ │ ├── GetMessageByCommandResponse.cs │ │ ├── SendMessageRequest.cs │ │ └── SendMessageResponse.cs ├── Exceptions │ ├── DeviceDisconnectedException.cs │ └── InvalidTemperatureException.cs ├── HTM.Infrastructure.csproj ├── Logging │ └── SerilogHelper.cs ├── Measurements │ └── Messages │ │ └── Requests │ │ ├── AddTemperatureMeasurementRequest.cs │ │ ├── AddTemperatureMeasurementResponse.cs │ │ ├── GetLastTemperatureMeasurementRequest.cs │ │ ├── GetLastTemperatureMeasurementResponse.cs │ │ ├── GetTemperatureMeasurementsByDateRangeRequest.cs │ │ └── GetTemperatureMeasurementsByDateRangeResponse.cs ├── Messages │ └── Events │ │ ├── TemperatureMeasurementActorInitializedEvent.cs │ │ ├── TimeoutEvent.cs │ │ └── TimerElapsedEvent.cs ├── MessagesBase │ ├── EventBase.cs │ ├── HtmRequest.cs │ └── HtmResponse.cs └── Models │ ├── SerialPortCommand.cs │ ├── SerialPortMessage.cs │ ├── SerialPortMessageType.cs │ └── TemperatureMeasurement.cs ├── HTM.Web.Communication ├── Extensions │ ├── DeviceTypeExtensions.cs │ ├── SerialPortMessageExtensions.cs │ ├── SerialPortMessageTypeExtensions.cs │ └── TemperaturesMeasurementExtensions.cs ├── HTM.Web.Communication.csproj ├── Services │ ├── GrpcHostedService.cs │ ├── HtmEventsServer.cs │ ├── HtmEventsService.cs │ ├── HtmMethodsClient.cs │ ├── IHtmEventsInvoker.cs │ └── IHtmEventsService.cs └── google │ └── api │ ├── BUILD.gn │ ├── README.md │ ├── annotations.proto │ ├── auth.proto │ ├── backend.proto │ ├── billing.proto │ ├── config_change.proto │ ├── consumer.proto │ ├── context.proto │ ├── control.proto │ ├── distribution.proto │ ├── documentation.proto │ ├── endpoint.proto │ ├── experimental │ ├── authorization_config.proto │ └── experimental.proto │ ├── http.proto │ ├── httpbody.proto │ ├── label.proto │ ├── log.proto │ ├── logging.proto │ ├── metric.proto │ ├── monitored_resource.proto │ ├── monitoring.proto │ ├── quota.proto │ ├── service.proto │ ├── servicecontrol │ ├── README.md │ └── v1 │ │ ├── check_error.proto │ │ ├── distribution.proto │ │ ├── log_entry.proto │ │ ├── metric_value.proto │ │ ├── operation.proto │ │ ├── quota_controller.proto │ │ └── service_controller.proto │ ├── servicemanagement │ ├── README.md │ └── v1 │ │ ├── resources.proto │ │ └── servicemanager.proto │ ├── source_info.proto │ ├── system_parameter.proto │ └── usage.proto ├── HTM.Web ├── App.razor ├── HTM.Web.csproj ├── Pages │ ├── ArduinoDiagnosticPage.razor │ ├── ArduinoDiagnosticPage.razor.cs │ ├── Error.cshtml │ ├── Error.cshtml.cs │ ├── Temperatures.razor │ ├── Temperatures.razor.cs │ ├── _Host.cshtml │ └── _Layout.cshtml ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── MainLayout.razor.css │ ├── NavMenu.razor │ ├── NavMenu.razor.css │ ├── PleaseWaitComponent.razor │ └── SurveyPrompt.razor ├── _Imports.razor ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ ├── css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ └── site.css │ └── favicon.ico ├── HTM.sln ├── HTM ├── HTM.csproj ├── Program.cs ├── akkaConfig.json └── appsettings.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | HTM.Devices.Arduino/Sketch/libraries/* linguist-vendored 2 | -------------------------------------------------------------------------------- /HTM.Communication/Actors/CommunicationActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Event; 2 | using Grpc.Net.Client; 3 | using HTM.Communication.Extensions; 4 | using HTM.Communication.V2; 5 | using HTM.Infrastructure.Akka; 6 | using HTM.Infrastructure.Devices.Messages.Events; 7 | 8 | namespace HTM.Communication.Actors; 9 | 10 | public class CommunicationActor : BaseActor 11 | { 12 | private readonly GrpcChannel _grpcChannel; 13 | 14 | public CommunicationActor() 15 | { 16 | _grpcChannel = GrpcChannel.ForAddress("http://localhost:2005"); 17 | 18 | ReceiveAsync(CallDeviceConnectionChanged); 19 | ReceiveAsync(CallMessageReceivedEvent); 20 | 21 | Context.System.EventStream.Subscribe(Self); 22 | Context.System.EventStream.Subscribe(Self); 23 | } 24 | 25 | private async Task CallDeviceConnectionChanged(DeviceConnectionChangedEvent @event) 26 | { 27 | try 28 | { 29 | var client = new HTMEventsService.HTMEventsServiceClient(_grpcChannel); 30 | 31 | var response = await client.DeviceConnectionChangedAsync(new GrpcDeviceConnectionChangedRequest 32 | { 33 | DeviceType = @event.DeviceType.ToDeviceType(), IsConnected = @event.IsConnected 34 | }); 35 | } 36 | catch (Exception ex) 37 | { 38 | Logger.Error(ex, "CallDeviceConnectionChanged Error"); 39 | } 40 | } 41 | 42 | private async Task CallMessageReceivedEvent(SerialPortMessageReceivedEvent @event) 43 | { 44 | try 45 | { 46 | var client = new HTMEventsService.HTMEventsServiceClient(_grpcChannel); 47 | 48 | var request = new GrpcSerialPortMessagesReceivedRequest(); 49 | 50 | request.Messages.AddRange(@event.Messages.Select(x => x.ToSerialPortMessage())); 51 | 52 | var response = await client.SerialPortMessagesReceivedAsync(request); 53 | } 54 | catch (Exception ex) 55 | { 56 | Logger.Error(ex, "CallMessageReceivedEvent Error"); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /HTM.Communication/Extensions/DeviceTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Devices.Enums; 3 | 4 | namespace HTM.Communication.Extensions; 5 | 6 | public static class DeviceTypeExtensions 7 | { 8 | public static DeviceType ToDeviceType(this GrpcDeviceType deviceType) 9 | { 10 | return deviceType switch 11 | { 12 | GrpcDeviceType.Arduino => DeviceType.Arduino, 13 | 14 | _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) 15 | }; 16 | } 17 | 18 | public static GrpcDeviceType ToDeviceType(this DeviceType deviceType) 19 | { 20 | return deviceType switch 21 | { 22 | DeviceType.Arduino => GrpcDeviceType.Arduino, 23 | 24 | _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) 25 | }; 26 | } 27 | } -------------------------------------------------------------------------------- /HTM.Communication/Extensions/SerialPortMessageExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Communication.Extensions; 5 | 6 | public static class SerialPortMessageExtensions 7 | { 8 | public static SerialPortMessage ToSerialPortMessage(this GrpcSerialPortMessage message) 9 | { 10 | return new SerialPortMessage(message.Type.ToSerialPortMessageType(), message.Text); 11 | } 12 | 13 | public static GrpcSerialPortMessage ToSerialPortMessage(this SerialPortMessage message) 14 | { 15 | return new GrpcSerialPortMessage 16 | { 17 | Type = message.Type.ToSerialPortMessageType(), 18 | Text = message.Text 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /HTM.Communication/Extensions/SerialPortMessageTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Communication.Extensions; 5 | 6 | public static class SerialPortMessageTypeExtensions 7 | { 8 | public static SerialPortMessageType ToSerialPortMessageType(this GrpcSerialPortMessageType messageType) 9 | { 10 | return messageType switch 11 | { 12 | GrpcSerialPortMessageType.Undefined => SerialPortMessageType.Undefined, 13 | GrpcSerialPortMessageType.Event => SerialPortMessageType.Event, 14 | GrpcSerialPortMessageType.CommandResponse => SerialPortMessageType.CommandResponse, 15 | 16 | _ => throw new ArgumentOutOfRangeException(nameof(messageType), messageType, null) 17 | }; 18 | } 19 | 20 | public static GrpcSerialPortMessageType ToSerialPortMessageType(this SerialPortMessageType messageType) 21 | { 22 | return messageType switch 23 | { 24 | SerialPortMessageType.Undefined => GrpcSerialPortMessageType.Undefined, 25 | SerialPortMessageType.Event => GrpcSerialPortMessageType.Event, 26 | SerialPortMessageType.CommandResponse => GrpcSerialPortMessageType.CommandResponse, 27 | 28 | _ => throw new ArgumentOutOfRangeException(nameof(messageType), messageType, null) 29 | }; 30 | } 31 | } -------------------------------------------------------------------------------- /HTM.Communication/Extensions/TemperatureMeasurementExtensions.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf.WellKnownTypes; 2 | using HTM.Communication.V2; 3 | using HTM.Infrastructure.Models; 4 | 5 | namespace HTM.Communication.Extensions; 6 | 7 | public static class TemperatureMeasurementExtensions 8 | { 9 | public static GrpcTemperatureMeasurement ToGrpcTemperatureMeasurement(this TemperatureMeasurement measurement) 10 | { 11 | return new GrpcTemperatureMeasurement 12 | { 13 | Id = measurement.Id, 14 | Temperature = measurement.Temperature, 15 | MeasurementDate = Timestamp.FromDateTime(DateTime.SpecifyKind(measurement.MeasurementDate, DateTimeKind.Utc)) 16 | }; 17 | } 18 | } -------------------------------------------------------------------------------- /HTM.Communication/HTM.Communication.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Protos\common.proto 26 | 27 | 28 | 29 | Protos\methods.proto 30 | 31 | 32 | 33 | Protos\events.proto 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /HTM.Communication/Services/GrpcHostedService.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Microsoft.Extensions.Hosting; 3 | using Serilog; 4 | 5 | namespace HTM.Communication.Services; 6 | 7 | public class GrpcHostedService : IHostedService 8 | { 9 | private readonly Server _server; 10 | 11 | public GrpcHostedService(Server server) 12 | { 13 | _server = server; 14 | } 15 | 16 | public Task StartAsync(CancellationToken cancellationToken) 17 | { 18 | _server.Start(); 19 | 20 | Log.Information("{GrpcHostedService} | Server Started", nameof(GrpcHostedService)); 21 | 22 | return Task.CompletedTask; 23 | } 24 | 25 | public async Task StopAsync(CancellationToken cancellationToken) 26 | { 27 | await _server.ShutdownAsync(); 28 | 29 | Log.Information("{GrpcHostedService} | Server Stopped", nameof(GrpcHostedService)); 30 | } 31 | } -------------------------------------------------------------------------------- /HTM.Communication/Services/HtmMethodsServer.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Grpc.Core; 3 | using HTM.Communication.Extensions; 4 | using HTM.Communication.V2; 5 | using HTM.Infrastructure.Akka; 6 | using HTM.Infrastructure.Devices.Messages.Requests; 7 | using HTM.Infrastructure.Measurements.Messages.Requests; 8 | using HTM.Infrastructure.Models; 9 | using Serilog; 10 | 11 | namespace HTM.Communication.Services; 12 | 13 | public class HtmMethodsServer : V2.HTMMethodsService.HTMMethodsServiceBase 14 | { 15 | private readonly HtmActorBridge _htmActorBridge; 16 | 17 | public HtmMethodsServer(HtmActorBridge htmActorBridge) 18 | { 19 | _htmActorBridge = htmActorBridge; 20 | } 21 | 22 | public override async Task GetDeviceConnectionState(GrpcGetDeviceConnectionStateRequest request, ServerCallContext context) 23 | { 24 | Log.Information("HtmMethodsServer | GetDeviceConnectionState, Device={Device}", request.DeviceType); 25 | 26 | var response = await _htmActorBridge.RequestHandlerActor 27 | .Ask( 28 | new GetDeviceConnectionStateRequest(request.DeviceType.ToDeviceType())); 29 | 30 | return new GrpcGetDeviceConnectionStateResponse 31 | { 32 | IsConnected = response.IsConnected 33 | }; 34 | } 35 | 36 | public override async Task GetMessageByCommand(GrpcGetMessageByCommandRequest request, ServerCallContext context) 37 | { 38 | Log.Information("HtmMethodsServer | GetMessageByCommand, Command={Command}", request.Command); 39 | 40 | var response = await _htmActorBridge.RequestHandlerActor 41 | .Ask( 42 | new GetMessageByCommandRequest(Enum.Parse(request.Command))); 43 | 44 | return new GrpcGetMessageByCommandResponse 45 | { 46 | Message = response.Message 47 | }; 48 | } 49 | 50 | public override async Task GrpcGetTemperatureMeasurements(GrpcGetTemperatureMeasurementsRequest request, ServerCallContext context) 51 | { 52 | Log.Information("HtmMethodsServer | GetTemperatureMeasurements"); 53 | 54 | var from = request.From.ToDateTime(); 55 | var to = request.To.ToDateTime(); 56 | 57 | var response = await _htmActorBridge.RequestHandlerActor 58 | .Ask( 59 | new GetTemperatureMeasurementsByDateRangeRequest(from, to)); 60 | 61 | var grpcResponse = new GrpcGetTemperatureMeasurementsResponse(); 62 | grpcResponse.GrpcTemperatureMeasurements.AddRange( 63 | response.TemperatureMeasurements?.Select(x => x.ToGrpcTemperatureMeasurement())); 64 | 65 | return grpcResponse; 66 | } 67 | } -------------------------------------------------------------------------------- /HTM.Communication/google/api/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The Fuchsia Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | import("//third_party/protobuf/proto_library.gni") 6 | 7 | proto_library("annotations_and_http") { 8 | sources = [ 9 | "annotations.proto", 10 | "http.proto", 11 | ] 12 | proto_in_dir = "//third_party/googleapis" 13 | import_dirs = [ "//third_party/googleapis" ] 14 | generate_python = false 15 | cc_generator_options = "lite" 16 | import_protobuf_full = true 17 | extra_configs = [ "//third_party/googleapis:googleapis_config" ] 18 | } 19 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/README.md: -------------------------------------------------------------------------------- 1 | This folder contains the schema of the configuration model for the API services 2 | platform. 3 | 4 | **Note**: Protos under this directory are in Alpha status, and therefore are 5 | subject to breaking changes. 6 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/backend.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "BackendProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // `Backend` defines the backend configuration for a service. 27 | message Backend { 28 | // A list of API backend rules that apply to individual API methods. 29 | // 30 | // **NOTE:** All service configuration rules follow "last one wins" order. 31 | repeated BackendRule rules = 1; 32 | } 33 | 34 | // A backend rule provides configuration for an individual API element. 35 | message BackendRule { 36 | // Selects the methods to which this rule applies. 37 | // 38 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 39 | string selector = 1; 40 | 41 | // The address of the API backend. 42 | string address = 2; 43 | 44 | // The number of seconds to wait for a response from a request. The 45 | // default depends on the deployment context. 46 | double deadline = 3; 47 | } 48 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/billing.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/metric.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "BillingProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | 29 | // Billing related configuration of the service. 30 | // 31 | // The following example shows how to configure monitored resources and metrics 32 | // for billing: 33 | // monitored_resources: 34 | // - type: library.googleapis.com/branch 35 | // labels: 36 | // - key: /city 37 | // description: The city where the library branch is located in. 38 | // - key: /name 39 | // description: The name of the branch. 40 | // metrics: 41 | // - name: library.googleapis.com/book/borrowed_count 42 | // metric_kind: DELTA 43 | // value_type: INT64 44 | // billing: 45 | // consumer_destinations: 46 | // - monitored_resource: library.googleapis.com/branch 47 | // metrics: 48 | // - library.googleapis.com/book/borrowed_count 49 | message Billing { 50 | // Configuration of a specific billing destination (Currently only support 51 | // bill against consumer project). 52 | message BillingDestination { 53 | // The monitored resource type. The type must be defined in 54 | // [Service.monitored_resources][google.api.Service.monitored_resources] section. 55 | string monitored_resource = 1; 56 | 57 | // Names of the metrics to report to this billing destination. 58 | // Each name must be defined in [Service.metrics][google.api.Service.metrics] section. 59 | repeated string metrics = 2; 60 | } 61 | 62 | // Billing configurations for sending metrics to the consumer project. 63 | // There can be multiple consumer destinations per service, each one must have 64 | // a different monitored resource type. A metric can be used in at most 65 | // one consumer destination. 66 | repeated BillingDestination consumer_destinations = 8; 67 | } 68 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/config_change.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/configchange;configchange"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ConfigChangeProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Output generated from semantically comparing two versions of a service 27 | // configuration. 28 | // 29 | // Includes detailed information about a field that have changed with 30 | // applicable advice about potential consequences for the change, such as 31 | // backwards-incompatibility. 32 | message ConfigChange { 33 | // Object hierarchy path to the change, with levels separated by a '.' 34 | // character. For repeated fields, an applicable unique identifier field is 35 | // used for the index (usually selector, name, or id). For maps, the term 36 | // 'key' is used. If the field has no unique identifier, the numeric index 37 | // is used. 38 | // Examples: 39 | // - visibility.rules[selector=="google.LibraryService.CreateBook"].restriction 40 | // - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value 41 | // - logging.producer_destinations[0] 42 | string element = 1; 43 | 44 | // Value of the changed object in the old Service configuration, 45 | // in JSON format. This field will not be populated if ChangeType == ADDED. 46 | string old_value = 2; 47 | 48 | // Value of the changed object in the new Service configuration, 49 | // in JSON format. This field will not be populated if ChangeType == REMOVED. 50 | string new_value = 3; 51 | 52 | // The type for this change, either ADDED, REMOVED, or MODIFIED. 53 | ChangeType change_type = 4; 54 | 55 | // Collection of advice provided for this change, useful for determining the 56 | // possible impact of this change. 57 | repeated Advice advices = 5; 58 | } 59 | 60 | // Generated advice about this change, used for providing more 61 | // information about how a change will affect the existing service. 62 | message Advice { 63 | // Useful description for why this advice was applied and what actions should 64 | // be taken to mitigate any implied risks. 65 | string description = 2; 66 | } 67 | 68 | // Classifies set of possible modifications to an object in the service 69 | // configuration. 70 | enum ChangeType { 71 | // No value was provided. 72 | CHANGE_TYPE_UNSPECIFIED = 0; 73 | 74 | // The changed object exists in the 'new' service configuration, but not 75 | // in the 'old' service configuration. 76 | ADDED = 1; 77 | 78 | // The changed object exists in the 'old' service configuration, but not 79 | // in the 'new' service configuration. 80 | REMOVED = 2; 81 | 82 | // The changed object exists in both service configurations, but its value 83 | // is different. 84 | MODIFIED = 3; 85 | } 86 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/consumer.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ConsumerProto"; 22 | option java_package = "com.google.api"; 23 | 24 | 25 | // A descriptor for defining project properties for a service. One service may 26 | // have many consumer projects, and the service may want to behave differently 27 | // depending on some properties on the project. For example, a project may be 28 | // associated with a school, or a business, or a government agency, a business 29 | // type property on the project may affect how a service responds to the client. 30 | // This descriptor defines which properties are allowed to be set on a project. 31 | // 32 | // Example: 33 | // 34 | // project_properties: 35 | // properties: 36 | // - name: NO_WATERMARK 37 | // type: BOOL 38 | // description: Allows usage of the API without watermarks. 39 | // - name: EXTENDED_TILE_CACHE_PERIOD 40 | // type: INT64 41 | message ProjectProperties { 42 | // List of per consumer project-specific properties. 43 | repeated Property properties = 1; 44 | } 45 | 46 | // Defines project properties. 47 | // 48 | // API services can define properties that can be assigned to consumer projects 49 | // so that backends can perform response customization without having to make 50 | // additional calls or maintain additional storage. For example, Maps API 51 | // defines properties that controls map tile cache period, or whether to embed a 52 | // watermark in a result. 53 | // 54 | // These values can be set via API producer console. Only API providers can 55 | // define and set these properties. 56 | message Property { 57 | // Supported data type of the property values 58 | enum PropertyType { 59 | // The type is unspecified, and will result in an error. 60 | UNSPECIFIED = 0; 61 | 62 | // The type is `int64`. 63 | INT64 = 1; 64 | 65 | // The type is `bool`. 66 | BOOL = 2; 67 | 68 | // The type is `string`. 69 | STRING = 3; 70 | 71 | // The type is 'double'. 72 | DOUBLE = 4; 73 | } 74 | 75 | // The name of the property (a.k.a key). 76 | string name = 1; 77 | 78 | // The type of this property. 79 | PropertyType type = 2; 80 | 81 | // The description of the property 82 | string description = 3; 83 | } 84 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/context.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ContextProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // `Context` defines which contexts an API requests. 27 | // 28 | // Example: 29 | // 30 | // context: 31 | // rules: 32 | // - selector: "*" 33 | // requested: 34 | // - google.rpc.context.ProjectContext 35 | // - google.rpc.context.OriginContext 36 | // 37 | // The above specifies that all methods in the API request 38 | // `google.rpc.context.ProjectContext` and 39 | // `google.rpc.context.OriginContext`. 40 | // 41 | // Available context types are defined in package 42 | // `google.rpc.context`. 43 | message Context { 44 | // A list of RPC context rules that apply to individual API methods. 45 | // 46 | // **NOTE:** All service configuration rules follow "last one wins" order. 47 | repeated ContextRule rules = 1; 48 | } 49 | 50 | // A context rule provides information about the context for an individual API 51 | // element. 52 | message ContextRule { 53 | // Selects the methods to which this rule applies. 54 | // 55 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 56 | string selector = 1; 57 | 58 | // A list of full type names of requested contexts. 59 | repeated string requested = 2; 60 | 61 | // A list of full type names of provided contexts. 62 | repeated string provided = 3; 63 | } 64 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/control.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ControlProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Selects and configures the service controller used by the service. The 27 | // service controller handles features like abuse, quota, billing, logging, 28 | // monitoring, etc. 29 | message Control { 30 | // The service control environment to use. If empty, no control plane 31 | // feature (like quota and billing) will be enabled. 32 | string environment = 1; 33 | } 34 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/endpoint.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "EndpointProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // `Endpoint` describes a network endpoint that serves a set of APIs. 29 | // A service may expose any number of endpoints, and all endpoints share the 30 | // same service configuration, such as quota configuration and monitoring 31 | // configuration. 32 | // 33 | // Example service configuration: 34 | // 35 | // name: library-example.googleapis.com 36 | // endpoints: 37 | // # Below entry makes 'google.example.library.v1.Library' 38 | // # API be served from endpoint address library-example.googleapis.com. 39 | // # It also allows HTTP OPTIONS calls to be passed to the backend, for 40 | // # it to decide whether the subsequent cross-origin request is 41 | // # allowed to proceed. 42 | // - name: library-example.googleapis.com 43 | // allow_cors: true 44 | message Endpoint { 45 | // The canonical name of this endpoint. 46 | string name = 1; 47 | 48 | // DEPRECATED: This field is no longer supported. Instead of using aliases, 49 | // please specify multiple [google.api.Endpoint][google.api.Endpoint] for each of the intented 50 | // alias. 51 | // 52 | // Additional names that this endpoint will be hosted on. 53 | repeated string aliases = 2; 54 | 55 | // The list of APIs served by this endpoint. 56 | repeated string apis = 3; 57 | 58 | // The list of features enabled on this endpoint. 59 | repeated string features = 4; 60 | 61 | // The specification of an Internet routable address of API frontend that will 62 | // handle requests to this [API Endpoint](https://cloud.google.com/apis/design/glossary). 63 | // It should be either a valid IPv4 address or a fully-qualified domain name. 64 | // For example, "8.8.8.8" or "myservice.appspot.com". 65 | string target = 101; 66 | 67 | // Allowing 68 | // [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka 69 | // cross-domain traffic, would allow the backends served from this endpoint to 70 | // receive and respond to HTTP OPTIONS requests. The response will be used by 71 | // the browser to determine whether the subsequent cross-origin request is 72 | // allowed to proceed. 73 | bool allow_cors = 5; 74 | } 75 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/experimental/authorization_config.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api;api"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "AuthorizationConfigProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Configuration of authorization. 27 | // 28 | // This section determines the authorization provider, if unspecified, then no 29 | // authorization check will be done. 30 | // 31 | // Example: 32 | // 33 | // experimental: 34 | // authorization: 35 | // provider: firebaserules.googleapis.com 36 | message AuthorizationConfig { 37 | // The name of the authorization provider, such as 38 | // firebaserules.googleapis.com. 39 | string provider = 1; 40 | } 41 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/experimental/experimental.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/experimental/authorization_config.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api;api"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "ExperimentalProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | 29 | // Experimental service configuration. These configuration options can 30 | // only be used by whitelisted users. 31 | message Experimental { 32 | // Authorization configuration. 33 | AuthorizationConfig authorization = 8; 34 | } 35 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/httpbody.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "HttpBodyProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Message that represents an arbitrary HTTP body. It should only be used for 27 | // payload formats that can't be represented as JSON, such as raw binary or 28 | // an HTML page. 29 | // 30 | // 31 | // This message can be used both in streaming and non-streaming API methods in 32 | // the request as well as the response. 33 | // 34 | // It can be used as a top-level request field, which is convenient if one 35 | // wants to extract parameters from either the URL or HTTP template into the 36 | // request fields and also want access to the raw HTTP body. 37 | // 38 | // Example: 39 | // 40 | // message GetResourceRequest { 41 | // // A unique request id. 42 | // string request_id = 1; 43 | // 44 | // // The raw HTTP body is bound to this field. 45 | // google.api.HttpBody http_body = 2; 46 | // } 47 | // 48 | // service ResourceService { 49 | // rpc GetResource(GetResourceRequest) returns (google.api.HttpBody); 50 | // rpc UpdateResource(google.api.HttpBody) returns (google.protobuf.Empty); 51 | // } 52 | // 53 | // Example with streaming methods: 54 | // 55 | // service CaldavService { 56 | // rpc GetCalendar(stream google.api.HttpBody) 57 | // returns (stream google.api.HttpBody); 58 | // rpc UpdateCalendar(stream google.api.HttpBody) 59 | // returns (stream google.api.HttpBody); 60 | // } 61 | // 62 | // Use of this type only changes how the request and response bodies are 63 | // handled, all other features will continue to work unchanged. 64 | message HttpBody { 65 | // The HTTP Content-Type string representing the content type of the body. 66 | string content_type = 1; 67 | 68 | // HTTP body binary data. 69 | bytes data = 2; 70 | } 71 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/label.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option cc_enable_arenas = true; 20 | option go_package = "google.golang.org/genproto/googleapis/api/label;label"; 21 | option java_multiple_files = true; 22 | option java_outer_classname = "LabelProto"; 23 | option java_package = "com.google.api"; 24 | option objc_class_prefix = "GAPI"; 25 | 26 | 27 | // A description of a label. 28 | message LabelDescriptor { 29 | // Value types that can be used as label values. 30 | enum ValueType { 31 | // A variable-length string. This is the default. 32 | STRING = 0; 33 | 34 | // Boolean; true or false. 35 | BOOL = 1; 36 | 37 | // A 64-bit signed integer. 38 | INT64 = 2; 39 | } 40 | 41 | // The label key. 42 | string key = 1; 43 | 44 | // The type of data that can be assigned to the label. 45 | ValueType value_type = 2; 46 | 47 | // A human-readable description for the label. 48 | string description = 3; 49 | } 50 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/log.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/label.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "LogProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // A description of a log type. Example in YAML format: 29 | // 30 | // - name: library.googleapis.com/activity_history 31 | // description: The history of borrowing and returning library items. 32 | // display_name: Activity 33 | // labels: 34 | // - key: /customer_id 35 | // description: Identifier of a library customer 36 | message LogDescriptor { 37 | // The name of the log. It must be less than 512 characters long and can 38 | // include the following characters: upper- and lower-case alphanumeric 39 | // characters [A-Za-z0-9], and punctuation characters including 40 | // slash, underscore, hyphen, period [/_-.]. 41 | string name = 1; 42 | 43 | // The set of labels that are available to describe a specific log entry. 44 | // Runtime requests that contain labels not specified here are 45 | // considered invalid. 46 | repeated LabelDescriptor labels = 2; 47 | 48 | // A human-readable description of this log. This information appears in 49 | // the documentation and can contain details. 50 | string description = 3; 51 | 52 | // The human-readable name for this log. This information appears on 53 | // the user interface and should be concise. 54 | string display_name = 4; 55 | } 56 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/logging.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "LoggingProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // Logging configuration of the service. 29 | // 30 | // The following example shows how to configure logs to be sent to the 31 | // producer and consumer projects. In the example, the `activity_history` 32 | // log is sent to both the producer and consumer projects, whereas the 33 | // `purchase_history` log is only sent to the producer project. 34 | // 35 | // monitored_resources: 36 | // - type: library.googleapis.com/branch 37 | // labels: 38 | // - key: /city 39 | // description: The city where the library branch is located in. 40 | // - key: /name 41 | // description: The name of the branch. 42 | // logs: 43 | // - name: activity_history 44 | // labels: 45 | // - key: /customer_id 46 | // - name: purchase_history 47 | // logging: 48 | // producer_destinations: 49 | // - monitored_resource: library.googleapis.com/branch 50 | // logs: 51 | // - activity_history 52 | // - purchase_history 53 | // consumer_destinations: 54 | // - monitored_resource: library.googleapis.com/branch 55 | // logs: 56 | // - activity_history 57 | message Logging { 58 | // Configuration of a specific logging destination (the producer project 59 | // or the consumer project). 60 | message LoggingDestination { 61 | // The monitored resource type. The type must be defined in the 62 | // [Service.monitored_resources][google.api.Service.monitored_resources] section. 63 | string monitored_resource = 3; 64 | 65 | // Names of the logs to be sent to this destination. Each name must 66 | // be defined in the [Service.logs][google.api.Service.logs] section. If the log name is 67 | // not a domain scoped name, it will be automatically prefixed with 68 | // the service name followed by "/". 69 | repeated string logs = 1; 70 | } 71 | 72 | // Logging configurations for sending logs to the producer project. 73 | // There can be multiple producer destinations, each one must have a 74 | // different monitored resource type. A log can be used in at most 75 | // one producer destination. 76 | repeated LoggingDestination producer_destinations = 1; 77 | 78 | // Logging configurations for sending logs to the consumer project. 79 | // There can be multiple consumer destinations, each one must have a 80 | // different monitored resource type. A log can be used in at most 81 | // one consumer destination. 82 | repeated LoggingDestination consumer_destinations = 2; 83 | } 84 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/servicecontrol/v1/check_error.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api.servicecontrol.v1; 18 | 19 | import "google/api/annotations.proto"; 20 | 21 | option cc_enable_arenas = true; 22 | option go_package = "google.golang.org/genproto/googleapis/api/servicecontrol/v1;servicecontrol"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "CheckErrorProto"; 25 | option java_package = "com.google.api.servicecontrol.v1"; 26 | 27 | 28 | // Defines the errors to be returned in 29 | // [google.api.servicecontrol.v1.CheckResponse.check_errors][google.api.servicecontrol.v1.CheckResponse.check_errors]. 30 | message CheckError { 31 | // Error codes for Check responses. 32 | enum Code { 33 | // This is never used in `CheckResponse`. 34 | ERROR_CODE_UNSPECIFIED = 0; 35 | 36 | // The consumer's project id was not found. 37 | // Same as [google.rpc.Code.NOT_FOUND][]. 38 | NOT_FOUND = 5; 39 | 40 | // The consumer doesn't have access to the specified resource. 41 | // Same as [google.rpc.Code.PERMISSION_DENIED][]. 42 | PERMISSION_DENIED = 7; 43 | 44 | // Quota check failed. Same as [google.rpc.Code.RESOURCE_EXHAUSTED][]. 45 | RESOURCE_EXHAUSTED = 8; 46 | 47 | // The consumer hasn't activated the service. 48 | SERVICE_NOT_ACTIVATED = 104; 49 | 50 | // The consumer cannot access the service because billing is disabled. 51 | BILLING_DISABLED = 107; 52 | 53 | // The consumer's project has been marked as deleted (soft deletion). 54 | PROJECT_DELETED = 108; 55 | 56 | // The consumer's project number or id does not represent a valid project. 57 | PROJECT_INVALID = 114; 58 | 59 | // The IP address of the consumer is invalid for the specific consumer 60 | // project. 61 | IP_ADDRESS_BLOCKED = 109; 62 | 63 | // The referer address of the consumer request is invalid for the specific 64 | // consumer project. 65 | REFERER_BLOCKED = 110; 66 | 67 | // The client application of the consumer request is invalid for the 68 | // specific consumer project. 69 | CLIENT_APP_BLOCKED = 111; 70 | 71 | // The consumer's API key is invalid. 72 | API_KEY_INVALID = 105; 73 | 74 | // The consumer's API Key has expired. 75 | API_KEY_EXPIRED = 112; 76 | 77 | // The consumer's API Key was not found in config record. 78 | API_KEY_NOT_FOUND = 113; 79 | 80 | // The backend server for looking up project id/number is unavailable. 81 | NAMESPACE_LOOKUP_UNAVAILABLE = 300; 82 | 83 | // The backend server for checking service status is unavailable. 84 | SERVICE_STATUS_UNAVAILABLE = 301; 85 | 86 | // The backend server for checking billing status is unavailable. 87 | BILLING_STATUS_UNAVAILABLE = 302; 88 | } 89 | 90 | // The error code. 91 | Code code = 1; 92 | 93 | // Free-form text providing details on the error cause of the error. 94 | string detail = 2; 95 | } 96 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/servicecontrol/v1/log_entry.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api.servicecontrol.v1; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/logging/type/log_severity.proto"; 21 | import "google/protobuf/any.proto"; 22 | import "google/protobuf/struct.proto"; 23 | import "google/protobuf/timestamp.proto"; 24 | 25 | option go_package = "google.golang.org/genproto/googleapis/api/servicecontrol/v1;servicecontrol"; 26 | option java_multiple_files = true; 27 | option java_outer_classname = "LogEntryProto"; 28 | option java_package = "com.google.api.servicecontrol.v1"; 29 | 30 | 31 | // An individual log entry. 32 | message LogEntry { 33 | // Required. The log to which this log entry belongs. Examples: `"syslog"`, 34 | // `"book_log"`. 35 | string name = 10; 36 | 37 | // The time the event described by the log entry occurred. If 38 | // omitted, defaults to operation start time. 39 | google.protobuf.Timestamp timestamp = 11; 40 | 41 | // The severity of the log entry. The default value is 42 | // `LogSeverity.DEFAULT`. 43 | google.logging.type.LogSeverity severity = 12; 44 | 45 | // A unique ID for the log entry used for deduplication. If omitted, 46 | // the implementation will generate one based on operation_id. 47 | string insert_id = 4; 48 | 49 | // A set of user-defined (key, value) data that provides additional 50 | // information about the log entry. 51 | map labels = 13; 52 | 53 | // The log entry payload, which can be one of multiple types. 54 | oneof payload { 55 | // The log entry payload, represented as a protocol buffer that is 56 | // expressed as a JSON object. The only accepted type currently is 57 | // [AuditLog][google.cloud.audit.AuditLog]. 58 | google.protobuf.Any proto_payload = 2; 59 | 60 | // The log entry payload, represented as a Unicode string (UTF-8). 61 | string text_payload = 3; 62 | 63 | // The log entry payload, represented as a structure that 64 | // is expressed as a JSON object. 65 | google.protobuf.Struct struct_payload = 6; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/servicecontrol/v1/metric_value.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api.servicecontrol.v1; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/servicecontrol/v1/distribution.proto"; 21 | import "google/protobuf/timestamp.proto"; 22 | import "google/type/money.proto"; 23 | 24 | option cc_enable_arenas = true; 25 | option go_package = "google.golang.org/genproto/googleapis/api/servicecontrol/v1;servicecontrol"; 26 | option java_multiple_files = true; 27 | option java_outer_classname = "MetricValueSetProto"; 28 | option java_package = "com.google.api.servicecontrol.v1"; 29 | 30 | 31 | // Represents a single metric value. 32 | message MetricValue { 33 | // The labels describing the metric value. 34 | // See comments on [google.api.servicecontrol.v1.Operation.labels][google.api.servicecontrol.v1.Operation.labels] for 35 | // the overriding relationship. 36 | map labels = 1; 37 | 38 | // The start of the time period over which this metric value's measurement 39 | // applies. The time period has different semantics for different metric 40 | // types (cumulative, delta, and gauge). See the metric definition 41 | // documentation in the service configuration for details. 42 | google.protobuf.Timestamp start_time = 2; 43 | 44 | // The end of the time period over which this metric value's measurement 45 | // applies. 46 | google.protobuf.Timestamp end_time = 3; 47 | 48 | // The value. The type of value used in the request must 49 | // agree with the metric definition in the service configuration, otherwise 50 | // the MetricValue is rejected. 51 | oneof value { 52 | // A boolean value. 53 | bool bool_value = 4; 54 | 55 | // A signed 64-bit integer value. 56 | int64 int64_value = 5; 57 | 58 | // A double precision floating point value. 59 | double double_value = 6; 60 | 61 | // A text string value. 62 | string string_value = 7; 63 | 64 | // A distribution value. 65 | Distribution distribution_value = 8; 66 | } 67 | } 68 | 69 | // Represents a set of metric values in the same metric. 70 | // Each metric value in the set should have a unique combination of start time, 71 | // end time, and label values. 72 | message MetricValueSet { 73 | // The metric name defined in the service configuration. 74 | string metric_name = 1; 75 | 76 | // The values in this metric. 77 | repeated MetricValue metric_values = 2; 78 | } 79 | -------------------------------------------------------------------------------- /HTM.Communication/google/api/source_info.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "SourceInfoProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // Source information used to create a Service Config 29 | message SourceInfo { 30 | // All files used during config generation. 31 | repeated google.protobuf.Any source_files = 1; 32 | } 33 | -------------------------------------------------------------------------------- /HTM.Core.Tests/Actors/RequestHandlerActorTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Akka.Actor; 3 | using Akka.TestKit; 4 | using Akka.TestKit.Xunit2; 5 | using HTM.Core.Actors; 6 | using HTM.Infrastructure.Devices.Messages.Requests; 7 | using Xunit; 8 | 9 | namespace HTM.Core.Tests.Actors; 10 | 11 | public class RequestHandlerActorTests : TestKit 12 | { 13 | [Fact] 14 | public void WhenReceiveRequestShouldSaveSenderId() 15 | { 16 | // Arrange 17 | var requestHandlerActor = ActorOf(Props.Create()); 18 | var request = new SendMessageRequest("test"); 19 | 20 | var subscriber = CreateTestProbe("subscriber"); 21 | Sys.EventStream.Subscribe(subscriber, typeof(SendMessageRequest)); 22 | 23 | subscriber.SetAutoPilot(new DelegateAutoPilot((sender, message) => 24 | { 25 | var requestId = (message as SendMessageRequest)?.RequestId ?? Guid.Empty; 26 | 27 | sender.Tell(new SendMessageResponse(requestId)); 28 | 29 | return AutoPilot.KeepRunning; 30 | })); 31 | 32 | // Act 33 | requestHandlerActor.Tell(request); 34 | 35 | // Assert 36 | ExpectMsg(response => response.RequestId == request.RequestId); 37 | } 38 | } -------------------------------------------------------------------------------- /HTM.Core.Tests/Actors/TemperatureMeasurementActorTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Akka.Actor; 3 | using Akka.TestKit.Xunit2; 4 | using HTM.Core.Actors; 5 | using HTM.Core.Adapters; 6 | using HTM.Infrastructure.Measurements.Messages.Requests; 7 | using HTM.Infrastructure.Models; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace HTM.Core.Tests.Actors; 12 | 13 | public class TemperatureMeasurementActorTests : TestKit 14 | { 15 | [Fact] 16 | public void WhenReceiveGetLastTemperatureMeasurementRequestShouldReturnLastTemperatureMeasurement() 17 | { 18 | // Arrange 19 | const long measurementId = 1; 20 | 21 | var temperatureMeasurementDaoMock = new Mock(); 22 | temperatureMeasurementDaoMock 23 | .Setup(x => x.GetLastMeasurement()) 24 | .Returns(Task.FromResult(new TemperatureMeasurement 25 | { 26 | Id = measurementId 27 | })); 28 | 29 | var temperatureMeasurementActor = ActorOf(Props.Create(temperatureMeasurementDaoMock.Object)); 30 | 31 | // Act 32 | temperatureMeasurementActor.Tell(new GetLastTemperatureMeasurementRequest()); 33 | 34 | // Assert 35 | ExpectMsg(response => response.TemperatureMeasurement.Id == measurementId); 36 | } 37 | } -------------------------------------------------------------------------------- /HTM.Core.Tests/HTM.Core.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /HTM.Core/Actors/DevicesHealthMonitorActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Event; 3 | using HTM.Infrastructure.Akka; 4 | using HTM.Infrastructure.Devices.Enums; 5 | using HTM.Infrastructure.Devices.Messages.Events; 6 | using HTM.Infrastructure.Devices.Messages.Requests; 7 | 8 | namespace HTM.Core.Actors; 9 | 10 | public class DevicesHealthMonitorActor : BaseActor 11 | { 12 | private readonly Dictionary _devicesConnectionsState = 13 | Enum.GetValues(typeof(DeviceType)) 14 | .Cast() 15 | .ToDictionary(x => x, x => false); 16 | 17 | public DevicesHealthMonitorActor() 18 | { 19 | Receive(OnDeviceConnectionChanged); 20 | Receive(request => 21 | { 22 | var isConnected = _devicesConnectionsState[request.DeviceType]; 23 | Sender.Tell(new GetDeviceConnectionStateResponse(request.RequestId, isConnected)); 24 | }); 25 | 26 | Context.System.EventStream.Subscribe(Self); 27 | Context.System.EventStream.Subscribe(Self); 28 | } 29 | 30 | private void OnDeviceConnectionChanged(DeviceConnectionChangedEvent @event) 31 | { 32 | Logger.Info("{DeviceConnectionChangedEvent} | Device={Device}, IsConnected={IsConnected}", 33 | nameof(DeviceConnectionChangedEvent), @event.DeviceType, @event.IsConnected); 34 | 35 | _devicesConnectionsState[@event.DeviceType] = @event.IsConnected; 36 | } 37 | } -------------------------------------------------------------------------------- /HTM.Core/Actors/HtmActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.DependencyInjection; 2 | using HTM.Communication.Actors; 3 | using HTM.Core.Devices.Arduino.Actors; 4 | using HTM.Infrastructure.Akka; 5 | 6 | namespace HTM.Core.Actors; 7 | 8 | public class HtmActor : BaseActor 9 | { 10 | public HtmActor() 11 | { 12 | AddActor(); 13 | AddActor(); 14 | AddActor(); 15 | AddActor(); 16 | AddActor(); 17 | AddActor(); 18 | AddActor(); 19 | } 20 | 21 | private void AddActor() where T : BaseActor 22 | { 23 | Context.ActorOf(DependencyResolver.For(Context.System).Props(), typeof(T).Name); 24 | } 25 | } -------------------------------------------------------------------------------- /HTM.Core/Actors/RequestHandlerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using HTM.Infrastructure.Akka; 3 | using HTM.Infrastructure.MessagesBase; 4 | 5 | namespace HTM.Core.Actors; 6 | 7 | public class RequestHandlerActor : BaseActor 8 | { 9 | private readonly Dictionary _messageIdToActor = new(); 10 | 11 | public RequestHandlerActor() 12 | { 13 | Receive(SaveRequestSenderAndPublishToEventStream); 14 | Receive(SendResponseToSenderAndRemoveFromDictionary); 15 | } 16 | 17 | private void SaveRequestSenderAndPublishToEventStream(T request) where T : HtmRequest 18 | { 19 | Logger.Info("SaveRequestSenderAndPublishToEventStream | RequestId={RequestId}", request.RequestId); 20 | 21 | _messageIdToActor.Add(request.RequestId, Sender); 22 | 23 | Context.System.EventStream.Publish(request); 24 | } 25 | 26 | private void SendResponseToSenderAndRemoveFromDictionary(T response) where T : HtmResponse 27 | { 28 | if (!_messageIdToActor.ContainsKey(response.RequestId)) 29 | { 30 | Logger.Error("SendResponseToSenderAndRemoveFromDictionary | Sender not recognized, RequestId={RequestId}", response.RequestId); 31 | return; 32 | } 33 | 34 | _messageIdToActor[response.RequestId].Tell(response); 35 | _messageIdToActor.Remove(response.RequestId); 36 | } 37 | } -------------------------------------------------------------------------------- /HTM.Core/Actors/TemperatureMeasurementActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Event; 3 | using HTM.Core.Adapters; 4 | using HTM.Infrastructure.Akka; 5 | using HTM.Infrastructure.Measurements.Messages.Requests; 6 | using HTM.Infrastructure.Messages.Events; 7 | 8 | namespace HTM.Core.Actors; 9 | 10 | public class TemperatureMeasurementActor : BaseActor 11 | { 12 | private readonly ITemperatureMeasurementDao _temperatureMeasurementDao; 13 | 14 | public TemperatureMeasurementActor(ITemperatureMeasurementDao temperatureMeasurementDao) 15 | { 16 | _temperatureMeasurementDao = temperatureMeasurementDao; 17 | 18 | Receive(AddMeasurement); 19 | Receive(GetLastMeasurement); 20 | Receive(GetMeasurementsByDateRange); 21 | 22 | Context.System.EventStream.Subscribe(Self); 23 | Context.System.EventStream.Subscribe(Self); 24 | Context.System.EventStream.Subscribe(Self); 25 | 26 | Context.System.EventStream.Publish(TemperatureMeasurementActorInitializedEvent.Instance); 27 | } 28 | 29 | private void AddMeasurement(AddTemperatureMeasurementRequest request) 30 | { 31 | Logger.Info("AddMeasurement"); 32 | 33 | _temperatureMeasurementDao.AddMeasurement(request.TemperatureMeasurement) 34 | .PipeTo( 35 | Sender, 36 | Self, 37 | () => AddTemperatureMeasurementResponse.WithSuccess(request.RequestId), 38 | ex => AddTemperatureMeasurementResponse.WithFailure(request.RequestId, ex)); 39 | } 40 | 41 | private void GetLastMeasurement(GetLastTemperatureMeasurementRequest request) 42 | { 43 | Logger.Info("GetLastMeasurement"); 44 | 45 | _temperatureMeasurementDao.GetLastMeasurement() 46 | .PipeTo( 47 | Sender, 48 | Self, 49 | data => GetLastTemperatureMeasurementResponse.WithSuccess(request.RequestId, data), 50 | ex => GetLastTemperatureMeasurementResponse.WithFailure(request.RequestId, ex)); 51 | } 52 | 53 | private void GetMeasurementsByDateRange(GetTemperatureMeasurementsByDateRangeRequest request) 54 | { 55 | Logger.Info("GetMeasurementsByDateRange | From={From}, To={To}", request.From, request.To); 56 | 57 | _temperatureMeasurementDao.GetMeasurementsByDateRange(request.From, request.To) 58 | .PipeTo( 59 | Sender, 60 | Self, 61 | data => GetTemperatureMeasurementsByDateRangeResponse.WithSuccess(request.RequestId, data), 62 | ex => GetTemperatureMeasurementsByDateRangeResponse.WithFailure(request.RequestId, ex)); 63 | } 64 | } -------------------------------------------------------------------------------- /HTM.Core/Actors/TemperatureMonitorActor.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure; 2 | using HTM.Infrastructure.Akka; 3 | using HTM.Infrastructure.Measurements.Messages.Requests; 4 | using HTM.Infrastructure.Messages.Events; 5 | using HTM.Infrastructure.Models; 6 | using System.Globalization; 7 | using Akka.Event; 8 | using HTM.Infrastructure.Devices.Messages.Requests; 9 | 10 | namespace HTM.Core.Actors; 11 | 12 | public class TemperatureMonitorActor : BaseActor 13 | { 14 | private readonly TimeSpan _loopDelay = TimeSpan.FromSeconds(10); 15 | private float? _lastTemperature; 16 | public TemperatureMonitorActor() 17 | { 18 | Receive(_ => 19 | { 20 | Context.System.EventStream.Publish(new GetLastTemperatureMeasurementRequest()); 21 | }); 22 | 23 | Receive(response => 24 | { 25 | _lastTemperature = response.TemperatureMeasurement?.Temperature; 26 | Context.System.Scheduler.ScheduleTellRepeatedly(TimeSpan.Zero, _loopDelay, Self, TimerElapsedEvent.Instance, Self); 27 | }); 28 | 29 | Receive(_ => 30 | { 31 | Context.System.EventStream.Publish(new GetMessageByCommandRequest(SerialPortCommand.GetTemperature)); 32 | }); 33 | 34 | Receive(OnGetMessageByCommandResponse); 35 | Receive(r => { }); 36 | 37 | Context.System.EventStream.Subscribe(Self); 38 | Context.System.EventStream.Subscribe(Self); 39 | } 40 | private void OnGetMessageByCommandResponse(GetMessageByCommandResponse response) 41 | { 42 | if (response.IsError) 43 | { 44 | return; 45 | } 46 | 47 | // if (!float.TryParse(response?.Message, out float temperature, CultureInfo.InvariantCulture)) 48 | // { 49 | // return; // InvalidTemperatureException 50 | // } 51 | 52 | var temperature = (float)Math.Round(float.Parse(response.Message ?? "9999", CultureInfo.InvariantCulture), 2); 53 | 54 | if (temperature == _lastTemperature) 55 | { 56 | return; 57 | } 58 | 59 | _lastTemperature = temperature; 60 | 61 | Context.System.EventStream.Publish(new AddTemperatureMeasurementRequest(new TemperatureMeasurement 62 | { 63 | MeasurementDate = DateTime.Now, 64 | Temperature = temperature 65 | })); 66 | } 67 | } -------------------------------------------------------------------------------- /HTM.Core/Adapters/ITemperatureMeasurementDao.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Models; 2 | 3 | namespace HTM.Core.Adapters; 4 | 5 | public interface ITemperatureMeasurementDao 6 | { 7 | Task AddMeasurement(TemperatureMeasurement temperatureMeasurement); 8 | Task GetLastMeasurement(); 9 | Task GetMeasurementsByDateRange(DateTime from, DateTime to); 10 | } -------------------------------------------------------------------------------- /HTM.Core/Devices/Arduino/Actors/ArduinoActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.DependencyInjection; 3 | using Akka.Event; 4 | using HTM.Infrastructure.Akka; 5 | using HTM.Infrastructure.Devices.Messages.Requests; 6 | using HTM.Infrastructure.MessagesBase; 7 | 8 | namespace HTM.Core.Devices.Arduino.Actors; 9 | 10 | public class ArduinoActor : BaseActor 11 | { 12 | public ArduinoActor() 13 | { 14 | var arduinoBridgeActor = Context.ActorOf(DependencyResolver.For(Context.System).Props(), nameof(ArduinoBridgeActor)); 15 | 16 | Receive(arduinoBridgeActor.Forward); 17 | Receive(Context.System.EventStream.Publish); 18 | 19 | Context.System.EventStream.Subscribe(Self); 20 | } 21 | } -------------------------------------------------------------------------------- /HTM.Core/Devices/Arduino/Actors/ArduinoBridgeActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using HTM.Infrastructure.Akka; 3 | using HTM.Infrastructure.Devices.Adapters; 4 | using HTM.Infrastructure.Devices.Enums; 5 | using HTM.Infrastructure.Devices.Messages; 6 | using HTM.Infrastructure.Devices.Messages.Events; 7 | using HTM.Infrastructure.Devices.Messages.Requests; 8 | using HTM.Infrastructure.Models; 9 | 10 | namespace HTM.Core.Devices.Arduino.Actors; 11 | 12 | public class ArduinoBridgeActor : BaseActor 13 | { 14 | private readonly ISerialPortDevice _serialPortDevice; 15 | private readonly IActorRef _deviceActor; 16 | 17 | public ArduinoBridgeActor(ISerialPortDevice serialPortDevice) 18 | { 19 | _deviceActor = Context.Parent; 20 | 21 | _serialPortDevice = serialPortDevice; 22 | _serialPortDevice.ConnectionChanged += NotifyArduinoConnectionChanged; 23 | _serialPortDevice.OnMessagesReceived += NotifyArduinoMessagesReceived; 24 | 25 | Receive( 26 | _ => Logger.Info("ArduinoBridgeActor | Device initialization success"), 27 | result => !result.IsError); 28 | 29 | Receive( 30 | result => Logger.Error("ArduinoBridgeActor | Device initialization Error={Error}", result.Exception.Message), 31 | result => result.IsError); 32 | 33 | Receive(SendMessage); 34 | } 35 | 36 | protected override void PreStart() 37 | { 38 | _serialPortDevice.Initialize() 39 | .PipeTo( 40 | Self, 41 | Self, 42 | () => InitializationResultMessage.WithSuccess, 43 | InitializationResultMessage.WithError); 44 | } 45 | 46 | protected override void PostStop() 47 | { 48 | _serialPortDevice?.Dispose(); 49 | } 50 | 51 | private void SendMessage(SendMessageRequest request) 52 | { 53 | SendMessageResponse response; 54 | 55 | try 56 | { 57 | _serialPortDevice.SendMessage(request.Message); 58 | 59 | response = new SendMessageResponse(request.RequestId); 60 | } 61 | catch (Exception ex) 62 | { 63 | response = new SendMessageResponse(request.RequestId, ex); 64 | } 65 | 66 | Sender.Tell(response); 67 | } 68 | 69 | private void NotifyArduinoConnectionChanged(object sender, bool isConnected) 70 | { 71 | _deviceActor.Tell(new DeviceConnectionChangedEvent(DeviceType.Arduino, isConnected)); 72 | } 73 | 74 | private void NotifyArduinoMessagesReceived(object sender, SerialPortMessage[] messages) 75 | { 76 | foreach (var message in messages) 77 | { 78 | Logger.Info("NotifyArduinoMessageReceived | Type={Type}, Text={Text}", message.Type, message.Text); 79 | } 80 | 81 | _deviceActor.Tell(new SerialPortMessageReceivedEvent(messages)); 82 | } 83 | } -------------------------------------------------------------------------------- /HTM.Core/Devices/Arduino/Actors/ArduinoMessengerActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Event; 3 | using HTM.Infrastructure.Akka; 4 | using HTM.Infrastructure.Devices.Messages.Events; 5 | using HTM.Infrastructure.Devices.Messages.Requests; 6 | using HTM.Infrastructure.Messages.Events; 7 | 8 | namespace HTM.Core.Devices.Arduino.Actors; 9 | 10 | record RequestData(IActorRef Sender, GetMessageByCommandRequest Request); 11 | 12 | public class ArduinoMessengerActor : BaseActor 13 | { 14 | private readonly TimeSpan _timerDelay = TimeSpan.FromMilliseconds(100); 15 | 16 | private readonly List _requests; 17 | private bool _isArduinoConnected; 18 | private DateTime _arduinoConnectedAt; 19 | 20 | private RequestData _currentRequestData; 21 | 22 | public ArduinoMessengerActor() 23 | { 24 | _requests = new List(); 25 | 26 | Receive(request => 27 | { 28 | Logger.Info("{ArduinoMessengerActor} Adding RequestId={RequestId}", nameof(ArduinoMessengerActor), request.RequestId); 29 | _requests.Add(new RequestData(Sender, request)); 30 | }); 31 | 32 | Receive(FinishHandleRequest); 33 | Receive(_ => StartHandleRequest()); 34 | 35 | Receive(e => 36 | { 37 | _arduinoConnectedAt = DateTime.Now; 38 | _isArduinoConnected = e.IsConnected; 39 | }); 40 | 41 | Context.System.EventStream.Subscribe(Self); 42 | Context.System.EventStream.Subscribe(Self); 43 | 44 | Context.System.Scheduler.ScheduleTellRepeatedly(TimeSpan.Zero, _timerDelay, Self, TimerElapsedEvent.Instance, Self); 45 | } 46 | 47 | private void StartHandleRequest() 48 | { 49 | if (!_isArduinoConnected || !_requests.Any()) 50 | { 51 | return; 52 | } 53 | 54 | if (DateTime.Now - _arduinoConnectedAt <= TimeSpan.FromSeconds(5)) 55 | { 56 | return; 57 | } 58 | 59 | if (!Context.Child(nameof(GetMessageByCommandActor)).IsNobody()) 60 | { 61 | return; 62 | } 63 | 64 | _currentRequestData = _requests.First(); 65 | 66 | Logger.Info("{StartHandleRequest} | RequestId={RequestId}, Command={Command}", 67 | nameof(StartHandleRequest), _currentRequestData?.Request.RequestId, _currentRequestData?.Request.Command); 68 | 69 | Context.ActorOf(Props.Create(_currentRequestData?.Request), nameof(GetMessageByCommandActor)); 70 | } 71 | 72 | private void FinishHandleRequest(GetMessageByCommandResponse response) 73 | { 74 | if (response.IsError) 75 | { 76 | Logger.Error("{FinishHandleRequest} | RequestId={RequestId}, Error={Error}", 77 | nameof(FinishHandleRequest), _currentRequestData?.Request.RequestId, response.Exception?.Message); 78 | } 79 | else 80 | { 81 | Logger.Info("{FinishHandleRequest} | RequestId={RequestId}, Message={Message}", 82 | nameof(FinishHandleRequest), _currentRequestData?.Request.RequestId, response.Message); 83 | 84 | _requests.Remove(_currentRequestData); 85 | 86 | } 87 | 88 | _currentRequestData?.Sender.Tell(response); 89 | } 90 | } -------------------------------------------------------------------------------- /HTM.Core/Devices/Arduino/Actors/GetMessageByCommandActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Event; 3 | using HTM.Infrastructure.Akka; 4 | using HTM.Infrastructure.Devices.Messages.Events; 5 | using HTM.Infrastructure.Devices.Messages.Requests; 6 | using HTM.Infrastructure.Messages.Events; 7 | using HTM.Infrastructure.Models; 8 | 9 | namespace HTM.Core.Devices.Arduino.Actors; 10 | 11 | public class GetMessageByCommandActor : BaseActor 12 | { 13 | private readonly GetMessageByCommandRequest _request; 14 | private const int TimeoutInSec = 5; 15 | 16 | private readonly ICancelable _cancelable; 17 | 18 | public GetMessageByCommandActor(GetMessageByCommandRequest request) 19 | { 20 | _request = request; 21 | Context.System.EventStream.Publish(new SendMessageRequest(request.Command.ToString())); 22 | _cancelable = Context.System.Scheduler.ScheduleTellOnceCancelable(TimeSpan.FromSeconds(TimeoutInSec), Self, TimeoutEvent.Instance, Self); 23 | 24 | Receive(_ => SendMessageToParent(new TimeoutException($"Timeout after {TimeoutInSec} s."))); 25 | 26 | Receive(response => 27 | { 28 | if (response.IsError) 29 | { 30 | SendMessageToParent(response.Exception); 31 | } 32 | }); 33 | 34 | Receive(e => 35 | { 36 | var message = e.Messages.FirstOrDefault(x => x.Type == SerialPortMessageType.CommandResponse); 37 | if (message == null) 38 | { 39 | return; 40 | } 41 | 42 | SendMessageToParent(message.Text); 43 | }); 44 | 45 | Context.System.EventStream.Subscribe(Self); 46 | } 47 | 48 | private void SendMessageToParent(string message) => SendMessageToParent(new GetMessageByCommandResponse(_request.RequestId, message)); 49 | private void SendMessageToParent(Exception exception) => SendMessageToParent(new GetMessageByCommandResponse(_request.RequestId, exception)); 50 | 51 | private void SendMessageToParent(GetMessageByCommandResponse response) 52 | { 53 | Context.System.EventStream.Unsubscribe(Self); 54 | _cancelable.Cancel(); 55 | Context.Parent.Tell(response); 56 | 57 | StopSelf(); 58 | } 59 | } -------------------------------------------------------------------------------- /HTM.Core/HTM.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /HTM.Core/Services/AppService.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Configuration; 3 | using Akka.DependencyInjection; 4 | using HTM.Core.Actors; 5 | using HTM.Infrastructure.Adapters; 6 | using HTM.Infrastructure.Akka; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Hosting; 9 | 10 | namespace HTM.Core.Services; 11 | 12 | public class AppService : IHostedService 13 | { 14 | private readonly IServiceProvider _serviceProvider; 15 | private ActorSystem _actorSystem; 16 | 17 | public AppService(IServiceProvider serviceProvider) 18 | { 19 | _serviceProvider = serviceProvider; 20 | } 21 | 22 | public async Task StartAsync(CancellationToken cancellationToken) 23 | { 24 | var persistenceInitializer = _serviceProvider.GetRequiredService(); 25 | await persistenceInitializer.Initialize(); 26 | 27 | var configuration = await File.ReadAllTextAsync( 28 | Path.Combine(Directory.GetCurrentDirectory(), "akkaConfig.json"), 29 | cancellationToken); 30 | 31 | var akkaConfig = ConfigurationFactory.ParseString(configuration); 32 | var actorSystemSetup = BootstrapSetup 33 | .Create() 34 | .WithConfig(akkaConfig) 35 | .And(DependencyResolverSetup.Create(_serviceProvider)); 36 | 37 | _actorSystem = ActorSystem.Create("HtmActorSystem", actorSystemSetup); 38 | _actorSystem.ActorOf(DependencyResolver.For(_actorSystem).Props(), nameof(HtmActor)); 39 | 40 | await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); 41 | 42 | var requestHandlerActor = await _actorSystem 43 | .ActorSelection("akka.tcp://HtmActorSystem@localhost:5005/user/HtmActor/RequestHandlerActor") 44 | .ResolveOne(TimeSpan.FromSeconds(5), cancellationToken); 45 | 46 | var htmActorBridge = _serviceProvider.GetRequiredService(); 47 | htmActorBridge.AddRequestHandlerActor(requestHandlerActor); 48 | } 49 | 50 | public Task StopAsync(CancellationToken cancellationToken) 51 | { 52 | _actorSystem?.Terminate(); 53 | return Task.CompletedTask; 54 | } 55 | } -------------------------------------------------------------------------------- /HTM.Database/Configurations/TemperatureMeasurementConfiguration.cs: -------------------------------------------------------------------------------- 1 | using HTM.Database.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace HTM.Database.Configurations; 6 | 7 | public class TemperatureMeasurementConfiguration: IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | //builder.Property(x => x.Temperature).HasPrecision(18, 2); 12 | } 13 | } -------------------------------------------------------------------------------- /HTM.Database/Dao/TemperatureMeasurementDao.cs: -------------------------------------------------------------------------------- 1 | using HTM.Core.Adapters; 2 | using HTM.Database.Entities; 3 | using HTM.Infrastructure.Models; 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace HTM.Database.Dao; 7 | 8 | public class TemperatureMeasurementDao : ITemperatureMeasurementDao 9 | { 10 | private readonly HtmContext _context; 11 | 12 | public TemperatureMeasurementDao(HtmContext context) 13 | { 14 | _context = context; 15 | } 16 | 17 | public async Task AddMeasurement(TemperatureMeasurement temperatureMeasurement) 18 | { 19 | await _context.TemperatureMeasurements.AddAsync(new TemperatureMeasurementDb(temperatureMeasurement)); 20 | await _context.SaveChangesAsync(); 21 | } 22 | 23 | public async Task GetLastMeasurement() 24 | { 25 | var measurement = await _context.TemperatureMeasurements 26 | .OrderByDescending(x => x.MeasurementDate) 27 | .FirstOrDefaultAsync(); 28 | 29 | return measurement?.ToModel(); 30 | } 31 | 32 | public async Task GetMeasurementsByDateRange(DateTime from, DateTime to) 33 | { 34 | return await _context.TemperatureMeasurements 35 | .OrderBy(x => x.MeasurementDate) 36 | .Where(x => x.MeasurementDate >= from && x.MeasurementDate <= to) 37 | .Select(x => x.ToModel()) 38 | .ToArrayAsync(); 39 | } 40 | } -------------------------------------------------------------------------------- /HTM.Database/DatabaseInitializer.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Adapters; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Serilog; 5 | 6 | namespace HTM.Database; 7 | 8 | public class DatabaseInitializer : IPersistenceInitializer 9 | { 10 | private readonly IServiceProvider _serviceProvider; 11 | 12 | public DatabaseInitializer(IServiceProvider serviceProvider) 13 | { 14 | _serviceProvider = serviceProvider; 15 | } 16 | 17 | public async Task Initialize() 18 | { 19 | Log.Information("Migrating database"); 20 | 21 | using var scope = _serviceProvider.CreateScope(); 22 | await using var dbContext = scope.ServiceProvider.GetRequiredService(); 23 | await dbContext.Database.MigrateAsync(); 24 | 25 | Log.Information("Migration complete"); 26 | } 27 | } -------------------------------------------------------------------------------- /HTM.Database/Entities/EntityBase.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Database.Entities; 2 | 3 | public abstract class EntityBase 4 | { 5 | public long Id { get; set; } 6 | } -------------------------------------------------------------------------------- /HTM.Database/Entities/TemperatureMeasurementDb.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Models; 2 | 3 | namespace HTM.Database.Entities; 4 | 5 | public class TemperatureMeasurementDb : EntityBase 6 | { 7 | public DateTime MeasurementDate { get; set; } 8 | public float Temperature { get; set; } 9 | 10 | private TemperatureMeasurementDb() 11 | { } 12 | 13 | public TemperatureMeasurementDb(TemperatureMeasurement temperatureMeasurement) 14 | { 15 | MeasurementDate = temperatureMeasurement.MeasurementDate; 16 | Temperature = temperatureMeasurement.Temperature; 17 | } 18 | } 19 | 20 | public static class TemperatureMeasurementExtensions 21 | { 22 | public static TemperatureMeasurement ToModel(this TemperatureMeasurementDb entity) 23 | { 24 | return new TemperatureMeasurement 25 | { 26 | Id = entity.Id, 27 | Temperature = entity.Temperature, 28 | MeasurementDate = entity.MeasurementDate 29 | }; 30 | } 31 | } -------------------------------------------------------------------------------- /HTM.Database/Extensions/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Core.Adapters; 2 | using HTM.Database.Dao; 3 | using HTM.Infrastructure.Constants; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | 8 | namespace HTM.Database.Extensions; 9 | 10 | public static class ServiceCollectionExtensions 11 | { 12 | public static void AddDatabase(this IServiceCollection services) 13 | { 14 | var connectionString = new ConfigurationBuilder() 15 | .SetBasePath(Directory.GetCurrentDirectory()) 16 | .AddJsonFile(Application.AppSettingsFile) 17 | .Build() 18 | .GetSection("Database")["ConnectionString"]; 19 | 20 | services.AddDbContext(options => options.UseSqlServer(connectionString)); 21 | services.AddScoped(); 22 | } 23 | } -------------------------------------------------------------------------------- /HTM.Database/HTM.Database.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | all 12 | runtime; build; native; contentfiles; analyzers; buildtransitive 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.0\Microsoft.Extensions.Configuration.dll 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /HTM.Database/HtmContext.cs: -------------------------------------------------------------------------------- 1 | using HTM.Database.Entities; 2 | using HTM.Infrastructure.Constants; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.Extensions.Configuration; 5 | 6 | namespace HTM.Database; 7 | 8 | public class HtmContext : DbContext 9 | { 10 | public DbSet TemperatureMeasurements { get; set; } 11 | 12 | public HtmContext() 13 | { 14 | 15 | } 16 | 17 | public HtmContext(DbContextOptions options) : base(options) 18 | { 19 | 20 | } 21 | 22 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 23 | { 24 | if (optionsBuilder.IsConfigured) 25 | return; 26 | 27 | var appDirectory = 28 | Path.Combine(new DirectoryInfo(Directory.GetCurrentDirectory())?.Parent?.FullName ?? "HTM", "HTM"); 29 | 30 | var configuration = new ConfigurationBuilder() 31 | .SetBasePath(appDirectory) 32 | .AddJsonFile(Application.AppSettingsFile) 33 | .Build(); 34 | 35 | var connectionString = configuration.GetSection("Database")["ConnectionString"]; 36 | optionsBuilder.UseSqlServer(connectionString); 37 | } 38 | 39 | protected override void OnModelCreating(ModelBuilder modelBuilder) 40 | { 41 | base.OnModelCreating(modelBuilder); 42 | 43 | modelBuilder.ApplyConfigurationsFromAssembly(typeof(HtmContext).Assembly); 44 | } 45 | } -------------------------------------------------------------------------------- /HTM.Database/Migrations/20220215201721_Initial.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using HTM.Database; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Migrations; 8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 9 | 10 | #nullable disable 11 | 12 | namespace HTM.Database.Migrations 13 | { 14 | [DbContext(typeof(HtmContext))] 15 | [Migration("20220215201721_Initial")] 16 | partial class Initial 17 | { 18 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 19 | { 20 | #pragma warning disable 612, 618 21 | modelBuilder 22 | .HasAnnotation("ProductVersion", "6.0.2") 23 | .HasAnnotation("Relational:MaxIdentifierLength", 128); 24 | 25 | SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); 26 | 27 | modelBuilder.Entity("HTM.Database.Entities.TemperatureMeasurementDb", b => 28 | { 29 | b.Property("Id") 30 | .ValueGeneratedOnAdd() 31 | .HasColumnType("bigint"); 32 | 33 | SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); 34 | 35 | b.Property("MeasurementDate") 36 | .HasColumnType("datetime2"); 37 | 38 | b.Property("Temperature") 39 | .HasColumnType("real"); 40 | 41 | b.HasKey("Id"); 42 | 43 | b.ToTable("TemperatureMeasurements"); 44 | }); 45 | #pragma warning restore 612, 618 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /HTM.Database/Migrations/20220215201721_Initial.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | #nullable disable 5 | 6 | namespace HTM.Database.Migrations 7 | { 8 | public partial class Initial : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "TemperatureMeasurements", 14 | columns: table => new 15 | { 16 | Id = table.Column(type: "bigint", nullable: false) 17 | .Annotation("SqlServer:Identity", "1, 1"), 18 | MeasurementDate = table.Column(type: "datetime2", nullable: false), 19 | Temperature = table.Column(type: "real", nullable: false) 20 | }, 21 | constraints: table => 22 | { 23 | table.PrimaryKey("PK_TemperatureMeasurements", x => x.Id); 24 | }); 25 | } 26 | 27 | protected override void Down(MigrationBuilder migrationBuilder) 28 | { 29 | migrationBuilder.DropTable( 30 | name: "TemperatureMeasurements"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /HTM.Database/Migrations/HtmContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using HTM.Database; 4 | using Microsoft.EntityFrameworkCore; 5 | using Microsoft.EntityFrameworkCore.Infrastructure; 6 | using Microsoft.EntityFrameworkCore.Metadata; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | 9 | #nullable disable 10 | 11 | namespace HTM.Database.Migrations 12 | { 13 | [DbContext(typeof(HtmContext))] 14 | partial class HtmContextModelSnapshot : ModelSnapshot 15 | { 16 | protected override void BuildModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "6.0.2") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128); 22 | 23 | SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); 24 | 25 | modelBuilder.Entity("HTM.Database.Entities.TemperatureMeasurementDb", b => 26 | { 27 | b.Property("Id") 28 | .ValueGeneratedOnAdd() 29 | .HasColumnType("bigint"); 30 | 31 | SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); 32 | 33 | b.Property("MeasurementDate") 34 | .HasColumnType("datetime2"); 35 | 36 | b.Property("Temperature") 37 | .HasColumnType("real"); 38 | 39 | b.HasKey("Id"); 40 | 41 | b.ToTable("TemperatureMeasurements"); 42 | }); 43 | #pragma warning restore 612, 618 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Configurations/ArduinoOptions.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Devices.Arduino.Configurations; 2 | 3 | public class ArduinoOptions 4 | { 5 | public const string SectionName = "Arduino"; 6 | public const string Emulator = "emulator"; 7 | 8 | public string PortName { get; set; } = "COM4"; 9 | public int PortBaudRate { get; set; } = 9600; 10 | } -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Extensions/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using HTM.Devices.Arduino.Configurations; 3 | using HTM.Devices.Arduino.Services; 4 | using HTM.Infrastructure.Constants; 5 | using HTM.Infrastructure.Devices.Adapters; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.DependencyInjection; 8 | 9 | namespace HTM.Devices.Arduino.Extensions; 10 | 11 | public static class ServiceCollectionExtensions 12 | { 13 | public static void AddArduino(this IServiceCollection services) 14 | { 15 | services.AddOptions() 16 | .Configure((o, c) => c.GetSection(ArduinoOptions.SectionName).Bind(o)); 17 | 18 | var portName = new ConfigurationBuilder() 19 | .SetBasePath(Directory.GetCurrentDirectory()) 20 | .AddJsonFile(Application.AppSettingsFile) 21 | .Build() 22 | .GetSection(ArduinoOptions.SectionName)[nameof(ArduinoOptions.PortName)]; 23 | 24 | if (portName == ArduinoOptions.Emulator) 25 | { 26 | services.AddSingleton(); 27 | } 28 | else 29 | { 30 | services.AddSingleton(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /HTM.Devices.Arduino/HTM.Devices.Arduino.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.2\Microsoft.Extensions.Configuration.dll 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Services/ArduinoEmulatorService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using HTM.Infrastructure.Devices.Adapters; 5 | using HTM.Infrastructure.Models; 6 | 7 | namespace HTM.Devices.Arduino.Services; 8 | 9 | public class ArduinoEmulatorService : ISerialPortDevice 10 | { 11 | public event EventHandler ConnectionChanged; 12 | public event EventHandler OnMessagesReceived; 13 | 14 | private readonly Random _random = new Random(); 15 | 16 | public async Task Initialize() 17 | { 18 | await Task.Delay(TimeSpan.FromSeconds(5)); 19 | 20 | ConnectionChanged?.Invoke(this, true); 21 | } 22 | 23 | public void SendMessage(string message) 24 | { 25 | if (!Enum.TryParse(message, out var command)) 26 | { 27 | return; 28 | } 29 | 30 | Thread.Sleep(1500); 31 | 32 | var callbackMessage = command switch 33 | { 34 | SerialPortCommand.TurnLedOn or SerialPortCommand.TurnLedOff => "ok", 35 | SerialPortCommand.GetTemperature => _random.Next(19, 27).ToString(), 36 | 37 | _ => string.Empty 38 | }; 39 | 40 | OnMessagesReceived?.Invoke(this, new SerialPortMessage[] { new SerialPortMessage(SerialPortMessageType.CommandResponse, callbackMessage) }); 41 | } 42 | 43 | public void Dispose() 44 | { 45 | } 46 | } -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/Sketch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ONE_WIRE_BUS 2 5 | #define DEBUG_LED_PIN 13 6 | #define LED_PIN 4 7 | #define BUTTON_PIN 7 8 | 9 | const String Event = "Event"; 10 | const String CommandResponse = "CommandResponse"; 11 | 12 | String message = ""; 13 | char* buf; 14 | bool ledState; 15 | int buttonValue = HIGH; 16 | 17 | OneWire oneWire(ONE_WIRE_BUS); 18 | DallasTemperature sensors(&oneWire); 19 | void setup() 20 | { 21 | 22 | pinMode(DEBUG_LED_PIN, OUTPUT); 23 | pinMode(LED_PIN, OUTPUT); 24 | pinMode(BUTTON_PIN, INPUT_PULLUP); 25 | 26 | sensors.begin(); 27 | 28 | Serial.begin(9600); 29 | } 30 | void loop() 31 | { 32 | String command; 33 | 34 | int currentButtonValue = digitalRead(BUTTON_PIN); 35 | if (currentButtonValue != buttonValue) 36 | { 37 | buttonValue = currentButtonValue; 38 | joinMessage(Event, buttonValue == LOW ? "ButtonLow" : "ButtonHigh"); 39 | } 40 | 41 | if (Serial.available() > 0) 42 | { 43 | command = Serial.readString(); 44 | 45 | if(command == "GetTemperature") 46 | { 47 | digitalWrite(DEBUG_LED_PIN, 1); 48 | sensors.requestTemperatures(); 49 | 50 | String value = ""; 51 | value.concat(sensors.getTempCByIndex(0)); 52 | joinMessage(CommandResponse, value); 53 | digitalWrite(DEBUG_LED_PIN, 0); 54 | } 55 | 56 | if(command == "TurnLedOn") 57 | { 58 | digitalWrite(LED_PIN, 1); 59 | ledState = true; 60 | 61 | joinMessage(CommandResponse, "ok"); 62 | } 63 | 64 | if(command == "TurnLedOff") 65 | { 66 | digitalWrite(LED_PIN, 0); 67 | ledState = false; 68 | 69 | joinMessage(CommandResponse, "ok"); 70 | } 71 | 72 | if(command == "GetLedState") 73 | { 74 | joinMessage(CommandResponse, ledState ? "1" : "0"); 75 | } 76 | } 77 | 78 | sendMessage(); 79 | delay(10); 80 | } 81 | 82 | void joinMessage(String type, String text) 83 | { 84 | message += type + "_" + text + "|"; 85 | } 86 | 87 | void sendMessage() 88 | { 89 | if (message != "") 90 | { 91 | Serial.println(message); 92 | message = ""; 93 | } 94 | } -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/DallasTemperature/README.md: -------------------------------------------------------------------------------- 1 | # Arduino Library for Maxim Temperature Integrated Circuits 2 | 3 | ## Usage 4 | 5 | This library supports the following devices : 6 | 7 | 8 | * DS18B20 9 | * DS18S20 - Please note there appears to be an issue with this series. 10 | * DS1822 11 | * DS1820 12 | 13 | 14 | You will need a pull-up resistor of about 5 KOhm between the 1-Wire data line 15 | and your 5V power. If you are using the DS18B20, ground pins 1 and 3. The 16 | centre pin is the data line '1-wire'. 17 | 18 | We have included a "REQUIRESNEW" and "REQUIRESALARMS" definition. If you 19 | want to slim down the code feel free to use either of these by including 20 | 21 | 22 | 23 | #define REQUIRESNEW 24 | 25 | or 26 | 27 | #define REQUIRESALARMS 28 | 29 | 30 | at the top of DallasTemperature.h 31 | 32 | 33 | ## Credits 34 | 35 | The OneWire code has been derived from 36 | http://www.arduino.cc/playground/Learning/OneWire. 37 | Miles Burton originally developed this library. 38 | Tim Newsome added support for multiple sensors on 39 | the same bus. 40 | Guil Barros [gfbarros@bappos.com] added getTempByAddress (v3.5) 41 | Rob Tillaart [rob.tillaart@gmail.com] added async modus (v3.7.0) 42 | 43 | 44 | ## Website 45 | 46 | 47 | You can find the latest version of the library at 48 | http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library 49 | 50 | # License 51 | 52 | This library is free software; you can redistribute it and/or 53 | modify it under the terms of the GNU Lesser General Public 54 | License as published by the Free Software Foundation; either 55 | version 2.1 of the License, or (at your option) any later version. 56 | 57 | This library is distributed in the hope that it will be useful, 58 | but WITHOUT ANY WARRANTY; without even the implied warranty of 59 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 60 | Lesser General Public License for more details. 61 | 62 | You should have received a copy of the GNU Lesser General Public 63 | License along with this library; if not, write to the Free Software 64 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 65 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/DallasTemperature/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For DallasTemperature 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | DallasTemperature KEYWORD1 9 | OneWire KEYWORD1 10 | AlarmHandler KEYWORD1 11 | DeviceAddress KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | setResolution KEYWORD2 18 | getResolution KEYWORD2 19 | getTempC KEYWORD2 20 | toFahrenheit KEYWORD2 21 | getTempF KEYWORD2 22 | getTempCByIndex KEYWORD2 23 | getTempFByIndex KEYWORD2 24 | setWaitForConversion KEYWORD2 25 | getWaitForConversion KEYWORD2 26 | requestTemperatures KEYWORD2 27 | requestTemperaturesByAddress KEYWORD2 28 | requestTemperaturesByIndex KEYWORD2 29 | isParasitePowerMode KEYWORD2 30 | begin KEYWORD2 31 | getDeviceCount KEYWORD2 32 | getAddress KEYWORD2 33 | validAddress KEYWORD2 34 | isConnected KEYWORD2 35 | readScratchPad KEYWORD2 36 | writeScratchPad KEYWORD2 37 | readPowerSupply KEYWORD2 38 | setHighAlarmTemp KEYWORD2 39 | setLowAlarmTemp KEYWORD2 40 | getHighAlarmTemp KEYWORD2 41 | getLowAlarmTemp KEYWORD2 42 | resetAlarmSearch KEYWORD2 43 | alarmSearch KEYWORD2 44 | hasAlarm KEYWORD2 45 | toCelsius KEYWORD2 46 | processAlarmss KEYWORD2 47 | setAlarmHandlers KEYWORD2 48 | defaultAlarmHandler KEYWORD2 49 | calculateTemperature KEYWORD2 50 | 51 | ####################################### 52 | # Constants (LITERAL1) 53 | ####################################### 54 | 55 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/DallasTemperature/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DallasTemperature", 3 | "keywords": "onewire, 1-wire, bus, sensor, temperature", 4 | "description": "Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820)", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library.git" 9 | }, 10 | "authors": 11 | [ 12 | { 13 | "name": "Miles Burton", 14 | "email": "miles@mnetcs.com", 15 | "url": "http://www.milesburton.com", 16 | "maintainer": true 17 | }, 18 | { 19 | "name": "Tim Newsome", 20 | "email": "nuisance@casualhacker.net" 21 | }, 22 | { 23 | "name": "Guil Barros", 24 | "email": "gfbarros@bappos.com" 25 | }, 26 | { 27 | "name": "Rob Tillaart", 28 | "email": "rob.tillaart@gmail.com" 29 | } 30 | ], 31 | "dependencies": 32 | { 33 | "name": "OneWire", 34 | "authors": "Paul Stoffregen", 35 | "frameworks": "arduino" 36 | }, 37 | "version": "3.7.6", 38 | "frameworks": "arduino", 39 | "platforms": "*" 40 | } 41 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/DallasTemperature/library.properties: -------------------------------------------------------------------------------- 1 | name=DallasTemperature 2 | version=3.7.6 3 | author=Miles Burton , Tim Newsome , Guil Barros , Rob Tillaart 4 | maintainer=Miles Burton 5 | sentence=Arduino Library for Dallas Temperature ICs 6 | paragraph=Supports DS18B20, DS18S20, DS1822, DS1820 7 | category=Sensors 8 | url=https://github.com/milesburton/Arduino-Temperature-Control-Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/OneWire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For OneWire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | OneWire KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | reset KEYWORD2 16 | write_bit KEYWORD2 17 | read_bit KEYWORD2 18 | write KEYWORD2 19 | write_bytes KEYWORD2 20 | read KEYWORD2 21 | read_bytes KEYWORD2 22 | select KEYWORD2 23 | skip KEYWORD2 24 | depower KEYWORD2 25 | reset_search KEYWORD2 26 | search KEYWORD2 27 | crc8 KEYWORD2 28 | crc16 KEYWORD2 29 | check_crc16 KEYWORD2 30 | 31 | ####################################### 32 | # Instances (KEYWORD2) 33 | ####################################### 34 | 35 | 36 | ####################################### 37 | # Constants (LITERAL1) 38 | ####################################### 39 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/OneWire/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OneWire", 3 | "frameworks": "Arduino", 4 | "keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton", 5 | "description": "Control 1-Wire protocol (DS18S20, DS18B20, DS2408 and etc)", 6 | "authors": 7 | [ 8 | { 9 | "name": "Paul Stoffregen", 10 | "email": "paul@pjrc.com", 11 | "url": "http://www.pjrc.com", 12 | "maintainer": true 13 | }, 14 | { 15 | "name": "Jim Studt" 16 | }, 17 | { 18 | "name": "Tom Pollard", 19 | "email": "pollard@alum.mit.edu" 20 | }, 21 | { 22 | "name": "Derek Yerger" 23 | }, 24 | { 25 | "name": "Josh Larios" 26 | }, 27 | { 28 | "name": "Robin James" 29 | }, 30 | { 31 | "name": "Glenn Trewitt" 32 | }, 33 | { 34 | "name": "Jason Dangel", 35 | "email": "dangel.jason AT gmail.com" 36 | }, 37 | { 38 | "name": "Guillermo Lovato" 39 | }, 40 | { 41 | "name": "Ken Butcher" 42 | }, 43 | { 44 | "name": "Mark Tillotson" 45 | }, 46 | { 47 | "name": "Bertrik Sikken" 48 | }, 49 | { 50 | "name": "Scott Roberts" 51 | } 52 | ], 53 | "repository": 54 | { 55 | "type": "git", 56 | "url": "https://github.com/PaulStoffregen/OneWire" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /HTM.Devices.Arduino/Sketch/libraries/OneWire/library.properties: -------------------------------------------------------------------------------- 1 | name=OneWire 2 | version=2.3.2 3 | author=Jim Studt, Tom Pollard, Robin James, Glenn Trewitt, Jason Dangel, Guillermo Lovato, Paul Stoffregen, Scott Roberts, Bertrik Sikken, Mark Tillotson, Ken Butcher, Roger Clark, Love Nystrom 4 | maintainer=Paul Stoffregen 5 | sentence=Access 1-wire temperature sensors, memory and other chips. 6 | paragraph= 7 | category=Communication 8 | url=http://www.pjrc.com/teensy/td_libs_OneWire.html 9 | architectures=* 10 | 11 | -------------------------------------------------------------------------------- /HTM.Infrastructure/Adapters/IPersistenceInitializer.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Adapters; 2 | 3 | public interface IPersistenceInitializer 4 | { 5 | Task Initialize(); 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Akka/BaseActor.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | using Akka.Event; 3 | 4 | namespace HTM.Infrastructure.Akka; 5 | 6 | public abstract class BaseActor : ReceiveActor 7 | { 8 | protected readonly ILoggingAdapter Logger; 9 | 10 | protected BaseActor() 11 | { 12 | Logger = Context.GetLogger(); 13 | } 14 | 15 | protected override void PreStart() 16 | { 17 | Logger.Info("Started"); 18 | } 19 | 20 | protected override void PostStop() 21 | { 22 | Logger.Info("Stopped"); 23 | } 24 | 25 | protected void StopSelf() => Context.Stop(Self); 26 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Akka/HtmActorBridge.cs: -------------------------------------------------------------------------------- 1 | using Akka.Actor; 2 | 3 | namespace HTM.Infrastructure.Akka; 4 | 5 | public class HtmActorBridge 6 | { 7 | public IActorRef RequestHandlerActor { get; private set; } 8 | 9 | public void AddRequestHandlerActor(IActorRef actor) 10 | { 11 | RequestHandlerActor = actor; 12 | } 13 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Communication/Protos/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package HTM.Communication.V2; 4 | 5 | enum GrpcDeviceType { 6 | ARDUINO = 0; 7 | } 8 | 9 | enum GrpcSerialPortMessageType { 10 | Undefined = 0; 11 | Event = 1; 12 | CommandResponse = 2; 13 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Communication/Protos/events.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package HTM.Communication.V2; 4 | 5 | import "common.proto"; 6 | 7 | service HTMEventsService { 8 | rpc DeviceConnectionChanged (GrpcDeviceConnectionChangedRequest) returns (GrpcDeviceConnectionChangedResponse); 9 | rpc SerialPortMessagesReceived (GrpcSerialPortMessagesReceivedRequest) returns (GrpcSerialPortMessagesReceivedResponse); 10 | } 11 | 12 | 13 | message GrpcDeviceConnectionChangedRequest { 14 | GrpcDeviceType deviceType = 1; 15 | bool isConnected = 2; 16 | } 17 | 18 | message GrpcDeviceConnectionChangedResponse { 19 | string error = 1; 20 | } 21 | 22 | message GrpcSerialPortMessagesReceivedRequest { 23 | repeated GrpcSerialPortMessage messages = 1; 24 | } 25 | 26 | message GrpcSerialPortMessagesReceivedResponse { 27 | string error = 1; 28 | } 29 | 30 | message GrpcSerialPortMessage { 31 | GrpcSerialPortMessageType Type = 1; 32 | string Text = 2; 33 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Communication/Protos/methods.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package HTM.Communication.V2; 4 | 5 | import "google/protobuf/timestamp.proto"; 6 | import "common.proto"; 7 | 8 | service HTMMethodsService { 9 | rpc GetMessageByCommand (GrpcGetMessageByCommandRequest) returns (GrpcGetMessageByCommandResponse); 10 | rpc GetDeviceConnectionState (GrpcGetDeviceConnectionStateRequest) returns (GrpcGetDeviceConnectionStateResponse); 11 | rpc GrpcGetTemperatureMeasurements (GrpcGetTemperatureMeasurementsRequest) returns (GrpcGetTemperatureMeasurementsResponse); 12 | } 13 | 14 | message GrpcGetMessageByCommandRequest { 15 | string command = 1; 16 | } 17 | 18 | message GrpcGetMessageByCommandResponse { 19 | string message = 1; 20 | } 21 | 22 | message GrpcGetDeviceConnectionStateRequest { 23 | GrpcDeviceType deviceType = 1; 24 | } 25 | 26 | message GrpcGetDeviceConnectionStateResponse { 27 | bool isConnected = 1; 28 | } 29 | 30 | message GrpcGetTemperatureMeasurementsRequest { 31 | google.protobuf.Timestamp from = 1; 32 | google.protobuf.Timestamp to = 2; 33 | } 34 | 35 | message GrpcGetTemperatureMeasurementsResponse { 36 | repeated GrpcTemperatureMeasurement GrpcTemperatureMeasurements = 1; 37 | } 38 | 39 | message GrpcTemperatureMeasurement { 40 | int64 id = 1; 41 | google.protobuf.Timestamp measurementDate = 2; 42 | float temperature = 3; 43 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Constants/Application.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Constants; 2 | 3 | public static class Application 4 | { 5 | public const string AppSettingsFile = "appsettings.json"; 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Adapters/IDevice.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Devices.Adapters; 2 | 3 | public interface IDevice : IDisposable 4 | { 5 | Task Initialize(); 6 | event EventHandler ConnectionChanged; 7 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Adapters/ISerialPortDevice.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Models; 2 | 3 | namespace HTM.Infrastructure.Devices.Adapters; 4 | 5 | public interface ISerialPortDevice : IDevice 6 | { 7 | void SendMessage(string message); 8 | event EventHandler OnMessagesReceived; 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Enums/DeviceType.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Devices.Enums; 2 | 3 | public enum DeviceType 4 | { 5 | Arduino 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Events/DeviceConnectionChangedEvent.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Devices.Enums; 2 | using HTM.Infrastructure.MessagesBase; 3 | 4 | namespace HTM.Infrastructure.Devices.Messages.Events; 5 | 6 | public class DeviceConnectionChangedEvent : EventBase 7 | { 8 | public DeviceType DeviceType { get; } 9 | public bool IsConnected { get; } 10 | 11 | public DeviceConnectionChangedEvent(DeviceType deviceType, bool isConnected) 12 | { 13 | DeviceType = deviceType; 14 | IsConnected = isConnected; 15 | } 16 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Events/SerialPortMessageReceivedEvent.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Infrastructure.Devices.Messages.Events; 5 | 6 | public class SerialPortMessageReceivedEvent : EventBase 7 | { 8 | public SerialPortMessage[] Messages { get; } 9 | 10 | public SerialPortMessageReceivedEvent(SerialPortMessage[] messages) 11 | { 12 | Messages = messages; 13 | } 14 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/InitializationResultMessage.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Devices.Messages; 2 | 3 | public class InitializationResultMessage 4 | { 5 | public static InitializationResultMessage WithSuccess => new(); 6 | public static InitializationResultMessage WithError(Exception exception) => new(exception); 7 | 8 | public bool IsError => Exception != null; 9 | public Exception Exception { get; } 10 | 11 | private InitializationResultMessage(Exception exception) 12 | { 13 | Exception = exception; 14 | } 15 | 16 | private InitializationResultMessage() 17 | { 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/GetDeviceConnectionStateRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Devices.Enums; 2 | using HTM.Infrastructure.MessagesBase; 3 | 4 | namespace HTM.Infrastructure.Devices.Messages.Requests; 5 | 6 | public class GetDeviceConnectionStateRequest : HtmRequest 7 | { 8 | public DeviceType DeviceType { get; } 9 | 10 | public GetDeviceConnectionStateRequest(DeviceType deviceType) 11 | { 12 | DeviceType = deviceType; 13 | } 14 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/GetDeviceConnectionStateResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Devices.Messages.Requests; 4 | 5 | public class GetDeviceConnectionStateResponse : HtmResponse 6 | { 7 | public bool IsConnected { get; } 8 | 9 | public GetDeviceConnectionStateResponse(Guid requestId, bool isConnected) : base(requestId) 10 | { 11 | IsConnected = isConnected; 12 | } 13 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/GetMessageByCommandRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Infrastructure.Devices.Messages.Requests; 5 | 6 | public class GetMessageByCommandRequest : HtmRequest 7 | { 8 | public SerialPortCommand Command { get; } 9 | 10 | public GetMessageByCommandRequest(SerialPortCommand command) 11 | { 12 | Command = command; 13 | } 14 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/GetMessageByCommandResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Devices.Messages.Requests; 4 | 5 | public class GetMessageByCommandResponse : HtmResponse 6 | { 7 | public string Message { get; } 8 | public Exception Exception { get; } 9 | public bool IsError => Exception != null; 10 | 11 | public GetMessageByCommandResponse(Guid requestId, string message) : base(requestId) 12 | { 13 | Message = message; 14 | } 15 | 16 | public GetMessageByCommandResponse(Guid requestId, Exception exception) : base(requestId) 17 | { 18 | Exception = exception; 19 | } 20 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/SendMessageRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Devices.Messages.Requests; 4 | 5 | public class SendMessageRequest : HtmRequest 6 | { 7 | public string Message { get; } 8 | 9 | public SendMessageRequest(string message) 10 | { 11 | Message = message; 12 | } 13 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Devices/Messages/Requests/SendMessageResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Devices.Messages.Requests; 4 | 5 | public class SendMessageResponse : HtmResponse 6 | { 7 | public Exception Exception { get; } 8 | public bool IsError => Exception != null; 9 | 10 | public SendMessageResponse(Guid requestId) : base(requestId) 11 | { } 12 | 13 | public SendMessageResponse(Guid requestId, Exception exception) : base(requestId) 14 | { 15 | Exception = exception; 16 | } 17 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Exceptions/DeviceDisconnectedException.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Exceptions; 2 | 3 | public class DeviceDisconnectedException : Exception 4 | { 5 | private new const string Message = "Device is disconnected."; 6 | 7 | public DeviceDisconnectedException() : base(Message) 8 | { } 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Exceptions/InvalidTemperatureException.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Exceptions; 2 | 3 | public class InvalidTemperatureException : Exception 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/HTM.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /HTM.Infrastructure/Logging/SerilogHelper.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | using Serilog.Events; 3 | 4 | namespace HTM.Infrastructure.Logging; 5 | 6 | public static class SerilogHelper 7 | { 8 | public static void AddSerilog() 9 | { 10 | Log.Logger = new LoggerConfiguration() 11 | .MinimumLevel.Information() 12 | .MinimumLevel.Override("Microsoft", LogEventLevel.Information) 13 | .Enrich.FromLogContext() 14 | .WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u4}][{LogSource}] {Message:lj}{NewLine}{Exception}") 15 | .WriteTo.File( 16 | "logs//LOG_.log", 17 | outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u4}][{LogSource}] {Message:lj}{NewLine}{Exception}", 18 | restrictedToMinimumLevel: LogEventLevel.Information, 19 | rollingInterval: RollingInterval.Day) 20 | .CreateBootstrapLogger(); 21 | } 22 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/AddTemperatureMeasurementRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 5 | 6 | public class AddTemperatureMeasurementRequest : HtmRequest 7 | { 8 | public TemperatureMeasurement TemperatureMeasurement { get; } 9 | 10 | public AddTemperatureMeasurementRequest(TemperatureMeasurement temperatureMeasurement) 11 | { 12 | TemperatureMeasurement = temperatureMeasurement; 13 | } 14 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/AddTemperatureMeasurementResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 4 | 5 | public class AddTemperatureMeasurementResponse : HtmResponse 6 | { 7 | public static AddTemperatureMeasurementResponse WithSuccess(Guid requestId) => new(requestId); 8 | public static AddTemperatureMeasurementResponse WithFailure(Guid requestId, Exception exception) => new(requestId, exception); 9 | 10 | public Exception Exception { get; } 11 | public bool IsError => Exception != null; 12 | 13 | public AddTemperatureMeasurementResponse(Guid requestId, Exception exception = null) : base(requestId) 14 | { 15 | Exception = exception; 16 | } 17 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/GetLastTemperatureMeasurementRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 4 | 5 | public class GetLastTemperatureMeasurementRequest : HtmRequest 6 | { 7 | 8 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/GetLastTemperatureMeasurementResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 5 | 6 | public class GetLastTemperatureMeasurementResponse : HtmResponse 7 | { 8 | public static GetLastTemperatureMeasurementResponse WithSuccess(Guid requestId, TemperatureMeasurement measurement) => new(requestId, measurement); 9 | public static GetLastTemperatureMeasurementResponse WithFailure(Guid requestId, Exception exception) => new(requestId, exception); 10 | 11 | public TemperatureMeasurement TemperatureMeasurement { get; } 12 | public Exception Exception { get; } 13 | 14 | public bool IsError => Exception != null; 15 | 16 | public GetLastTemperatureMeasurementResponse(Guid requestId, TemperatureMeasurement measurement) : base(requestId) 17 | { 18 | TemperatureMeasurement = measurement; 19 | } 20 | 21 | public GetLastTemperatureMeasurementResponse(Guid requestId, Exception exception) : base(requestId) 22 | { 23 | Exception = exception; 24 | } 25 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/GetTemperatureMeasurementsByDateRangeRequest.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | 3 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 4 | 5 | public class GetTemperatureMeasurementsByDateRangeRequest : HtmRequest 6 | { 7 | public DateTime From { get; } 8 | public DateTime To { get; } 9 | 10 | public GetTemperatureMeasurementsByDateRangeRequest(DateTime from, DateTime to) 11 | { 12 | From = from; 13 | To = to; 14 | } 15 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Measurements/Messages/Requests/GetTemperatureMeasurementsByDateRangeResponse.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.MessagesBase; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Infrastructure.Measurements.Messages.Requests; 5 | 6 | public class GetTemperatureMeasurementsByDateRangeResponse : HtmResponse 7 | { 8 | public static GetTemperatureMeasurementsByDateRangeResponse WithSuccess(Guid requestId, TemperatureMeasurement[] measurements) => new(requestId, measurements); 9 | public static GetTemperatureMeasurementsByDateRangeResponse WithFailure(Guid requestId, Exception exception) => new(requestId, exception); 10 | 11 | public TemperatureMeasurement[] TemperatureMeasurements { get; } 12 | public Exception Exception { get; } = null!; 13 | public bool IsError => Exception != null; 14 | 15 | public GetTemperatureMeasurementsByDateRangeResponse(Guid requestId, TemperatureMeasurement[] measurements) : base(requestId) 16 | { 17 | TemperatureMeasurements = measurements; 18 | } 19 | 20 | public GetTemperatureMeasurementsByDateRangeResponse(Guid requestId, Exception exception) : base(requestId) 21 | { 22 | Exception = exception; 23 | } 24 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Messages/Events/TemperatureMeasurementActorInitializedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Messages.Events; 2 | 3 | public class TemperatureMeasurementActorInitializedEvent 4 | { 5 | public static TemperatureMeasurementActorInitializedEvent Instance => new(); 6 | 7 | private TemperatureMeasurementActorInitializedEvent() 8 | { } 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Messages/Events/TimeoutEvent.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Messages.Events; 2 | 3 | public class TimeoutEvent 4 | { 5 | public static TimeoutEvent Instance => new(); 6 | 7 | private TimeoutEvent() 8 | { } 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Messages/Events/TimerElapsedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Messages.Events; 2 | 3 | public class TimerElapsedEvent 4 | { 5 | public static TimerElapsedEvent Instance => new(); 6 | 7 | private TimerElapsedEvent() 8 | { } 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/MessagesBase/EventBase.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.MessagesBase; 2 | 3 | public abstract class EventBase 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/MessagesBase/HtmRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.MessagesBase; 2 | 3 | public abstract class HtmRequest 4 | { 5 | public Guid RequestId { get; } = Guid.NewGuid(); 6 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/MessagesBase/HtmResponse.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.MessagesBase; 2 | 3 | public abstract class HtmResponse 4 | { 5 | public Guid RequestId { get; } 6 | 7 | public HtmResponse(Guid requestId) 8 | { 9 | RequestId = requestId; 10 | } 11 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Models/SerialPortCommand.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Models; 2 | 3 | public enum SerialPortCommand 4 | { 5 | GetTemperature, 6 | TurnLedOn, 7 | TurnLedOff, 8 | GetLedState 9 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Models/SerialPortMessage.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Models; 2 | 3 | public class SerialPortMessage 4 | { 5 | public SerialPortMessageType Type { get; } 6 | public string Text { get; } 7 | 8 | public SerialPortMessage(SerialPortMessageType type, string text) 9 | { 10 | Type = type; 11 | Text = text; 12 | } 13 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Models/SerialPortMessageType.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Models; 2 | 3 | public enum SerialPortMessageType 4 | { 5 | Undefined, 6 | Event, 7 | CommandResponse, 8 | } -------------------------------------------------------------------------------- /HTM.Infrastructure/Models/TemperatureMeasurement.cs: -------------------------------------------------------------------------------- 1 | namespace HTM.Infrastructure.Models; 2 | 3 | public class TemperatureMeasurement 4 | { 5 | public long Id { get; set; } 6 | public DateTime MeasurementDate { get; set; } 7 | public float Temperature { get; set; } 8 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Extensions/DeviceTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Devices.Enums; 3 | 4 | namespace HTM.Web.Communication.Extensions; 5 | 6 | public static class DeviceTypeExtensions 7 | { 8 | public static DeviceType ToDeviceType(this GrpcDeviceType deviceType) 9 | { 10 | return deviceType switch 11 | { 12 | GrpcDeviceType.Arduino => DeviceType.Arduino, 13 | 14 | _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) 15 | }; 16 | } 17 | 18 | public static GrpcDeviceType ToDeviceType(this DeviceType deviceType) 19 | { 20 | return deviceType switch 21 | { 22 | DeviceType.Arduino => GrpcDeviceType.Arduino, 23 | 24 | _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) 25 | }; 26 | } 27 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Extensions/SerialPortMessageExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Extensions; 5 | 6 | public static class SerialPortMessageExtensions 7 | { 8 | public static SerialPortMessage ToSerialPortMessage(this GrpcSerialPortMessage message) 9 | { 10 | return new SerialPortMessage(message.Type.ToSerialPortMessageType(), message.Text); 11 | } 12 | 13 | public static GrpcSerialPortMessage ToSerialPortMessage(this SerialPortMessage message) 14 | { 15 | return new GrpcSerialPortMessage 16 | { 17 | Type = message.Type.ToSerialPortMessageType(), 18 | Text = message.Text 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Extensions/SerialPortMessageTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Extensions; 5 | 6 | public static class SerialPortMessageTypeExtensions 7 | { 8 | public static SerialPortMessageType ToSerialPortMessageType(this GrpcSerialPortMessageType messageType) 9 | { 10 | return messageType switch 11 | { 12 | GrpcSerialPortMessageType.Undefined => SerialPortMessageType.Undefined, 13 | GrpcSerialPortMessageType.Event => SerialPortMessageType.Event, 14 | GrpcSerialPortMessageType.CommandResponse => SerialPortMessageType.CommandResponse, 15 | 16 | _ => throw new ArgumentOutOfRangeException(nameof(messageType), messageType, null) 17 | }; 18 | } 19 | 20 | public static GrpcSerialPortMessageType ToSerialPortMessageType(this SerialPortMessageType messageType) 21 | { 22 | return messageType switch 23 | { 24 | SerialPortMessageType.Undefined => GrpcSerialPortMessageType.Undefined, 25 | SerialPortMessageType.Event => GrpcSerialPortMessageType.Event, 26 | SerialPortMessageType.CommandResponse => GrpcSerialPortMessageType.CommandResponse, 27 | 28 | _ => throw new ArgumentOutOfRangeException(nameof(messageType), messageType, null) 29 | }; 30 | } 31 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Extensions/TemperaturesMeasurementExtensions.cs: -------------------------------------------------------------------------------- 1 | using HTM.Communication.V2; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Extensions; 5 | 6 | public static class TemperaturesMeasurementExtensions 7 | { 8 | public static TemperatureMeasurement ToTemperaturesMeasurement(this GrpcTemperatureMeasurement temperatureMeasurement) 9 | { 10 | return new TemperatureMeasurement 11 | { 12 | Id = temperatureMeasurement.Id, 13 | Temperature = temperatureMeasurement.Temperature, 14 | MeasurementDate = temperatureMeasurement.MeasurementDate.ToDateTime() 15 | }; 16 | } 17 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/HTM.Web.Communication.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Protos\common.proto 28 | 29 | 30 | 31 | Protos\methods.proto 32 | 33 | 34 | 35 | Protos\events.proto 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/GrpcHostedService.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Microsoft.Extensions.Hosting; 3 | using Serilog; 4 | 5 | namespace HTM.Web.Communication.Services; 6 | 7 | public class GrpcHostedService : IHostedService 8 | { 9 | private readonly Server _server; 10 | 11 | public GrpcHostedService(Server server) 12 | { 13 | _server = server; 14 | } 15 | 16 | public Task StartAsync(CancellationToken cancellationToken) 17 | { 18 | _server.Start(); 19 | 20 | Log.Information("{GrpcHostedService} | Server Started", nameof(GrpcHostedService)); 21 | 22 | return Task.CompletedTask; 23 | } 24 | 25 | public async Task StopAsync(CancellationToken cancellationToken) 26 | { 27 | await _server.ShutdownAsync(); 28 | 29 | Log.Information("{GrpcHostedService} | Server Stopped", nameof(GrpcHostedService)); 30 | } 31 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/HtmEventsServer.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using HTM.Communication.V2; 3 | using HTM.Web.Communication.Extensions; 4 | using Newtonsoft.Json; 5 | using Serilog; 6 | 7 | namespace HTM.Web.Communication.Services; 8 | 9 | public class HtmEventsServer : HTMEventsService.HTMEventsServiceBase 10 | { 11 | private readonly IHtmEventsInvoker _htmEventsInvoker; 12 | 13 | public HtmEventsServer(IHtmEventsInvoker htmEventsInvoker) 14 | { 15 | _htmEventsInvoker = htmEventsInvoker; 16 | } 17 | 18 | public override Task DeviceConnectionChanged(GrpcDeviceConnectionChangedRequest request, ServerCallContext context) 19 | { 20 | Log.Information("{HtmEventsServer} - {DeviceConnectionChanged} | Request={Request}", 21 | nameof(HtmEventsServer), nameof(DeviceConnectionChanged), JsonConvert.SerializeObject(request)); 22 | 23 | _htmEventsInvoker.InvokeDeviceConnectionChangedEvent(request.DeviceType.ToDeviceType(), request.IsConnected); 24 | 25 | return Task.FromResult(new GrpcDeviceConnectionChangedResponse()); 26 | } 27 | 28 | public override Task SerialPortMessagesReceived(GrpcSerialPortMessagesReceivedRequest request, ServerCallContext context) 29 | { 30 | Log.Information("{HtmEventsServer} - {SerialPortMessagesReceived} | Request={Request}", 31 | nameof(HtmEventsServer), nameof(SerialPortMessagesReceived), JsonConvert.SerializeObject(request)); 32 | 33 | var messages = request.Messages.Select(x => x.ToSerialPortMessage()).ToArray(); 34 | _htmEventsInvoker.InvokeSerialPortMessagesReceivedEvent(messages); 35 | 36 | return Task.FromResult(new GrpcSerialPortMessagesReceivedResponse()); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/HtmEventsService.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Devices.Enums; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Services; 5 | 6 | public class HtmEventsService : IHtmEventsService, IHtmEventsInvoker 7 | { 8 | public event EventHandler<(DeviceType deviceType, bool isConnected)> OnDeviceConnectionChangedEvent; 9 | public event EventHandler OnSerialPortMessagesReceivedEvent; 10 | 11 | public void InvokeDeviceConnectionChangedEvent(DeviceType deviceType, bool isConnected) 12 | { 13 | OnDeviceConnectionChangedEvent?.Invoke(this, new (deviceType, isConnected)); 14 | } 15 | 16 | public void InvokeSerialPortMessagesReceivedEvent(SerialPortMessage[] messages) 17 | { 18 | OnSerialPortMessagesReceivedEvent?.Invoke(this, messages); 19 | } 20 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/HtmMethodsClient.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf.WellKnownTypes; 2 | using Grpc.Net.Client; 3 | using HTM.Communication.V2; 4 | using HTM.Infrastructure; 5 | using HTM.Infrastructure.Devices.Enums; 6 | using HTM.Infrastructure.Models; 7 | using HTM.Web.Communication.Extensions; 8 | using Serilog; 9 | 10 | namespace HTM.Web.Communication.Services; 11 | 12 | public class HtmMethodsClient 13 | { 14 | private readonly GrpcChannel _grpcChannel; 15 | 16 | private DateTime DeadLine => DateTime.UtcNow.AddSeconds(5); 17 | 18 | public HtmMethodsClient() 19 | { 20 | _grpcChannel = GrpcChannel.ForAddress("http://localhost:2010"); 21 | } 22 | 23 | public async Task GetDeviceConnectionStatus(DeviceType deviceType) 24 | { 25 | try 26 | { 27 | var client = new HTMMethodsService.HTMMethodsServiceClient(_grpcChannel); 28 | var response = await client.GetDeviceConnectionStateAsync(new GrpcGetDeviceConnectionStateRequest 29 | { 30 | DeviceType = deviceType.ToDeviceType() 31 | }, deadline: DeadLine); 32 | 33 | return response.IsConnected; 34 | } 35 | catch (Exception ex) 36 | { 37 | Log.Error(ex, nameof(GetDeviceConnectionStatus)); 38 | return false; 39 | } 40 | } 41 | 42 | public async Task GetMessageByCommand(SerialPortCommand command) 43 | { 44 | var client = new HTMMethodsService.HTMMethodsServiceClient(_grpcChannel); 45 | var response = await client.GetMessageByCommandAsync(new GrpcGetMessageByCommandRequest 46 | { 47 | Command = command.ToString() 48 | }, deadline: DeadLine); 49 | 50 | return response.Message; 51 | } 52 | 53 | public async Task GetTemperaturesMeasurements(DateTime from, DateTime to) 54 | { 55 | try 56 | { 57 | var client = new HTMMethodsService.HTMMethodsServiceClient(_grpcChannel); 58 | var response = await client.GrpcGetTemperatureMeasurementsAsync(new GrpcGetTemperatureMeasurementsRequest 59 | { 60 | From = Timestamp.FromDateTime(DateTime.SpecifyKind(from, DateTimeKind.Utc)), 61 | To = Timestamp.FromDateTime(DateTime.SpecifyKind(to, DateTimeKind.Utc)) 62 | }, deadline: DeadLine); 63 | 64 | return response.GrpcTemperatureMeasurements.Select(x => x.ToTemperaturesMeasurement()).ToArray(); 65 | } 66 | catch (Exception ex) 67 | { 68 | Log.Error(ex, nameof(GetDeviceConnectionStatus)); 69 | return null; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/IHtmEventsInvoker.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Devices.Enums; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Services; 5 | 6 | public interface IHtmEventsInvoker 7 | { 8 | void InvokeDeviceConnectionChangedEvent(DeviceType deviceType, bool isConnected); 9 | void InvokeSerialPortMessagesReceivedEvent(SerialPortMessage[] messages); 10 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/Services/IHtmEventsService.cs: -------------------------------------------------------------------------------- 1 | using HTM.Infrastructure.Devices.Enums; 2 | using HTM.Infrastructure.Models; 3 | 4 | namespace HTM.Web.Communication.Services; 5 | 6 | public interface IHtmEventsService 7 | { 8 | event EventHandler<(DeviceType deviceType, bool isConnected)> OnDeviceConnectionChangedEvent; 9 | event EventHandler OnSerialPortMessagesReceivedEvent; 10 | } -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The Fuchsia Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | import("//third_party/protobuf/proto_library.gni") 6 | 7 | proto_library("annotations_and_http") { 8 | sources = [ 9 | "annotations.proto", 10 | "http.proto", 11 | ] 12 | proto_in_dir = "//third_party/googleapis" 13 | import_dirs = [ "//third_party/googleapis" ] 14 | generate_python = false 15 | cc_generator_options = "lite" 16 | import_protobuf_full = true 17 | extra_configs = [ "//third_party/googleapis:googleapis_config" ] 18 | } 19 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/README.md: -------------------------------------------------------------------------------- 1 | This folder contains the schema of the configuration model for the API services 2 | platform. 3 | 4 | **Note**: Protos under this directory are in Alpha status, and therefore are 5 | subject to breaking changes. 6 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/backend.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "BackendProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // `Backend` defines the backend configuration for a service. 27 | message Backend { 28 | // A list of API backend rules that apply to individual API methods. 29 | // 30 | // **NOTE:** All service configuration rules follow "last one wins" order. 31 | repeated BackendRule rules = 1; 32 | } 33 | 34 | // A backend rule provides configuration for an individual API element. 35 | message BackendRule { 36 | // Selects the methods to which this rule applies. 37 | // 38 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 39 | string selector = 1; 40 | 41 | // The address of the API backend. 42 | string address = 2; 43 | 44 | // The number of seconds to wait for a response from a request. The 45 | // default depends on the deployment context. 46 | double deadline = 3; 47 | } 48 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/billing.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/metric.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "BillingProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | 29 | // Billing related configuration of the service. 30 | // 31 | // The following example shows how to configure monitored resources and metrics 32 | // for billing: 33 | // monitored_resources: 34 | // - type: library.googleapis.com/branch 35 | // labels: 36 | // - key: /city 37 | // description: The city where the library branch is located in. 38 | // - key: /name 39 | // description: The name of the branch. 40 | // metrics: 41 | // - name: library.googleapis.com/book/borrowed_count 42 | // metric_kind: DELTA 43 | // value_type: INT64 44 | // billing: 45 | // consumer_destinations: 46 | // - monitored_resource: library.googleapis.com/branch 47 | // metrics: 48 | // - library.googleapis.com/book/borrowed_count 49 | message Billing { 50 | // Configuration of a specific billing destination (Currently only support 51 | // bill against consumer project). 52 | message BillingDestination { 53 | // The monitored resource type. The type must be defined in 54 | // [Service.monitored_resources][google.api.Service.monitored_resources] section. 55 | string monitored_resource = 1; 56 | 57 | // Names of the metrics to report to this billing destination. 58 | // Each name must be defined in [Service.metrics][google.api.Service.metrics] section. 59 | repeated string metrics = 2; 60 | } 61 | 62 | // Billing configurations for sending metrics to the consumer project. 63 | // There can be multiple consumer destinations per service, each one must have 64 | // a different monitored resource type. A metric can be used in at most 65 | // one consumer destination. 66 | repeated BillingDestination consumer_destinations = 8; 67 | } 68 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/config_change.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/configchange;configchange"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ConfigChangeProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Output generated from semantically comparing two versions of a service 27 | // configuration. 28 | // 29 | // Includes detailed information about a field that have changed with 30 | // applicable advice about potential consequences for the change, such as 31 | // backwards-incompatibility. 32 | message ConfigChange { 33 | // Object hierarchy path to the change, with levels separated by a '.' 34 | // character. For repeated fields, an applicable unique identifier field is 35 | // used for the index (usually selector, name, or id). For maps, the term 36 | // 'key' is used. If the field has no unique identifier, the numeric index 37 | // is used. 38 | // Examples: 39 | // - visibility.rules[selector=="google.LibraryService.CreateBook"].restriction 40 | // - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value 41 | // - logging.producer_destinations[0] 42 | string element = 1; 43 | 44 | // Value of the changed object in the old Service configuration, 45 | // in JSON format. This field will not be populated if ChangeType == ADDED. 46 | string old_value = 2; 47 | 48 | // Value of the changed object in the new Service configuration, 49 | // in JSON format. This field will not be populated if ChangeType == REMOVED. 50 | string new_value = 3; 51 | 52 | // The type for this change, either ADDED, REMOVED, or MODIFIED. 53 | ChangeType change_type = 4; 54 | 55 | // Collection of advice provided for this change, useful for determining the 56 | // possible impact of this change. 57 | repeated Advice advices = 5; 58 | } 59 | 60 | // Generated advice about this change, used for providing more 61 | // information about how a change will affect the existing service. 62 | message Advice { 63 | // Useful description for why this advice was applied and what actions should 64 | // be taken to mitigate any implied risks. 65 | string description = 2; 66 | } 67 | 68 | // Classifies set of possible modifications to an object in the service 69 | // configuration. 70 | enum ChangeType { 71 | // No value was provided. 72 | CHANGE_TYPE_UNSPECIFIED = 0; 73 | 74 | // The changed object exists in the 'new' service configuration, but not 75 | // in the 'old' service configuration. 76 | ADDED = 1; 77 | 78 | // The changed object exists in the 'old' service configuration, but not 79 | // in the 'new' service configuration. 80 | REMOVED = 2; 81 | 82 | // The changed object exists in both service configurations, but its value 83 | // is different. 84 | MODIFIED = 3; 85 | } 86 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/consumer.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ConsumerProto"; 22 | option java_package = "com.google.api"; 23 | 24 | 25 | // A descriptor for defining project properties for a service. One service may 26 | // have many consumer projects, and the service may want to behave differently 27 | // depending on some properties on the project. For example, a project may be 28 | // associated with a school, or a business, or a government agency, a business 29 | // type property on the project may affect how a service responds to the client. 30 | // This descriptor defines which properties are allowed to be set on a project. 31 | // 32 | // Example: 33 | // 34 | // project_properties: 35 | // properties: 36 | // - name: NO_WATERMARK 37 | // type: BOOL 38 | // description: Allows usage of the API without watermarks. 39 | // - name: EXTENDED_TILE_CACHE_PERIOD 40 | // type: INT64 41 | message ProjectProperties { 42 | // List of per consumer project-specific properties. 43 | repeated Property properties = 1; 44 | } 45 | 46 | // Defines project properties. 47 | // 48 | // API services can define properties that can be assigned to consumer projects 49 | // so that backends can perform response customization without having to make 50 | // additional calls or maintain additional storage. For example, Maps API 51 | // defines properties that controls map tile cache period, or whether to embed a 52 | // watermark in a result. 53 | // 54 | // These values can be set via API producer console. Only API providers can 55 | // define and set these properties. 56 | message Property { 57 | // Supported data type of the property values 58 | enum PropertyType { 59 | // The type is unspecified, and will result in an error. 60 | UNSPECIFIED = 0; 61 | 62 | // The type is `int64`. 63 | INT64 = 1; 64 | 65 | // The type is `bool`. 66 | BOOL = 2; 67 | 68 | // The type is `string`. 69 | STRING = 3; 70 | 71 | // The type is 'double'. 72 | DOUBLE = 4; 73 | } 74 | 75 | // The name of the property (a.k.a key). 76 | string name = 1; 77 | 78 | // The type of this property. 79 | PropertyType type = 2; 80 | 81 | // The description of the property 82 | string description = 3; 83 | } 84 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/context.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ContextProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // `Context` defines which contexts an API requests. 27 | // 28 | // Example: 29 | // 30 | // context: 31 | // rules: 32 | // - selector: "*" 33 | // requested: 34 | // - google.rpc.context.ProjectContext 35 | // - google.rpc.context.OriginContext 36 | // 37 | // The above specifies that all methods in the API request 38 | // `google.rpc.context.ProjectContext` and 39 | // `google.rpc.context.OriginContext`. 40 | // 41 | // Available context types are defined in package 42 | // `google.rpc.context`. 43 | message Context { 44 | // A list of RPC context rules that apply to individual API methods. 45 | // 46 | // **NOTE:** All service configuration rules follow "last one wins" order. 47 | repeated ContextRule rules = 1; 48 | } 49 | 50 | // A context rule provides information about the context for an individual API 51 | // element. 52 | message ContextRule { 53 | // Selects the methods to which this rule applies. 54 | // 55 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 56 | string selector = 1; 57 | 58 | // A list of full type names of requested contexts. 59 | repeated string requested = 2; 60 | 61 | // A list of full type names of provided contexts. 62 | repeated string provided = 3; 63 | } 64 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/control.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "ControlProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Selects and configures the service controller used by the service. The 27 | // service controller handles features like abuse, quota, billing, logging, 28 | // monitoring, etc. 29 | message Control { 30 | // The service control environment to use. If empty, no control plane 31 | // feature (like quota and billing) will be enabled. 32 | string environment = 1; 33 | } 34 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/endpoint.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "EndpointProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // `Endpoint` describes a network endpoint that serves a set of APIs. 29 | // A service may expose any number of endpoints, and all endpoints share the 30 | // same service configuration, such as quota configuration and monitoring 31 | // configuration. 32 | // 33 | // Example service configuration: 34 | // 35 | // name: library-example.googleapis.com 36 | // endpoints: 37 | // # Below entry makes 'google.example.library.v1.Library' 38 | // # API be served from endpoint address library-example.googleapis.com. 39 | // # It also allows HTTP OPTIONS calls to be passed to the backend, for 40 | // # it to decide whether the subsequent cross-origin request is 41 | // # allowed to proceed. 42 | // - name: library-example.googleapis.com 43 | // allow_cors: true 44 | message Endpoint { 45 | // The canonical name of this endpoint. 46 | string name = 1; 47 | 48 | // DEPRECATED: This field is no longer supported. Instead of using aliases, 49 | // please specify multiple [google.api.Endpoint][google.api.Endpoint] for each of the intented 50 | // alias. 51 | // 52 | // Additional names that this endpoint will be hosted on. 53 | repeated string aliases = 2; 54 | 55 | // The list of APIs served by this endpoint. 56 | repeated string apis = 3; 57 | 58 | // The list of features enabled on this endpoint. 59 | repeated string features = 4; 60 | 61 | // The specification of an Internet routable address of API frontend that will 62 | // handle requests to this [API Endpoint](https://cloud.google.com/apis/design/glossary). 63 | // It should be either a valid IPv4 address or a fully-qualified domain name. 64 | // For example, "8.8.8.8" or "myservice.appspot.com". 65 | string target = 101; 66 | 67 | // Allowing 68 | // [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka 69 | // cross-domain traffic, would allow the backends served from this endpoint to 70 | // receive and respond to HTTP OPTIONS requests. The response will be used by 71 | // the browser to determine whether the subsequent cross-origin request is 72 | // allowed to proceed. 73 | bool allow_cors = 5; 74 | } 75 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/experimental/authorization_config.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api;api"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "AuthorizationConfigProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Configuration of authorization. 27 | // 28 | // This section determines the authorization provider, if unspecified, then no 29 | // authorization check will be done. 30 | // 31 | // Example: 32 | // 33 | // experimental: 34 | // authorization: 35 | // provider: firebaserules.googleapis.com 36 | message AuthorizationConfig { 37 | // The name of the authorization provider, such as 38 | // firebaserules.googleapis.com. 39 | string provider = 1; 40 | } 41 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/experimental/experimental.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/experimental/authorization_config.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api;api"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "ExperimentalProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | 29 | // Experimental service configuration. These configuration options can 30 | // only be used by whitelisted users. 31 | message Experimental { 32 | // Authorization configuration. 33 | AuthorizationConfig authorization = 8; 34 | } 35 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/httpbody.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "HttpBodyProto"; 22 | option java_package = "com.google.api"; 23 | option objc_class_prefix = "GAPI"; 24 | 25 | 26 | // Message that represents an arbitrary HTTP body. It should only be used for 27 | // payload formats that can't be represented as JSON, such as raw binary or 28 | // an HTML page. 29 | // 30 | // 31 | // This message can be used both in streaming and non-streaming API methods in 32 | // the request as well as the response. 33 | // 34 | // It can be used as a top-level request field, which is convenient if one 35 | // wants to extract parameters from either the URL or HTTP template into the 36 | // request fields and also want access to the raw HTTP body. 37 | // 38 | // Example: 39 | // 40 | // message GetResourceRequest { 41 | // // A unique request id. 42 | // string request_id = 1; 43 | // 44 | // // The raw HTTP body is bound to this field. 45 | // google.api.HttpBody http_body = 2; 46 | // } 47 | // 48 | // service ResourceService { 49 | // rpc GetResource(GetResourceRequest) returns (google.api.HttpBody); 50 | // rpc UpdateResource(google.api.HttpBody) returns (google.protobuf.Empty); 51 | // } 52 | // 53 | // Example with streaming methods: 54 | // 55 | // service CaldavService { 56 | // rpc GetCalendar(stream google.api.HttpBody) 57 | // returns (stream google.api.HttpBody); 58 | // rpc UpdateCalendar(stream google.api.HttpBody) 59 | // returns (stream google.api.HttpBody); 60 | // } 61 | // 62 | // Use of this type only changes how the request and response bodies are 63 | // handled, all other features will continue to work unchanged. 64 | message HttpBody { 65 | // The HTTP Content-Type string representing the content type of the body. 66 | string content_type = 1; 67 | 68 | // HTTP body binary data. 69 | bytes data = 2; 70 | } 71 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/label.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | option cc_enable_arenas = true; 20 | option go_package = "google.golang.org/genproto/googleapis/api/label;label"; 21 | option java_multiple_files = true; 22 | option java_outer_classname = "LabelProto"; 23 | option java_package = "com.google.api"; 24 | option objc_class_prefix = "GAPI"; 25 | 26 | 27 | // A description of a label. 28 | message LabelDescriptor { 29 | // Value types that can be used as label values. 30 | enum ValueType { 31 | // A variable-length string. This is the default. 32 | STRING = 0; 33 | 34 | // Boolean; true or false. 35 | BOOL = 1; 36 | 37 | // A 64-bit signed integer. 38 | INT64 = 2; 39 | } 40 | 41 | // The label key. 42 | string key = 1; 43 | 44 | // The type of data that can be assigned to the label. 45 | ValueType value_type = 2; 46 | 47 | // A human-readable description for the label. 48 | string description = 3; 49 | } 50 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/log.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/label.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "LogProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // A description of a log type. Example in YAML format: 29 | // 30 | // - name: library.googleapis.com/activity_history 31 | // description: The history of borrowing and returning library items. 32 | // display_name: Activity 33 | // labels: 34 | // - key: /customer_id 35 | // description: Identifier of a library customer 36 | message LogDescriptor { 37 | // The name of the log. It must be less than 512 characters long and can 38 | // include the following characters: upper- and lower-case alphanumeric 39 | // characters [A-Za-z0-9], and punctuation characters including 40 | // slash, underscore, hyphen, period [/_-.]. 41 | string name = 1; 42 | 43 | // The set of labels that are available to describe a specific log entry. 44 | // Runtime requests that contain labels not specified here are 45 | // considered invalid. 46 | repeated LabelDescriptor labels = 2; 47 | 48 | // A human-readable description of this log. This information appears in 49 | // the documentation and can contain details. 50 | string description = 3; 51 | 52 | // The human-readable name for this log. This information appears on 53 | // the user interface and should be concise. 54 | string display_name = 4; 55 | } 56 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/logging.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/annotations.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "LoggingProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // Logging configuration of the service. 29 | // 30 | // The following example shows how to configure logs to be sent to the 31 | // producer and consumer projects. In the example, the `activity_history` 32 | // log is sent to both the producer and consumer projects, whereas the 33 | // `purchase_history` log is only sent to the producer project. 34 | // 35 | // monitored_resources: 36 | // - type: library.googleapis.com/branch 37 | // labels: 38 | // - key: /city 39 | // description: The city where the library branch is located in. 40 | // - key: /name 41 | // description: The name of the branch. 42 | // logs: 43 | // - name: activity_history 44 | // labels: 45 | // - key: /customer_id 46 | // - name: purchase_history 47 | // logging: 48 | // producer_destinations: 49 | // - monitored_resource: library.googleapis.com/branch 50 | // logs: 51 | // - activity_history 52 | // - purchase_history 53 | // consumer_destinations: 54 | // - monitored_resource: library.googleapis.com/branch 55 | // logs: 56 | // - activity_history 57 | message Logging { 58 | // Configuration of a specific logging destination (the producer project 59 | // or the consumer project). 60 | message LoggingDestination { 61 | // The monitored resource type. The type must be defined in the 62 | // [Service.monitored_resources][google.api.Service.monitored_resources] section. 63 | string monitored_resource = 3; 64 | 65 | // Names of the logs to be sent to this destination. Each name must 66 | // be defined in the [Service.logs][google.api.Service.logs] section. If the log name is 67 | // not a domain scoped name, it will be automatically prefixed with 68 | // the service name followed by "/". 69 | repeated string logs = 1; 70 | } 71 | 72 | // Logging configurations for sending logs to the producer project. 73 | // There can be multiple producer destinations, each one must have a 74 | // different monitored resource type. A log can be used in at most 75 | // one producer destination. 76 | repeated LoggingDestination producer_destinations = 1; 77 | 78 | // Logging configurations for sending logs to the consumer project. 79 | // There can be multiple consumer destinations, each one must have a 80 | // different monitored resource type. A log can be used in at most 81 | // one consumer destination. 82 | repeated LoggingDestination consumer_destinations = 2; 83 | } 84 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/servicecontrol/v1/log_entry.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api.servicecontrol.v1; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/logging/type/log_severity.proto"; 21 | import "google/protobuf/any.proto"; 22 | import "google/protobuf/struct.proto"; 23 | import "google/protobuf/timestamp.proto"; 24 | 25 | option go_package = "google.golang.org/genproto/googleapis/api/servicecontrol/v1;servicecontrol"; 26 | option java_multiple_files = true; 27 | option java_outer_classname = "LogEntryProto"; 28 | option java_package = "com.google.api.servicecontrol.v1"; 29 | 30 | 31 | // An individual log entry. 32 | message LogEntry { 33 | // Required. The log to which this log entry belongs. Examples: `"syslog"`, 34 | // `"book_log"`. 35 | string name = 10; 36 | 37 | // The time the event described by the log entry occurred. If 38 | // omitted, defaults to operation start time. 39 | google.protobuf.Timestamp timestamp = 11; 40 | 41 | // The severity of the log entry. The default value is 42 | // `LogSeverity.DEFAULT`. 43 | google.logging.type.LogSeverity severity = 12; 44 | 45 | // A unique ID for the log entry used for deduplication. If omitted, 46 | // the implementation will generate one based on operation_id. 47 | string insert_id = 4; 48 | 49 | // A set of user-defined (key, value) data that provides additional 50 | // information about the log entry. 51 | map labels = 13; 52 | 53 | // The log entry payload, which can be one of multiple types. 54 | oneof payload { 55 | // The log entry payload, represented as a protocol buffer that is 56 | // expressed as a JSON object. The only accepted type currently is 57 | // [AuditLog][google.cloud.audit.AuditLog]. 58 | google.protobuf.Any proto_payload = 2; 59 | 60 | // The log entry payload, represented as a Unicode string (UTF-8). 61 | string text_payload = 3; 62 | 63 | // The log entry payload, represented as a structure that 64 | // is expressed as a JSON object. 65 | google.protobuf.Struct struct_payload = 6; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/servicecontrol/v1/metric_value.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api.servicecontrol.v1; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/servicecontrol/v1/distribution.proto"; 21 | import "google/protobuf/timestamp.proto"; 22 | import "google/type/money.proto"; 23 | 24 | option cc_enable_arenas = true; 25 | option go_package = "google.golang.org/genproto/googleapis/api/servicecontrol/v1;servicecontrol"; 26 | option java_multiple_files = true; 27 | option java_outer_classname = "MetricValueSetProto"; 28 | option java_package = "com.google.api.servicecontrol.v1"; 29 | 30 | 31 | // Represents a single metric value. 32 | message MetricValue { 33 | // The labels describing the metric value. 34 | // See comments on [google.api.servicecontrol.v1.Operation.labels][google.api.servicecontrol.v1.Operation.labels] for 35 | // the overriding relationship. 36 | map labels = 1; 37 | 38 | // The start of the time period over which this metric value's measurement 39 | // applies. The time period has different semantics for different metric 40 | // types (cumulative, delta, and gauge). See the metric definition 41 | // documentation in the service configuration for details. 42 | google.protobuf.Timestamp start_time = 2; 43 | 44 | // The end of the time period over which this metric value's measurement 45 | // applies. 46 | google.protobuf.Timestamp end_time = 3; 47 | 48 | // The value. The type of value used in the request must 49 | // agree with the metric definition in the service configuration, otherwise 50 | // the MetricValue is rejected. 51 | oneof value { 52 | // A boolean value. 53 | bool bool_value = 4; 54 | 55 | // A signed 64-bit integer value. 56 | int64 int64_value = 5; 57 | 58 | // A double precision floating point value. 59 | double double_value = 6; 60 | 61 | // A text string value. 62 | string string_value = 7; 63 | 64 | // A distribution value. 65 | Distribution distribution_value = 8; 66 | } 67 | } 68 | 69 | // Represents a set of metric values in the same metric. 70 | // Each metric value in the set should have a unique combination of start time, 71 | // end time, and label values. 72 | message MetricValueSet { 73 | // The metric name defined in the service configuration. 74 | string metric_name = 1; 75 | 76 | // The values in this metric. 77 | repeated MetricValue metric_values = 2; 78 | } 79 | -------------------------------------------------------------------------------- /HTM.Web.Communication/google/api/source_info.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "SourceInfoProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | 28 | // Source information used to create a Service Config 29 | message SourceInfo { 30 | // All files used during config generation. 31 | repeated google.protobuf.Any source_files = 1; 32 | } 33 | -------------------------------------------------------------------------------- /HTM.Web/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
-------------------------------------------------------------------------------- /HTM.Web/HTM.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HTM.Web/Pages/ArduinoDiagnosticPage.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

Arduino Diagnostic

4 | 5 | 6 |

Status: @(_isConnected ? "online" : "offline")

7 |
8 | 9 | @if (_isConnected) 10 | { 11 | 12 |
13 |
14 | Led ON 15 | Led OFF 16 |
17 | 18 |
19 |

Led is @(_isLedOn ? "on" : "off")

20 |
21 |
22 |
23 | 24 | if (_receivedMessages.Any()) 25 | { 26 | 27 |
28 | Clear 29 |
30 | 31 |
32 | @foreach (var (receivedAt, serialPortMessageType, text) in _receivedMessages.OrderByDescending(x => x.ReceivedAt)) 33 | { 34 |

@($"{receivedAt} | {serialPortMessageType} - {text}")

35 | } 36 |
37 |
38 | } 39 | } 40 | 41 | @if (!string.IsNullOrWhiteSpace(_errorMessage)) 42 | { 43 | 44 |

Error occurred: @_errorMessage

45 |
46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /HTM.Web/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model HTM.Web.Pages.ErrorModel 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Error 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Error.

19 |

An error occurred while processing your request.

20 | 21 | @if (Model.ShowRequestId) 22 | { 23 |

24 | Request ID: @Model.RequestId 25 |

26 | } 27 | 28 |

Development Mode

29 |

30 | Swapping to the Development environment displays detailed information about the error that occurred. 31 |

32 |

33 | The Development environment shouldn't be enabled for deployed applications. 34 | It can result in displaying sensitive information from exceptions to end users. 35 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 36 | and restarting the app. 37 |

38 |
39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /HTM.Web/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | using Microsoft.Extensions.Logging; 5 | 6 | namespace HTM.Web.Pages; 7 | 8 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 9 | [IgnoreAntiforgeryToken] 10 | public class ErrorModel : PageModel 11 | { 12 | public string RequestId { get; set; } 13 | 14 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 15 | 16 | private readonly ILogger _logger; 17 | 18 | public ErrorModel(ILogger logger) 19 | { 20 | _logger = logger; 21 | } 22 | 23 | public void OnGet() 24 | { 25 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 26 | } 27 | } -------------------------------------------------------------------------------- /HTM.Web/Pages/Temperatures.razor: -------------------------------------------------------------------------------- 1 | @page "/temperatures" 2 | 3 |

Temperatures

4 | 5 |
6 | 7 |
8 |
9 | From 10 |
11 | 12 |
13 | await FetchData()) 20 | @bind-Value="@_fromDate" 21 | DateFormat="MM/dd/yyyy HH:mm" class="mb-2" /> 22 |
23 |
24 | 25 |
26 |
27 | To 28 |
29 | 30 |
31 | await FetchData()) 38 | @bind-Value="@_toDate" 39 | DateFormat="MM/dd/yyyy HH:mm" /> 40 |
41 |
42 |
43 |
44 | 45 | @if (_temperatureMeasurement != null) 46 | { 47 | 48 |
49 |
50 |
51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
70 |
71 |
72 |
73 | } 74 | 75 | -------------------------------------------------------------------------------- /HTM.Web/Pages/Temperatures.razor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using HTM.Infrastructure.Models; 4 | using HTM.Web.Communication.Services; 5 | using HTM.Web.Shared; 6 | using Microsoft.AspNetCore.Components; 7 | 8 | namespace HTM.Web.Pages; 9 | 10 | public partial class Temperatures 11 | { 12 | [Inject] public HtmMethodsClient HtmMethodsClient { get; set; } 13 | 14 | private PleaseWaitComponent _pleaseWaitComponent; 15 | private TemperatureMeasurement[] _temperatureMeasurement; 16 | private DateTime _fromDate = DateTime.Now.AddMonths(-1); 17 | private DateTime _toDate = DateTime.Now; 18 | 19 | protected override async Task OnAfterRenderAsync(bool firstRender) 20 | { 21 | if (!firstRender) 22 | { 23 | return; 24 | } 25 | 26 | await FetchData(); 27 | } 28 | 29 | private async Task FetchData() 30 | { 31 | _pleaseWaitComponent.Show(); 32 | await Task.Delay(1000); 33 | 34 | _temperatureMeasurement = await HtmMethodsClient.GetTemperaturesMeasurements( 35 | DateTime.Now.AddMonths(-1), 36 | DateTime.Now); 37 | 38 | _pleaseWaitComponent.Close(); 39 | StateHasChanged(); 40 | } 41 | } -------------------------------------------------------------------------------- /HTM.Web/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace HTM.Web.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @{ 5 | Layout = "_Layout"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /HTM.Web/Pages/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @namespace HTM.Web.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | @RenderBody() 19 | 20 |
21 | 22 | An error has occurred. This application may no longer respond until reloaded. 23 | 24 | 25 | An unhandled exception has occurred. See browser dev tools for details. 26 | 27 | Reload 28 | 🗙 29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /HTM.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using HTM.Communication.V2; 3 | using HTM.Infrastructure.Logging; 4 | using HTM.Web.Communication.Services; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | using Radzen; 9 | 10 | SerilogHelper.AddSerilog(); 11 | 12 | var builder = WebApplication.CreateBuilder(args); 13 | 14 | builder.Services.AddRazorPages(); 15 | builder.Services.AddServerSideBlazor(); 16 | builder.Services.AddScoped(); 17 | 18 | var htmEventsService = new HtmEventsService(); 19 | builder.Services.AddSingleton(_ => htmEventsService); 20 | builder.Services.AddSingleton(_ => htmEventsService); 21 | builder.Services.AddScoped(); 22 | 23 | builder.Services.AddSingleton(sp => 24 | { 25 | var htmEventsCaller = sp.GetRequiredService(); 26 | return new Server 27 | { 28 | Services = { HTMEventsService.BindService(new HtmEventsServer(htmEventsCaller)) }, 29 | Ports = { new ServerPort("localhost", 2005, ServerCredentials.Insecure) } 30 | }; 31 | }); 32 | 33 | builder.Services.AddHostedService(); 34 | 35 | var app = builder.Build(); 36 | if (!app.Environment.IsDevelopment()) 37 | { 38 | app.UseExceptionHandler("/Error"); 39 | app.UseHsts(); 40 | } 41 | 42 | app.UseStaticFiles(); 43 | app.UseRouting(); 44 | app.MapBlazorHub(); 45 | app.MapFallbackToPage("/_Host"); 46 | 47 | app.Run(); -------------------------------------------------------------------------------- /HTM.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:20010", 7 | "sslPort": 44329 8 | } 9 | }, 10 | "profiles": { 11 | "HTM.Web": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "https://localhost:7088;http://localhost:5088", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /HTM.Web/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | HTM 4 | 5 |
6 | 9 | 10 |
11 |
12 | About 13 |
14 | 15 |
16 | @Body 17 | 18 |
19 |
20 |
-------------------------------------------------------------------------------- /HTM.Web/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .top-row, article { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } -------------------------------------------------------------------------------- /HTM.Web/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  9 | 10 |
11 | 23 |
24 | 25 | @code { 26 | private bool _collapseNavMenu = true; 27 | 28 | private string NavMenuCssClass => _collapseNavMenu ? "collapse" : null; 29 | 30 | private void ToggleNavMenu() 31 | { 32 | _collapseNavMenu = !_collapseNavMenu; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /HTM.Web/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /HTM.Web/Shared/PleaseWaitComponent.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Inject] public DialogService Dialog { get; set; } 3 | 4 | public void Show() => Dialog.Open("Please wait", ds => 5 | @
6 |
7 |

Please wait ...

8 |
9 | Loading... 10 |
11 |
12 |
, new DialogOptions { Width = "300px", ShowTitle = false }); 13 | 14 | public void Close() => Dialog.Close(); 15 | } -------------------------------------------------------------------------------- /HTM.Web/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |
2 | 3 | @Title 4 | 5 | 6 | Please take our 7 | brief survey 8 | 9 | and tell us what you think. 10 |
11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string Title { get; set; } 16 | 17 | } -------------------------------------------------------------------------------- /HTM.Web/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using HTM.Web 10 | @using HTM.Web.Shared 11 | @using Radzen 12 | @using Radzen.Blazor 13 | @using HTM.Infrastructure.Models -------------------------------------------------------------------------------- /HTM.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /HTM.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grofab95/HomeTemperatureMonitor/c416be92765bf78270cce884082a003eeaffc7c8/HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grofab95/HomeTemperatureMonitor/c416be92765bf78270cce884082a003eeaffc7c8/HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grofab95/HomeTemperatureMonitor/c416be92765bf78270cce884082a003eeaffc7c8/HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grofab95/HomeTemperatureMonitor/c416be92765bf78270cce884082a003eeaffc7c8/HTM.Web/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /HTM.Web/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | h1:focus { 8 | outline: none; 9 | } 10 | 11 | a, .btn-link { 12 | color: #0071c1; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .content { 22 | padding-top: 1.1rem; 23 | } 24 | 25 | .valid.modified:not([type=checkbox]) { 26 | outline: 1px solid #26b050; 27 | } 28 | 29 | .invalid { 30 | outline: 1px solid red; 31 | } 32 | 33 | .validation-message { 34 | color: red; 35 | } 36 | 37 | #blazor-error-ui { 38 | background: lightyellow; 39 | bottom: 0; 40 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 41 | display: none; 42 | left: 0; 43 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 44 | position: fixed; 45 | width: 100%; 46 | z-index: 1000; 47 | } 48 | 49 | #blazor-error-ui .dismiss { 50 | cursor: pointer; 51 | position: absolute; 52 | right: 0.75rem; 53 | top: 0.5rem; 54 | } 55 | 56 | .blazor-error-boundary { 57 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 58 | padding: 1rem 1rem 1rem 3.7rem; 59 | color: white; 60 | } 61 | 62 | .blazor-error-boundary::after { 63 | content: "An error has occurred." 64 | } 65 | -------------------------------------------------------------------------------- /HTM.Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grofab95/HomeTemperatureMonitor/c416be92765bf78270cce884082a003eeaffc7c8/HTM.Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /HTM/HTM.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | PreserveNewest 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /HTM/Program.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using HTM.Communication.Services; 3 | using HTM.Communication.V2; 4 | using HTM.Core.Services; 5 | using HTM.Database; 6 | using HTM.Database.Extensions; 7 | using HTM.Devices.Arduino.Extensions; 8 | using HTM.Infrastructure.Adapters; 9 | using HTM.Infrastructure.Akka; 10 | using HTM.Infrastructure.Logging; 11 | using Microsoft.Extensions.DependencyInjection; 12 | using Microsoft.Extensions.Hosting; 13 | using Microsoft.Extensions.Logging; 14 | using Serilog; 15 | 16 | SerilogHelper.AddSerilog(); 17 | 18 | CreateHostBuilder(args).Build().Run(); 19 | 20 | static IHostBuilder CreateHostBuilder(string[] args) => 21 | Host.CreateDefaultBuilder(args) 22 | .ConfigureLogging(logging => 23 | { 24 | logging.ClearProviders(); 25 | logging.AddSerilog(); 26 | }) 27 | .ConfigureServices(services => 28 | { 29 | services.AddArduino(); 30 | services.AddDatabase(); 31 | services.AddSingleton(); 32 | services.AddSingleton(); 33 | services.AddHostedService(); 34 | services.AddSingleton(sp => 35 | { 36 | var htmActorBridge = sp.GetRequiredService(); 37 | 38 | return new Server 39 | { 40 | Services = {HTMMethodsService.BindService(new HtmMethodsServer(htmActorBridge))}, 41 | Ports = {new ServerPort("localhost", 2010, ServerCredentials.Insecure)} 42 | }; 43 | }); 44 | 45 | services.AddHostedService(); 46 | }); -------------------------------------------------------------------------------- /HTM/akkaConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "akka": { 3 | "actor": { 4 | "provider": "remote", 5 | "serializers": { 6 | "hyperion": "Akka.Serialization.HyperionSerializer, Akka.Serialization.Hyperion" 7 | }, 8 | "serialization-bindings": { 9 | "System.Object": "hyperion" 10 | } 11 | }, 12 | "loggers": [ 13 | "Akka.Logger.Serilog.SerilogLogger, Akka.Logger.Serilog" 14 | ], 15 | "loglevel": "INFO", 16 | "remote": { 17 | "dot-netty": { 18 | "tcp": { 19 | "hostname": "localhost", 20 | "port": 5005 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /HTM/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Arduino": { 3 | "PortName": "COM6", 4 | "PortBaudRate": 9600 5 | }, 6 | 7 | "Database": { 8 | "ConnectionString": "Server=DESKTOP-HV06FGL;Database=HTM;User Id=sa; Password=Q1w2e3Q1w2e3;" 9 | } 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Home Temperature Monitor 2 | 3 | Stack: .Net 6, Akka.Net, Arduino, GRPC, Blazor, EF Core 4 | 5 | Project has two main applications: 6 | - HTM console app 7 | - HTM.Web blazor server side app 8 | 9 | HTM communicates with arduino through the serial port and asks for the current temperature repeatedly. The result is saved in the ms sql database. 10 | With HTM.Web we can view the temperatures history on a line chart and diagnose arduino board. 11 | Both applications connect to each other using the grpc protocol. 12 | 13 | 14 | ![1](https://user-images.githubusercontent.com/42341432/163802425-bb19bd28-7f94-4be8-b51a-8169f14e7620.png) 15 | --------------------------------------------------------------------------------