├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Examples ├── AnomalyDetection │ ├── .dockerignore │ ├── .env │ ├── .gitignore │ ├── LICENSE │ ├── Modules │ │ ├── AnomalyDetection │ │ │ ├── AnomalyDetection.cs │ │ │ ├── AnomalyDetection.csproj │ │ │ ├── Dockerfile │ │ │ ├── KMeansScoring.cs │ │ │ ├── Program.cs │ │ │ └── anomalydetectionSettings.json │ │ ├── ModelTraining │ │ │ ├── Dockerfile │ │ │ ├── KMeansTraining.cs │ │ │ ├── ModelTraining.cs │ │ │ ├── ModelTraining.csproj │ │ │ └── Program.cs │ │ ├── Orchestrator │ │ │ ├── Dockerfile │ │ │ ├── Orchestrator.cs │ │ │ ├── Orchestrator.csproj │ │ │ └── Program.cs │ │ ├── TemperatureSensor │ │ │ ├── Dockerfile │ │ │ ├── Program.cs │ │ │ ├── TemperatureSensor.cs │ │ │ └── TemperatureSensor.csproj │ │ ├── Visualization │ │ │ ├── Dockerfile │ │ │ ├── Program.cs │ │ │ ├── Visualization.cs │ │ │ ├── Visualization.csproj │ │ │ └── visualizationSettings.json │ │ └── VisualizationWeb │ │ │ ├── ChatHub.cs │ │ │ ├── Dockerfile │ │ │ ├── Pages │ │ │ ├── About.cshtml │ │ │ ├── About.cshtml.cs │ │ │ ├── Contact.cshtml │ │ │ ├── Contact.cshtml.cs │ │ │ ├── Error.cshtml │ │ │ ├── Error.cshtml.cs │ │ │ ├── Index.cshtml │ │ │ ├── Index.cshtml.cs │ │ │ ├── Privacy.cshtml │ │ │ ├── Privacy.cshtml.cs │ │ │ ├── Shared │ │ │ │ ├── _CookieConsentPartial.cshtml │ │ │ │ ├── _Layout.cshtml │ │ │ │ └── _ValidationScriptsPartial.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ │ ├── Program.cs │ │ │ ├── Properties │ │ │ └── launchSettings.json │ │ │ ├── Startup.cs │ │ │ ├── VisualizationWeb.csproj │ │ │ └── wwwroot │ │ │ ├── css │ │ │ ├── site.css │ │ │ └── site.min.css │ │ │ ├── favicon.ico │ │ │ ├── images │ │ │ ├── banner1.svg │ │ │ ├── banner2.svg │ │ │ └── banner3.svg │ │ │ ├── js │ │ │ ├── site.js │ │ │ ├── site.min.js │ │ │ └── visualizer.js │ │ │ └── lib │ │ │ ├── bootstrap │ │ │ ├── .bower.json │ │ │ ├── LICENSE │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ ├── bootstrap-theme.css │ │ │ │ ├── bootstrap-theme.css.map │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ ├── bootstrap-theme.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ └── js │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── npm.js │ │ │ ├── jquery-validation-unobtrusive │ │ │ ├── .bower.json │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ └── jquery.validate.unobtrusive.min.js │ │ │ ├── jquery-validation │ │ │ ├── .bower.json │ │ │ ├── LICENSE.md │ │ │ └── dist │ │ │ │ ├── additional-methods.js │ │ │ │ ├── additional-methods.min.js │ │ │ │ ├── jquery.validate.js │ │ │ │ └── jquery.validate.min.js │ │ │ ├── jquery │ │ │ ├── .bower.json │ │ │ ├── LICENSE.txt │ │ │ └── dist │ │ │ │ ├── jquery.js │ │ │ │ ├── jquery.min.js │ │ │ │ └── jquery.min.map │ │ │ └── signalr │ │ │ └── signalr.js │ ├── README.md │ ├── Thermostat.Emulator │ │ ├── Dockerfile │ │ ├── Program.cs │ │ ├── Thermostat.Emulator.csproj │ │ └── manifest.json │ ├── Thermostat.ServiceApp │ │ ├── Program.cs │ │ └── Thermostat.ServiceApp.csproj │ ├── Thermostat.Shared │ │ ├── Algorithm.cs │ │ ├── ML │ │ │ ├── IScorer.cs │ │ │ └── ITrainer.cs │ │ ├── Messages │ │ │ ├── Anomaly.cs │ │ │ ├── DataAggregate.cs │ │ │ ├── GraphData.cs │ │ │ ├── Model.cs │ │ │ ├── Temperature.cs │ │ │ ├── Visualization │ │ │ │ ├── Chart.cs │ │ │ │ ├── ChartData.cs │ │ │ │ └── VisualizationMessage.cs │ │ │ └── VisualizationData.cs │ │ ├── Modules │ │ │ ├── IAnomalyDetection.cs │ │ │ ├── IModelTraining.cs │ │ │ ├── IOrchestrator.cs │ │ │ ├── ITemperatureSensor.cs │ │ │ └── IVisualization.cs │ │ ├── TemperatureScale.cs │ │ ├── Thermostat.Shared.csproj │ │ ├── Twins │ │ │ ├── ModelTrainingTwin.cs │ │ │ ├── OrchestratorTwin.cs │ │ │ ├── TemperatureTwin.cs │ │ │ ├── VisualizationTwin.cs │ │ │ ├── Waveform.cs │ │ │ └── WaveformType.cs │ │ └── Volumes │ │ │ └── ISharedVolume.cs │ ├── ThermostatApplication.sln │ ├── docker-compose.dcproj │ ├── docker-compose.override.yml │ ├── docker-compose.yml │ └── images │ │ ├── Anomaly.png │ │ ├── EdgeMLContainer.PNG │ │ ├── EdgeML_AD_HighLevelArchitecture.png │ │ ├── VisualizationGraphs.PNG │ │ ├── dirac.png │ │ ├── diracTr.png │ │ ├── homoiconicity.png │ │ └── serviceApp.png └── QuickStart │ ├── .dockerignore │ ├── .env │ ├── .gitignore │ ├── LICENSE │ ├── Modules │ └── TemperatureSensor │ │ ├── Dockerfile │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── TemperatureSensor.cs │ │ └── TemperatureSensor.csproj │ ├── README.md │ ├── Thermostat.Emulator │ ├── Dockerfile │ ├── Program.cs │ ├── Thermostat.Emulator.csproj │ └── manifest.json │ ├── Thermostat.ServiceApp │ ├── Program.cs │ └── Thermostat.ServiceApp.csproj │ ├── Thermostat.Shared │ ├── Messages │ │ └── Temperature.cs │ ├── Modules │ │ └── ITemperatureSensor.cs │ ├── TemperatureScale.cs │ ├── Thermostat.Shared.csproj │ └── Twins │ │ ├── TemperatureTwin.cs │ │ ├── Waveform.cs │ │ └── WaveformType.cs │ ├── ThermostatApplication.sln │ ├── docker │ ├── docker-compose.dcproj │ ├── docker-compose.override.yml │ ├── docker-compose.vs.debug.yml │ ├── docker-compose.vs.release.yml │ └── docker-compose.yml ├── LICENSE ├── Microsoft.Azure.TypeEdge - Examples.sln ├── Microsoft.Azure.TypeEdge.Host ├── .nuspec ├── Certificates │ └── edge-hub-dev │ │ ├── edge-hub-server.ca.pem │ │ └── edge-hub-server.pem ├── Constants.cs ├── Docker │ ├── DockerHostingSettings.cs │ └── DockerModule.cs ├── Dockerfile ├── EmulatorConfigSource.cs ├── Hub │ ├── EdgeHub.cs │ └── IEdgeHub.cs ├── Microsoft.Azure.TypeEdge.Host.csproj ├── Microsoft.Azure.TypeEdge.Host.targets ├── Service │ ├── CodeGenerator.cs │ ├── CodeGeneratorSettings.cs │ ├── Language.cs │ ├── Service.cs │ ├── Service.partial.cs │ ├── Service.tt │ └── ServiceGenerator.cs ├── TypeEdgeHost.cs ├── appsettings_hub.json └── deviceconfig.json ├── Microsoft.Azure.TypeEdge.Proxy ├── IProxy.cs ├── Microsoft.Azure.TypeEdge.Proxy.csproj ├── Proxy.cs └── ProxyFactory.cs ├── Microsoft.Azure.TypeEdge.Test ├── End2EndTest.cs ├── ITestModule.cs ├── Microsoft.Azure.TypeEdge.Test.csproj ├── Properties │ └── launchSettings.json ├── TestModule.cs └── appsettings.json ├── Microsoft.Azure.TypeEdge.Tests ├── Microsoft.Azure.TypeEdge.Tests.csproj └── Program.cs ├── Microsoft.Azure.TypeEdge.sln ├── Microsoft.Azure.TypeEdge ├── Attributes │ └── TypeModuleAttribute.cs ├── Description │ ├── ArgumentDescription.cs │ ├── DirectMethodDescription.cs │ ├── EndpointDescription.cs │ ├── SchemaGenerator.cs │ ├── ServiceDescription.cs │ ├── ServiceDescriptor.cs │ ├── TwinDescription.cs │ └── TypeDescription.cs ├── DovEnv │ ├── DotΕnv.cs │ ├── DotΕnvConfigurationProvider.cs │ └── DotΕnvConfigurationSource.cs ├── Enums │ ├── CompositionResult.cs │ ├── ExecutionResult.cs │ ├── MethodResult.cs │ └── PublishResult.cs ├── Extensions.cs ├── Logger.cs ├── Methods │ ├── EdgeMethodAttribute.cs │ └── MethodArgument.cs ├── Microsoft.Azure.TypeEdge.csproj ├── Modules │ ├── Endpoints │ │ ├── Endpoint.cs │ │ ├── Input.cs │ │ ├── Output.cs │ │ └── Upstream.cs │ ├── Enums │ │ ├── InitializationResult.cs │ │ ├── InputMessageCallbackResult.cs │ │ ├── ModuleStatus.cs │ │ ├── RestartPolicy.cs │ │ └── TwinResult.cs │ ├── ExternalModule.cs │ ├── HostingSettings.cs │ ├── Messages │ │ ├── EdgeMessage.cs │ │ ├── IEdgeMessage.cs │ │ ├── IModuleMessage.cs │ │ ├── JsonMessage.cs │ │ ├── MessageResult.cs │ │ ├── PropertiesResult.cs │ │ └── Reference.cs │ ├── MethodCallback.cs │ ├── ModuleCollection.cs │ ├── ModuleProperties.cs │ ├── SubscriptionCallback.cs │ └── TypeModule.cs ├── Proxy │ ├── IModuleProxy.cs │ ├── ModuleProxy.cs │ └── ModuleProxyBase.cs ├── Startup.cs ├── Twins │ ├── JsonFlatteningConverter.cs │ ├── ModuleTwin.cs │ └── TypeTwin.cs ├── TypeProperty.cs └── Volumes │ ├── Constants.cs │ └── Volume.cs ├── NuGet.Config ├── README.md ├── SignPackages ├── Program.cs ├── SignPackages.csproj └── SignTemplate.json ├── Templates ├── .gitignore ├── LICENSE ├── README.md ├── TypeEdgeApplication.nuspec ├── TypeEdgeApplication │ ├── .dockerignore │ ├── .env │ ├── .template.config │ │ ├── dotnetcli.host.json │ │ └── template.json │ ├── .vscode │ │ ├── launch.json │ │ └── tasks.json │ ├── Modules │ │ ├── TypeEdgeModule1 │ │ │ ├── Dockerfile │ │ │ ├── Program.cs │ │ │ ├── TypeEdgeModule1.cs │ │ │ └── TypeEdgeModule1.csproj │ │ └── TypeEdgeModule2 │ │ │ ├── Dockerfile │ │ │ ├── Program.cs │ │ │ ├── TypeEdgeModule2.cs │ │ │ └── TypeEdgeModule2.csproj │ ├── TypeEdgeApplication.Emulator │ │ ├── Dockerfile │ │ ├── DockerfileEmpty │ │ ├── Program.cs │ │ └── TypeEdgeApplication.Emulator.csproj │ ├── TypeEdgeApplication.Proxy │ │ ├── Program.cs │ │ └── TypeEdgeApplication.Proxy.csproj │ ├── TypeEdgeApplication.Shared │ │ ├── ITypeEdgeModule1.cs │ │ ├── ITypeEdgeModule2.cs │ │ ├── Messages │ │ │ ├── TypeEdgeModule1Output.cs │ │ │ └── TypeEdgeModule2Output.cs │ │ ├── Twins │ │ │ ├── TypeEdgeModule1Twin.cs │ │ │ └── TypeEdgeModule2Twin.cs │ │ └── TypeEdgeApplication.Shared.csproj │ ├── TypeEdgeApplication.sln │ ├── docker-compose.dcproj │ ├── docker-compose.override.yml │ ├── docker-compose.vs.debug.yml │ ├── docker-compose.vs.release.yml │ └── docker-compose.yml ├── TypeEdgeEmulator.nuspec ├── TypeEdgeEmulator │ ├── .template.config │ │ └── template.json │ ├── Program.cs │ └── TypeEdgeEmulator.csproj ├── TypeEdgeModule.nuspec ├── TypeEdgeModule │ ├── .template.config │ │ └── template.json │ ├── Program.cs │ ├── Shared │ │ ├── ITypeEdgeModule.cs │ │ ├── Messages │ │ │ └── TypeEdgeModuleOutput.cs │ │ └── Twins │ │ │ └── TypeEdgeModuleTwin.cs │ ├── TypeEdgeModule.cs │ └── TypeEdgeModule.csproj ├── TypeEdgeModuleVsCode.nuspec ├── TypeEdgeModuleVsCode │ ├── .template.config │ │ ├── dotnetcli.host.json │ │ └── template.json │ ├── Dockerfile.amd64 │ ├── Dockerfile.amd64.debug │ ├── Dockerfile.arm32v7 │ ├── Dockerfile.windows-amd64 │ ├── Program.cs │ ├── Shared │ │ ├── ITypeEdgeModuleVsCode.cs │ │ ├── Messages │ │ │ └── TypeEdgeModuleVsCodeOutput.cs │ │ └── Twins │ │ │ └── TypeEdgeModuleVsCodeTwin.cs │ ├── TypeEdgeModuleVsCode.cs │ ├── TypeEdgeModuleVsCode.csproj │ └── module.json ├── TypeEdgeServiceProxy.nuspec ├── TypeEdgeServiceProxy │ ├── .template.config │ │ └── template.json │ ├── Program.cs │ └── TypeEdgeServiceProxy.csproj ├── TypeEdgeTemplates.sln ├── favicon.ico ├── list-of-excluded-files.txt ├── nuget.exe └── nugetBuild.bat ├── azure-pipelines.yml ├── images ├── IoTEdge.png ├── hqdefault.jpg ├── image.png ├── incontainer.png ├── iothubowner.png ├── maxresdefault.jpg ├── messages.png ├── solution.png ├── vstsSecurity.jpg └── vstsSecurity2.jpg └── nuget.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | Please provide a succinct description of your issue. 4 | 5 | ### Repro steps 6 | 7 | Please provide the steps required to reproduce the problem 8 | 9 | 1. Step A 10 | 11 | 2. Step B 12 | 13 | ### Expected behavior 14 | 15 | Please provide a description of the behavior you expect. 16 | 17 | ### Actual behavior 18 | 19 | Please provide a description of the actual behavior you observe. 20 | 21 | ### Known workarounds 22 | 23 | Please provide a description of any known workarounds. 24 | 25 | ### Related information 26 | 27 | * Operating system 28 | * Branch 29 | * .NET Runtime, CoreCLR or Mono Version 30 | * Performance information, links to performance testing scripts 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for Azure TypeEdge 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "IoT.Edge"] 2 | path = IoT.Edge 3 | url = https://github.com/Azure/iotedge 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.git": false, 4 | "**/.github":false 5 | } 6 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please fork, branch and pull-request any changes you'd like to make. 2 | 3 | #### Contributor Dev Machine Setup 4 | 5 | 1. Clone or Fork this Repository **recursively** 6 | 7 | `git clone https://github.com/paloukari/TypeEdge --recurse-submodules` 8 | 9 | 1. Install the latest .NET Core SDK ( the minimum version is 2.1.302 version) 10 | 1. Replace the "CONNECTION_STRING" in the appsettings.json files with your IoT Hub **owner** connection string 11 | 1. Open the **TypeEdge - AD Example** solution and start the emulator of one of the two examples. 12 | 13 | #### VS Code/ Visual Studio Debugging 14 | 1. You can use the two submodules examples for developing and debugging purposes. 15 | There are two examples, a simple one that has only a temperature generator, and a more complicated 16 | one that is running anomaly detection on the edge with continious retraining of the model. 17 | These examples reference the NuGet packages in "Debug", and the class library projects in "TemplateDevelopment" 18 | configuration. It is highly recommented to work in "TemplateDevelopment". You might have to restart Visual Studio after you change to another configuration. 19 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .git 3 | .gitignore 4 | .vs 5 | .vscode 6 | docker-compose.yml 7 | docker-compose.*.yml 8 | */bin 9 | */obj 10 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/.env: -------------------------------------------------------------------------------- 1 | DOCKER_REGISTRY=typeedge.azurecr.io/ -------------------------------------------------------------------------------- /Examples/AnomalyDetection/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Spyros Garyfallos 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/AnomalyDetection/AnomalyDetection.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp2.1 4 | 5 | latest 6 | Exe 7 | Debug;Release 8 | 9 | 10 | 11 | 12 | 13 | TRACE;DEBUG 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | PreserveNewest 27 | PreserveNewest 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/AnomalyDetection/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/AnomalyDetection/AnomalyDetection.csproj Modules/AnomalyDetection/ 8 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 9 | RUN dotnet restore Modules/AnomalyDetection/AnomalyDetection.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/AnomalyDetection 12 | RUN dotnet build AnomalyDetection.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish AnomalyDetection.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "AnomalyDetection.dll"] 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/AnomalyDetection/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/AnomalyDetection/anomalydetectionSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "kMeansClusters": "3" 3 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/ModelTraining/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/ModelTraining/ModelTraining.csproj Modules/ModelTraining/ 8 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 9 | RUN dotnet restore Modules/ModelTraining/ModelTraining.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/ModelTraining 12 | RUN dotnet build ModelTraining.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish ModelTraining.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "ModelTraining.dll"] 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/ModelTraining/ModelTraining.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | latest 7 | Exe 8 | Debug;Release 9 | 10 | 11 | 12 | 13 | TRACE;DEBUG 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/ModelTraining/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Orchestrator/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/Orchestrator/Orchestrator.csproj Modules/Orchestrator/ 8 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 9 | RUN dotnet restore Modules/Orchestrator/Orchestrator.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/Orchestrator 12 | RUN dotnet build Orchestrator.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish Orchestrator.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Orchestrator.dll"] 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Orchestrator/Orchestrator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | Exe 7 | latest 8 | Debug;Release 9 | 10 | 11 | 12 | TRACE;DEBUG 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Orchestrator/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/TemperatureSensor/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/TemperatureSensor/TemperatureSensor.csproj Modules/TemperatureSensor/ 8 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 9 | RUN dotnet restore Modules/TemperatureSensor/TemperatureSensor.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/TemperatureSensor 12 | RUN dotnet build TemperatureSensor.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish TemperatureSensor.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "TemperatureSensor.dll"] 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/TemperatureSensor/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/TemperatureSensor/TemperatureSensor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | Exe 7 | latest 8 | Debug;Release 9 | 10 | 11 | 12 | TRACE;DEBUG 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Visualization/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1-aspnetcore-runtime 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | EXPOSE 52832 5 | EXPOSE 44331 6 | 7 | FROM microsoft/dotnet:2.1.302-sdk AS build 8 | WORKDIR /src 9 | COPY Modules/Visualization/Visualization.csproj Modules/Visualization/ 10 | COPY Modules/VisualizationWeb/VisualizationWeb.csproj Modules/VisualizationWeb/ 11 | 12 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 13 | RUN dotnet restore Modules/Visualization/Visualization.csproj 14 | COPY . . 15 | WORKDIR /src/Modules/Visualization 16 | RUN dotnet build Visualization.csproj -c Release -o /app 17 | 18 | FROM build AS publish 19 | RUN dotnet publish Visualization.csproj -c Release -o /app 20 | 21 | FROM base AS final 22 | WORKDIR /app 23 | COPY --from=publish /app . 24 | ENTRYPOINT ["dotnet", "Visualization.dll"] 25 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Visualization/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Visualization/Visualization.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | 6 | Exe 7 | latest 8 | Debug;Release 9 | 10 | 11 | 12 | TRACE;DEBUG 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | wwwroot\%(RecursiveDir)%(FileName)%(Extension) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | PreserveNewest 37 | PreserveNewest 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/Visualization/visualizationSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "Urls": "", 8 | "AllowedHosts": "*", 9 | "ASPNETCORE_ENVIRONMENT": "Development", 10 | "server.urls": "http://localhost:5000;http://localhost:5001" 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/ChatHub.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.SignalR; 3 | 4 | namespace SignalRChat.Hubs 5 | { 6 | public class VisualizerHub : Hub 7 | { 8 | // Called when one client tries to send a message. It will then broadcast 9 | // To all clients with that data. 10 | public async Task SendInput(string message) 11 | { 12 | await Clients.All.SendAsync("ReceiveInput", message); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 52832 4 | EXPOSE 44331 5 | 6 | FROM microsoft/dotnet:2.1-sdk AS build 7 | WORKDIR /src 8 | COPY Modules/VisualizationWeb/VisualizationWeb.csproj Modules/VisualizationWeb/ 9 | RUN dotnet restore Modules/VisualizationWeb/VisualizationWeb.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/VisualizationWeb 12 | RUN dotnet build VisualizationWeb.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish VisualizationWeb.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "VisualizationWeb.dll"] 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/About.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model AboutModel 3 | @{ 4 | ViewData["Title"] = "About"; 5 | } 6 |

@ViewData["Title"]

7 |

@Model.Message

8 | 9 |

Use this area to provide additional information!!!

-------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/About.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.RazorPages; 2 | 3 | namespace VisualizationWeb.Pages 4 | { 5 | public class AboutModel : PageModel 6 | { 7 | public string Message { get; set; } 8 | 9 | public void OnGet() 10 | { 11 | Message = "Your application description page."; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ContactModel 3 | @{ 4 | ViewData["Title"] = "Contact"; 5 | } 6 |

@ViewData["Title"]

7 |

@Model.Message

8 | 9 |
10 | One Microsoft Way
11 | Redmond, WA 98052-6399
12 | P: 13 | 425.555.0100 14 |
15 | 16 |
17 | Support: Support@example.com
18 | Marketing: Marketing@example.com 19 |
-------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Contact.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.RazorPages; 2 | 3 | namespace VisualizationWeb.Pages 4 | { 5 | public class ContactModel : PageModel 6 | { 7 | public string Message { get; set; } 8 | 9 | public void OnGet() 10 | { 11 | Message = "Your contact page."; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to Development environment will display more detailed information about the error that occurred. 20 |

21 |

22 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 23 |

-------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace VisualizationWeb.Pages 6 | { 7 | public class ErrorModel : PageModel 8 | { 9 | public string RequestId { get; set; } 10 | 11 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 12 | 13 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 14 | public void OnGet() 15 | { 16 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | 3 | 4 | 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 |
34 |
35 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.RazorPages; 2 | 3 | namespace VisualizationWeb.Pages 4 | { 5 | public class IndexModel : PageModel 6 | { 7 | public void OnGet() 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PrivacyModel 3 | @{ 4 | ViewData["Title"] = "Privacy Policy"; 5 | } 6 |

@ViewData["Title"]

7 | 8 |

Use this page to detail your site's privacy policy.

-------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Privacy.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.RazorPages; 2 | 3 | namespace VisualizationWeb.Pages 4 | { 5 | public class PrivacyModel : PageModel 6 | { 7 | public void OnGet() 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Shared/_CookieConsentPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Http.Features 2 | @{ 3 | var consentFeature = Context.Features.Get(); 4 | var showBanner = !consentFeature?.CanTrack ?? false; 5 | var cookieString = consentFeature?.CreateConsentCookie(); 6 | } 7 | 8 | @if (showBanner) 9 | { 10 | 34 | 44 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 12 | 18 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using VisualizationWeb 2 | @namespace VisualizationWeb.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace VisualizationWeb 5 | { 6 | public class Program 7 | { 8 | // Begin 9 | public static void Main(string[] args) 10 | { 11 | CreateWebHostBuilder(args).Build().Run(); 12 | } 13 | 14 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) 15 | { 16 | return WebHost.CreateDefaultBuilder(args) 17 | .UseStartup(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:52832", 7 | "sslPort": 44331 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "VisualizationWeb": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.Extensions.Configuration; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using SignalRChat.Hubs; 7 | 8 | namespace VisualizationWeb 9 | { 10 | public class Startup 11 | { 12 | public Startup(IConfiguration configuration) 13 | { 14 | Configuration = configuration; 15 | } 16 | 17 | public IConfiguration Configuration { get; } 18 | 19 | // This method gets called by the runtime. Use this method to add services to the container. 20 | public void ConfigureServices(IServiceCollection services) 21 | { 22 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 23 | 24 | services.AddCors(options => options.AddPolicy("CorsPolicy", 25 | builder => 26 | { 27 | builder.AllowAnyMethod().AllowAnyHeader() 28 | .AllowCredentials(); 29 | })); 30 | 31 | 32 | services.AddSignalR(); 33 | } 34 | 35 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 36 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 37 | { 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseExceptionHandler("/Error"); 45 | } 46 | 47 | app.UseStaticFiles(); 48 | 49 | //Route to VisualizerHub, allowing for SingalR 50 | app.UseSignalR(routes => { routes.MapHub("/visualizerhub"); }); 51 | app.UseMvc(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/VisualizationWeb.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | ..\..\docker-compose.dcproj 6 | ab76f0af-b3ab-4686-90f7-1a31d9a8504a 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | body { 4 | padding-bottom: 20px; 5 | padding-top: 50px; 6 | } 7 | 8 | /* Wrapping element */ 9 | 10 | /* Set some basic padding to keep content from hitting the edges */ 11 | 12 | .body-content { 13 | padding-left: 15px; 14 | padding-right: 15px; 15 | } 16 | 17 | /* Carousel */ 18 | 19 | .carousel-caption p { 20 | font-size: 20px; 21 | line-height: 1.4; 22 | } 23 | 24 | /* Make .svg files in the carousel display properly in older browsers */ 25 | 26 | .carousel-inner .item img[src$=".svg"] { width: 100%; } 27 | 28 | /* QR code generator */ 29 | 30 | #qrCode { margin: 15px; } 31 | 32 | /* Hide/rearrange for smaller screens */ 33 | 34 | @media screen and (max-width: 767px) { 35 | /* Hide captions */ 36 | .carousel-caption { display: none; } 37 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your Javascript code. -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 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. 22 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require("../../js/transition.js"); 3 | require("../../js/alert.js"); 4 | require("../../js/button.js"); 5 | require("../../js/carousel.js"); 6 | require("../../js/collapse.js"); 7 | require("../../js/dropdown.js"); 8 | require("../../js/modal.js"); 9 | require("../../js/tooltip.js"); 10 | require("../../js/popover.js"); 11 | require("../../js/scrollspy.js"); 12 | require("../../js/tab.js"); 13 | require("../../js/affix.js"); -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 4 | "version": "3.2.9", 5 | "_release": "3.2.9", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v3.2.9", 9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396" 10 | }, 11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git", 12 | "_target": "^3.2.9", 13 | "_originalSource": "jquery-validation-unobtrusive", 14 | "_direct": true 15 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | 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 distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "https://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jquery-validation/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.17.0", 31 | "_release": "1.17.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.17.0", 35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772" 36 | }, 37 | "_source": "https://github.com/jzaefferer/jquery-validation.git", 38 | "_target": "^1.17.0", 39 | "_originalSource": "jquery-validation", 40 | "_direct": true 41 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "3.3.1", 16 | "_release": "3.3.1", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "3.3.1", 20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e" 21 | }, 22 | "_source": "https://github.com/jquery/jquery-dist.git", 23 | "_target": "^3.3.1", 24 | "_originalSource": "jquery", 25 | "_direct": true 26 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Modules/VisualizationWeb/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Emulator/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | 4 | # Add an unprivileged user account for running Edge Hub 5 | RUN useradd -ms /bin/bash edgehubuser 6 | ENV EdgeHubUser=edgehubuser 7 | 8 | ARG EXE_DIR=. 9 | ENV SSL_CERTIFICATE_PATH=/app/certs 10 | ENV SSL_CERTIFICATE_NAME=mqtt-server.pfx 11 | 12 | # Install snappy and set up symlinks that are absent from the base image 13 | # Required by RocksDb 14 | RUN apt-get update && \ 15 | apt-get install -y libsnappy1v5 libcap2-bin && \ 16 | ln -s /lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so && \ 17 | ln -s /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # add the CAP_NET_BIND_SERVICE capability to the dotnet binary because 21 | # we are starting edge hub as a non-root user 22 | RUN setcap 'cap_net_bind_service=+ep' /usr/share/dotnet/dotnet 23 | 24 | WORKDIR /app 25 | 26 | COPY $EXE_DIR/ ./ 27 | 28 | # Expose MQTT and HTTPS ports 29 | EXPOSE 8883/tcp 30 | EXPOSE 443/tcp 31 | 32 | 33 | WORKDIR /app 34 | 35 | FROM microsoft/dotnet:2.1.302-sdk AS build 36 | WORKDIR /src 37 | COPY Thermostat.Emulator/Thermostat.Emulator.csproj Thermostat.Emulator/ 38 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 39 | COPY Modules/Orchestrator/Orchestrator.csproj Modules/Orchestrator/ 40 | COPY Modules/TemperatureSensor/TemperatureSensor.csproj Modules/TemperatureSensor/ 41 | COPY Modules/ModelTraining/ModelTraining.csproj Modules/ModelTraining/ 42 | COPY Modules/AnomalyDetection/AnomalyDetection.csproj Modules/AnomalyDetection/ 43 | COPY Modules/Visualization/Visualization.csproj Modules/Visualization/ 44 | COPY Modules/VisualizationWeb/VisualizationWeb.csproj Modules/VisualizationWeb/ 45 | 46 | COPY ./.env Thermostat.Emulator/ 47 | COPY NuGet.Config ./ 48 | RUN dotnet restore Thermostat.Emulator/Thermostat.Emulator.csproj 49 | COPY . . 50 | WORKDIR /src/Thermostat.Emulator 51 | RUN dotnet build Thermostat.Emulator.csproj -c Release -o /app 52 | 53 | FROM build AS publish 54 | RUN dotnet publish Thermostat.Emulator.csproj -c Release -o /app 55 | 56 | FROM base AS final 57 | WORKDIR /app 58 | COPY --from=publish /app . 59 | ENTRYPOINT ["dotnet", "Thermostat.Emulator.dll"] 60 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Emulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 5 | using Microsoft.Azure.TypeEdge; 6 | using Microsoft.Azure.TypeEdge.Host; 7 | using Microsoft.Extensions.Configuration; 8 | using Modules; 9 | using ThermostatApplication.Modules; 10 | 11 | namespace ThermostatApplication 12 | { 13 | internal class Program 14 | { 15 | private static async Task Main(string[] args) 16 | { 17 | var configuration = new ConfigurationBuilder() 18 | .AddJsonFile("appSettings.json") 19 | .AddEnvironmentVariables() 20 | .AddDotΕnv() 21 | .AddCommandLine(args) 22 | .Build(); 23 | 24 | var host = new TypeEdgeHost(configuration); 25 | 26 | host.RegisterModule(); 27 | host.RegisterModule(); 28 | host.RegisterModule(); 29 | host.RegisterModule(); 30 | host.RegisterModule(); 31 | 32 | host.Upstream.Subscribe(host.GetProxy().Anomaly); 33 | 34 | var dockerRegistry = configuration.GetValue("DOCKER_REGISTRY") ?? ""; 35 | var manifest = host.GenerateDeviceManifest((e, settings) => 36 | { 37 | //this is the opportunity of the host to change the hosting settings of the module e 38 | if (!settings.IsExternalModule && !settings.IsSystemModule) 39 | settings.Config = new DockerConfig($"{dockerRegistry}{e}:latest", settings.Config.CreateOptions); 40 | return settings; 41 | }); 42 | File.WriteAllText("../../../manifest.json", manifest); 43 | 44 | var sasToken = host.ProvisionDevice(manifest); 45 | 46 | host.BuildEmulatedDevice(sasToken); 47 | 48 | await host.RunAsync(); 49 | 50 | Console.WriteLine("Press to exit.."); 51 | Console.ReadLine(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Emulator/Thermostat.Emulator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.2 6 | latest 7 | Debug;Release 8 | 9 | 10 | 11 | TRACE;DEBUG 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Certificates\%(RecursiveDir)%(FileName)%(Extension) 40 | 41 | 42 | 43 | 44 | 45 | appsettings_hub.json 46 | 47 | 48 | 49 | 50 | 51 | PreserveNewest 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.ServiceApp/Thermostat.ServiceApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | latest 6 | Exe 7 | Debug;Release 8 | 9 | 10 | 11 | TRACE;DEBUG 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Always 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Algorithm.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication 2 | { 3 | public enum Algorithm 4 | { 5 | kMeans = 0, 6 | LSTM = 1 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/ML/IScorer.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.ML 2 | { 3 | public interface IScorer 4 | { 5 | void DeserializeModel(string data); 6 | int Score(double[] point); 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/ML/ITrainer.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.ML 2 | { 3 | public interface ITrainer 4 | { 5 | string SerializeModel(); 6 | void TrainModel(double[][] rawData); 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Anomaly.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class Anomaly : EdgeMessage 6 | { 7 | public Temperature Temperature { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/DataAggregate.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class DataAggregate : EdgeMessage 6 | { 7 | public double[][] Values { get; set; } 8 | public double SamplingRateHz { get; set; } 9 | public string CorrelationID { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/GraphData.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class GraphData : EdgeMessage 6 | { 7 | public bool Anomaly { get; set; } 8 | public double[][] Values { get; set; } 9 | public string CorrelationID { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Model.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class Model : EdgeMessage 6 | { 7 | public Algorithm Algorithm { get; set; } 8 | public string DataJson { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Temperature.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class Temperature : EdgeMessage 6 | { 7 | public double Value { get; set; } 8 | public double TimeStamp { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Visualization/Chart.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Messages.Visualization 2 | { 3 | public class Chart 4 | { 5 | public string Name { get; set; } 6 | public string X_Label { get; set; } 7 | public string Y_Label { get; set; } 8 | public string[] Headers { get; set; } 9 | public bool Append { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Visualization/ChartData.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Messages.Visualization 2 | { 3 | public class ChartData 4 | { 5 | public Chart Chart { get; set; } 6 | public double[][] Points { get; set; } 7 | public bool IsAnomaly { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/Visualization/VisualizationMessage.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Messages.Visualization 2 | { 3 | public class VisualizationMessage 4 | { 5 | public ChartData[] messages; 6 | } 7 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Messages/VisualizationData.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | using ThermostatApplication.Messages.Visualization; 3 | 4 | namespace ThermostatApplication.Messages 5 | { 6 | public class VisualizationData : EdgeMessage 7 | { 8 | public Chart Metadata { get; set; } 9 | public GraphData Data { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Modules/IAnomalyDetection.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using ThermostatApplication.Messages; 4 | 5 | namespace ThermostatApplication.Modules 6 | { 7 | [TypeModule] 8 | public interface IAnomalyDetection 9 | { 10 | Output Anomaly { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Modules/IModelTraining.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using ThermostatApplication.Messages; 5 | using ThermostatApplication.Twins; 6 | 7 | namespace ThermostatApplication.Modules 8 | { 9 | [TypeModule] 10 | public interface IModelTraining 11 | { 12 | Output Model { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Modules/IOrchestrator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using ThermostatApplication.Messages; 5 | using ThermostatApplication.Twins; 6 | 7 | namespace ThermostatApplication.Modules 8 | { 9 | [TypeModule] 10 | public interface IOrchestrator 11 | { 12 | Output Training { get; set; } 13 | Output Detection { get; set; } 14 | Output Visualization { get; set; } 15 | Output Model { get; set; } 16 | ModuleTwin Twin { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Modules/ITemperatureSensor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using ThermostatApplication.Messages; 5 | using ThermostatApplication.Twins; 6 | 7 | namespace ThermostatApplication.Modules 8 | { 9 | [TypeModule] 10 | public interface ITemperatureSensor 11 | { 12 | Output Temperature { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | 15 | void GenerateAnomaly(int value); 16 | } 17 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Modules/IVisualization.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Twins; 3 | using ThermostatApplication.Twins; 4 | 5 | namespace ThermostatApplication.Modules 6 | { 7 | [TypeModule] 8 | public interface IVisualization 9 | { 10 | ModuleTwin Twin { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/TemperatureScale.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication 2 | { 3 | public enum TemperatureScale 4 | { 5 | Celsius, 6 | Fahrenheit 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Thermostat.Shared.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Debug;Release 6 | 7 | 8 | 9 | TRACE;DEBUG 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/ModelTrainingTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace ThermostatApplication.Twins 4 | { 5 | public class ModelTrainingTwin : TypeTwin 6 | { 7 | public int TumblingWindowPercentage { get; set; } 8 | public int AggregationSize { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/OrchestratorTwin.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Azure.TypeEdge.Twins; 3 | 4 | namespace ThermostatApplication.Twins 5 | { 6 | [Flags] 7 | public enum Routing 8 | { 9 | None = 1 << 0, 10 | Train = 1 << 1, 11 | Detect = 1 << 2, 12 | VisualizeSource = 1 << 3, 13 | FeatureExtraction = 1 << 4, 14 | VisualizeFeature = 1 << 5 15 | } 16 | 17 | public class OrchestratorTwin : TypeTwin 18 | { 19 | public TemperatureScale Scale { get; set; } 20 | 21 | public Routing RoutingMode { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/TemperatureTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace ThermostatApplication.Twins 4 | { 5 | public class TemperatureTwin : TypeTwin 6 | { 7 | public double SamplingHz { get; set; } 8 | public double Frequency { get; set; } 9 | public double Amplitude { get; set; } 10 | public WaveformType WaveType { get; set; } 11 | public double Offset { get; set; } 12 | 13 | //TODO: convert this to array-ish 14 | //public Waveform Waveform { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/VisualizationTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace ThermostatApplication.Twins 4 | { 5 | public class VisualizationTwin : TypeTwin 6 | { 7 | public string ChartName { get; set; } 8 | public string XAxisLabel { get; set; } 9 | public string YAxisLabel { get; set; } 10 | public bool Append { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/Waveform.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Twins 2 | { 3 | public class Waveform 4 | { 5 | public double Frequency { get; set; } 6 | public double Amplitude { get; set; } 7 | public WaveformType WaveType { get; set; } 8 | public double VerticalShift { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Twins/WaveformType.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Twins 2 | { 3 | public enum WaveformType 4 | { 5 | Flat = 0, 6 | Sine = 1, 7 | Sawtooth = 2, 8 | Square = 3, 9 | Triangle = 4 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/Thermostat.Shared/Volumes/ISharedVolume.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Volumes; 2 | using ThermostatApplication.Messages; 3 | 4 | namespace ThermostatApplication.Modules 5 | { 6 | public interface ISharedVolume 7 | { 8 | Volume Aggregates { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/AnomalyDetection/docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | Linux 6 | 1373dbdc-dc13-429e-8c17-2e4d85cf42ba 7 | LaunchBrowser 8 | {Scheme}://localhost:{ServicePort} 9 | visualizationweb 10 | 11 | 12 | 13 | 14 | docker-compose.yml 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | visualization: 5 | environment: 6 | - ASPNETCORE_ENVIRONMENT=Development 7 | - ASPNETCORE_URLS=https://+:443;http://+:80 8 | - ASPNETCORE_HTTPS_PORT=44331 9 | ports: 10 | - "52832:80" 11 | - "44331:443" 12 | volumes: 13 | - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro 14 | - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro 15 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | volumes: 3 | env: 4 | 5 | services: 6 | thermostat.emulator: 7 | image: ${DOCKER_REGISTRY}thermostatemulator 8 | build: 9 | context: . 10 | dockerfile: Thermostat.Emulator/Dockerfile 11 | volumes: 12 | - env:/app/env 13 | 14 | orchestrator: 15 | image: ${DOCKER_REGISTRY}orchestrator 16 | build: 17 | context: . 18 | dockerfile: Modules/Orchestrator/Dockerfile 19 | volumes: 20 | - env:/app/env 21 | 22 | temperaturesensor: 23 | image: ${DOCKER_REGISTRY}temperaturesensor 24 | build: 25 | context: . 26 | dockerfile: Modules/TemperatureSensor/Dockerfile 27 | volumes: 28 | - env:/app/env 29 | 30 | modeltraining: 31 | image: ${DOCKER_REGISTRY}modeltraining 32 | build: 33 | context: . 34 | dockerfile: Modules/ModelTraining/Dockerfile 35 | volumes: 36 | - env:/app/env 37 | 38 | anomalydetection: 39 | image: ${DOCKER_REGISTRY}anomalydetection 40 | build: 41 | context: . 42 | dockerfile: Modules/AnomalyDetection/Dockerfile 43 | volumes: 44 | - env:/app/env 45 | 46 | visualization: 47 | image: ${DOCKER_REGISTRY}visualization 48 | build: 49 | context: . 50 | dockerfile: Modules/Visualization/Dockerfile 51 | volumes: 52 | - env:/app/env 53 | -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/Anomaly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/Anomaly.png -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/EdgeMLContainer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/EdgeMLContainer.PNG -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/EdgeML_AD_HighLevelArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/EdgeML_AD_HighLevelArchitecture.png -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/VisualizationGraphs.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/VisualizationGraphs.PNG -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/dirac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/dirac.png -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/diracTr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/diracTr.png -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/homoiconicity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/homoiconicity.png -------------------------------------------------------------------------------- /Examples/AnomalyDetection/images/serviceApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/AnomalyDetection/images/serviceApp.png -------------------------------------------------------------------------------- /Examples/QuickStart/.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .git 3 | .gitignore 4 | .vs 5 | .vscode 6 | docker-compose.yml 7 | docker-compose.*.yml 8 | */bin 9 | */obj 10 | -------------------------------------------------------------------------------- /Examples/QuickStart/.env: -------------------------------------------------------------------------------- 1 | DOCKER_REGISTRY=typeedge.azurecr.io/ -------------------------------------------------------------------------------- /Examples/QuickStart/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Spyros Garyfallos 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Examples/QuickStart/Modules/TemperatureSensor/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/TemperatureSensor/TemperatureSensor.csproj Modules/TemperatureSensor/ 8 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 9 | 10 | COPY ./.env Thermostat.Emulator/ 11 | COPY NuGet.Config ./ 12 | 13 | RUN dotnet restore Modules/TemperatureSensor/TemperatureSensor.csproj 14 | COPY . . 15 | WORKDIR /src/Modules/TemperatureSensor 16 | RUN dotnet build TemperatureSensor.csproj -c Release -o /app 17 | 18 | FROM build AS publish 19 | RUN dotnet publish TemperatureSensor.csproj -c Release -o /app 20 | 21 | FROM base AS final 22 | WORKDIR /app 23 | COPY --from=publish /app . 24 | ENTRYPOINT ["dotnet", "TemperatureSensor.dll"] 25 | -------------------------------------------------------------------------------- /Examples/QuickStart/Modules/TemperatureSensor/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace Modules 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Modules/TemperatureSensor/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "TemperatureSensor": { 4 | "commandName": "Project", 5 | "commandLineArgs": "metadata=true" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Modules/TemperatureSensor/TemperatureSensor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | Exe 7 | latest 8 | Debug;Release 9 | 10 | 11 | 12 | TRACE;DEBUG 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Examples/QuickStart/README.md: -------------------------------------------------------------------------------- 1 | # TypeEdge.QuickStart 2 | A simple IoT edge application example that uses TypeEdge 3 | -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Emulator/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | 4 | # Add an unprivileged user account for running Edge Hub 5 | RUN useradd -ms /bin/bash edgehubuser 6 | ENV EdgeHubUser=edgehubuser 7 | 8 | ARG EXE_DIR=. 9 | ENV SSL_CERTIFICATE_PATH=/app/certs 10 | ENV SSL_CERTIFICATE_NAME=mqtt-server.pfx 11 | 12 | # Install snappy and set up symlinks that are absent from the base image 13 | # Required by RocksDb 14 | RUN apt-get update && \ 15 | apt-get install -y libsnappy1v5 libcap2-bin && \ 16 | ln -s /lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so && \ 17 | ln -s /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # add the CAP_NET_BIND_SERVICE capability to the dotnet binary because 21 | # we are starting edge hub as a non-root user 22 | RUN setcap 'cap_net_bind_service=+ep' /usr/share/dotnet/dotnet 23 | 24 | WORKDIR /app 25 | 26 | COPY $EXE_DIR/ ./ 27 | 28 | # Expose MQTT and HTTPS ports 29 | EXPOSE 8883/tcp 30 | EXPOSE 443/tcp 31 | 32 | 33 | WORKDIR /app 34 | 35 | FROM microsoft/dotnet:2.1.302-sdk AS build 36 | WORKDIR /src 37 | COPY Thermostat.Emulator/Thermostat.Emulator.csproj Thermostat.Emulator/ 38 | COPY Thermostat.Shared/Thermostat.Shared.csproj Thermostat.Shared/ 39 | COPY Modules/TemperatureSensor/TemperatureSensor.csproj Modules/TemperatureSensor/ 40 | 41 | COPY NuGet.Config ./ 42 | RUN dotnet restore Thermostat.Emulator/Thermostat.Emulator.csproj 43 | COPY . . 44 | WORKDIR /src/Thermostat.Emulator 45 | RUN dotnet build Thermostat.Emulator.csproj -c Release -o /app 46 | 47 | FROM build AS publish 48 | RUN dotnet publish Thermostat.Emulator.csproj -c Release -o /app 49 | 50 | FROM base AS final 51 | WORKDIR /app 52 | COPY --from=publish /app . 53 | ENTRYPOINT ["dotnet", "Thermostat.Emulator.dll"] 54 | -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Emulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 5 | using Microsoft.Azure.TypeEdge; 6 | using Microsoft.Azure.TypeEdge.Host; 7 | using Microsoft.Extensions.Configuration; 8 | using Modules; 9 | using ThermostatApplication.Modules; 10 | 11 | namespace ThermostatApplication 12 | { 13 | internal class Program 14 | { 15 | private static async Task Main(string[] args) 16 | { 17 | var configuration = new ConfigurationBuilder() 18 | .AddJsonFile("appsettings.json") 19 | .AddEnvironmentVariables() 20 | .AddDotΕnv() 21 | .AddCommandLine(args) 22 | .Build(); 23 | 24 | var host = new TypeEdgeHost(configuration); 25 | 26 | //register the modules 27 | host.RegisterModule(); 28 | 29 | //var description = Microsoft.Azure.TypeEdge.Description.ServiceDescriptor.Describe(); 30 | //Microsoft.Azure.TypeEdge.Host.Service.ServiceGenerator.CreateFiles(description); 31 | 32 | //host.RegisterExternalModule(new TypeEdge.Host.Docker.DockerModule("tempSensor", 33 | // new HostingSettings("mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0", null), 34 | // null, 35 | // null)); 36 | 37 | //add cross-module routes 38 | host.Upstream.Subscribe(host.GetProxy().Temperature); 39 | 40 | //customize the runtime configuration 41 | var dockerRegistry = configuration.GetValue("DOCKER_REGISTRY") ?? ""; 42 | var manifest = host.GenerateDeviceManifest((e, settings) => 43 | { 44 | //this is the opportunity for the host to change the hosting settings of the module e 45 | if (!settings.IsExternalModule && !settings.IsSystemModule) 46 | settings.Config = new DockerConfig($"{dockerRegistry}{e}:latest", settings.Config.CreateOptions); 47 | return settings; 48 | }); 49 | File.WriteAllText("../../../manifest.json", manifest); 50 | 51 | //provision a new device with the new manifest 52 | var sasToken = host.ProvisionDevice(manifest); 53 | 54 | //build an emulated device in memory 55 | host.BuildEmulatedDevice(sasToken); 56 | 57 | //run the emulated device 58 | await host.RunAsync(); 59 | 60 | Console.WriteLine("Press to exit.."); 61 | Console.ReadLine(); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Emulator/Thermostat.Emulator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | NU1603 7 | latest 8 | Debug;Release 9 | 10 | 11 | 12 | TRACE;DEBUG 13 | 14 | 15 | 16 | 17 | PreserveNewest 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Certificates\%(RecursiveDir)%(FileName)%(Extension) 39 | 40 | 41 | 42 | 43 | 44 | appsettings_hub.json 45 | 46 | 47 | 48 | 49 | 50 | Always 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Emulator/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modulesContent": { 3 | "$edgeAgent": { 4 | "properties.desired": { 5 | "schemaVersion": "1.0", 6 | "runtime": { 7 | "type": "docker", 8 | "settings": { 9 | "minDockerVersion": "v1.25", 10 | "loggingOptions": "", 11 | "registryCredentials": {} 12 | } 13 | }, 14 | "systemModules": { 15 | "edgeAgent": { 16 | "type": "docker", 17 | "settings": { 18 | "image": "mcr.microsoft.com/azureiotedge-agent:1.0", 19 | "createOptions": "{}" 20 | } 21 | }, 22 | "edgeHub": { 23 | "type": "docker", 24 | "status": "running", 25 | "restartPolicy": "always", 26 | "settings": { 27 | "image": "mcr.microsoft.com/azureiotedge-hub:1.0", 28 | "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}" 29 | } 30 | } 31 | }, 32 | "modules": { 33 | "temperaturesensor": { 34 | "version": "1.0", 35 | "type": "docker", 36 | "status": "running", 37 | "restartPolicy": "on-failure", 38 | "settings": { 39 | "image": "typeedge.azurecr.io/temperaturesensor:latest", 40 | "createOptions": "{\"Env\":[\"moduleName=temperaturesensor\"]}" 41 | } 42 | } 43 | } 44 | } 45 | }, 46 | "$edgeHub": { 47 | "properties.desired": { 48 | "schemaVersion": "1.0", 49 | "routes": { 50 | "route0": "FROM /messages/modules/temperaturesensor/outputs/Temperature INTO $upstream" 51 | }, 52 | "storeAndForwardConfiguration": { 53 | "timeToLiveSecs": 20 54 | } 55 | } 56 | }, 57 | "temperaturesensor": { 58 | "properties.desired": { 59 | "SamplingHz": "10", 60 | "Frequency": "2", 61 | "Amplitude": "10", 62 | "WaveType": "Sine", 63 | "Offset": "60", 64 | "___Twin": true 65 | } 66 | } 67 | }, 68 | "deviceContent": null 69 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.ServiceApp/Thermostat.ServiceApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | latest 6 | Exe 7 | Debug;Release 8 | 9 | 10 | 11 | TRACE;DEBUG 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Always 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Messages/Temperature.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace ThermostatApplication.Messages 4 | { 5 | public class Temperature : EdgeMessage 6 | { 7 | public double Value { get; set; } 8 | public double TimeStamp { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Modules/ITemperatureSensor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using ThermostatApplication.Messages; 5 | using ThermostatApplication.Twins; 6 | 7 | namespace ThermostatApplication.Modules 8 | { 9 | [TypeModule] 10 | public interface ITemperatureSensor 11 | { 12 | Output Temperature { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | 15 | void GenerateAnomaly(int value); 16 | } 17 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/TemperatureScale.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication 2 | { 3 | public enum TemperatureScale 4 | { 5 | Celsius, 6 | Fahrenheit 7 | } 8 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Thermostat.Shared.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Debug;Release 6 | 7 | 8 | 9 | TRACE;DEBUG 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Twins/TemperatureTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace ThermostatApplication.Twins 4 | { 5 | public class TemperatureTwin : TypeTwin 6 | { 7 | public double SamplingHz { get; set; } 8 | public double Frequency { get; set; } 9 | public double Amplitude { get; set; } 10 | public WaveformType WaveType { get; set; } 11 | public double Offset { get; set; } 12 | 13 | //TODO: convert this to array-ish 14 | //public Waveform Waveform { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Twins/Waveform.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Twins 2 | { 3 | public class Waveform 4 | { 5 | public double Frequency { get; set; } 6 | public double Amplitude { get; set; } 7 | public WaveformType WaveType { get; set; } 8 | public double VerticalShift { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Examples/QuickStart/Thermostat.Shared/Twins/WaveformType.cs: -------------------------------------------------------------------------------- 1 | namespace ThermostatApplication.Twins 2 | { 3 | public enum WaveformType 4 | { 5 | Flat = 0, 6 | Sine = 1, 7 | Sawtooth = 2, 8 | Square = 3, 9 | Triangle = 4 10 | } 11 | } -------------------------------------------------------------------------------- /Examples/QuickStart/docker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Examples/QuickStart/docker -------------------------------------------------------------------------------- /Examples/QuickStart/docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | Linux 6 | 2b7edc32-1e75-4aaa-a0b9-9b19b53d9587 7 | 8 | 9 | 10 | 11 | docker-compose.yml 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Examples/QuickStart/docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | -------------------------------------------------------------------------------- /Examples/QuickStart/docker-compose.vs.debug.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | -------------------------------------------------------------------------------- /Examples/QuickStart/docker-compose.vs.release.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | -------------------------------------------------------------------------------- /Examples/QuickStart/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | volumes: 3 | env: 4 | 5 | services: 6 | thermostat.emulator: 7 | image: ${DOCKER_REGISTRY}thermostatemulator 8 | build: 9 | context: . 10 | dockerfile: Thermostat.Emulator/Dockerfile 11 | volumes: 12 | - env:/app/env 13 | 14 | temperaturesensor: 15 | image: ${DOCKER_REGISTRY}temperaturesensor 16 | build: 17 | context: . 18 | dockerfile: Modules/TemperatureSensor/Dockerfile 19 | volumes: 20 | - env:/app/env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ------------------------------------------- START OF LICENSE ----------------------------------------- 2 | Azure IoT TypeEdge 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | ----------------------------------------------- END OF LICENSE ------------------------------------------ -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Certificates/edge-hub-dev/edge-hub-server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDo9/SQVADo/+Ph xOBk4skjtWCm2r/zxElfIhh0O4JfpJz070GLxHR1St09iUUVHgsRvCZntiPybE9t OYGR3lAX9L992HaYgxY6XCE68zEk7KANJco7Tz+Wq0US1UitXoK0toc7WWSY6KuT Vo6ef4Ni21Xcb4mIAvmt6Q3LikYyZdw/jYtgRjxo9MuSv4hdhlak5svxNZYFKysO NdgjCknE568PEOIFCo4TuF9XVUi6YQMAGn6k69Y/8jxJKaXKSO8W7OfexKjL1Jdh IBLsfb2V64GxlcOX6qiuBNq9jFDOfUw6VoxdATPITDUaz8E86qAv9HBDm4h3q/4M N143S5sVAgMBAAECggEBAMDvUIASwao0+YGpLXj/hDppZMDqWpvDzEvYDc581izl RANo/ayFpzjYJj9nJmoltl8apeewJTcIUgMP4+ls5oHgdJIBKb6GmWr9j5uleeat fKNGz6OsrunVr1+4ePbzVWXZ4Ebbcn9b+XQM9BH5YlMFeKcVTB3y8NoBLyaIvjfP JTVHV2/vUbyVc3lBGaQ4Pg9N9kne98UgUgtjWholgFDy0uZC9rYiedhLwO35e8aV 6ikpoCkTeW6KVF9t4Bu+ZAiFg2+zjfseznCjRzqe/puysAnXRayBQqZu+nqEVblL b1lQRLTP6uz794Km3PMxesR3GVVirHVSd3cLQ2m11kECgYEA+MfZ8blyyRxMVkW0 P3HfQen8YGWhtx+qzvt8+tEMs62l2ECvCnC60xOtyPHyKjO9G6TpUSbGizW3iLwI 4/ixbyuGDXvuafFsoqjsXpSmdOMT44ipf20ETV5e0D5iqq6JzLva38sCAY+woT/f 9iSXr4o0VAhcoTuxMwsS6GWFe7ECgYEA77qjf6gRT81HA+S9k85u4UNvtQSzqIpi JL9UIcbCc1me62iNtmMnJKfg2SEmAEvQlOrBhGspoBnp3KYyN0MbVA8lr+MtzH0F TswgcSdnZcdUjjg1VdUu5PcgfzWq6grovHRDhrMKDPM3QVtbaXL/Bmkhu7Jd0ArN sVVq10pjgqUCgYBH0TGqZVWslt22ngKtugqwNYLktRIdEig1/kWTBlw7Vmqk5e9h /S8BlhG6C5ZT9oGmBFJSWfZA463q7BVI8lcOd6sII3ms3cP1pPwvRYxT++WW7rG3 lloCl7aZORk0mpQvJR/HMQyQNNHRiuX1YZTkWOpIQ+2xodDConS/3+bL0QKBgBok pW3nezPTtBnlmRMEYS0puIXqJFmN9dQCFX+1eEEyFdWgSkwIlh02PZwQNF+15OJI k6AIO7rc+Jb6fOFv7QwGttpukPEK9Ug5lJQicvEzgrIbyR06KWoI1T9qL+BkHitn FnIbFk6BO5ZiCx79znf5gRdCBV8JvpLHOOaPkziNAoGBAKOYhW2odWTYH67eK7l6 A7EsmOezSUfnr/eoIScDwMSt9C5aBFrDnGeugGCqdAWYX3nOePTtgfdnInVbwErr VOWGGBUgeqNJ2uO7LqpPzltedSndZDgBJED/VLK/D/+k35wTxE6GsFA8RH8UFAL0 D8P0S22Pxo+neoz+tRqScrNQ -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Host 2 | { 3 | internal class Constants 4 | { 5 | internal const string ManifestEnvironmentName = "Manifest"; 6 | } 7 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.0-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} 3 | 4 | # Add an unprivileged user account for running Edge Hub 5 | RUN useradd -ms /bin/bash edgehubuser 6 | ENV EdgeHubUser=edgehubuser 7 | 8 | ARG EXE_DIR=. 9 | ENV SSL_CERTIFICATE_PATH=/app/certs 10 | ENV SSL_CERTIFICATE_NAME=mqtt-server.pfx 11 | 12 | # Install snappy and set up symlinks that are absent from the base image 13 | # Required by RocksDb 14 | RUN apt-get update && \ 15 | apt-get install -y libsnappy1v5 libcap2-bin && \ 16 | ln -s /lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so && \ 17 | ln -s /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # add the CAP_NET_BIND_SERVICE capability to the dotnet binary because 21 | # we are starting edge hub as a non-root user 22 | RUN setcap 'cap_net_bind_service=+ep' /usr/share/dotnet/dotnet 23 | 24 | WORKDIR /app 25 | 26 | COPY $EXE_DIR/ ./ 27 | 28 | # Expose MQTT and HTTPS ports 29 | EXPOSE 8883/tcp 30 | EXPOSE 443/tcp 31 | 32 | CMD ["scripts/linux/start.sh"] 33 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Hub/EdgeHub.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Microsoft.Azure.Devices.Edge.Hub.Service; 4 | using Microsoft.Azure.TypeEdge.Enums; 5 | using Microsoft.Azure.TypeEdge.Modules; 6 | using Microsoft.Azure.TypeEdge.Modules.Enums; 7 | using Microsoft.Extensions.Configuration; 8 | using Agent = Microsoft.Azure.Devices.Edge.Agent.Core; 9 | 10 | namespace Microsoft.Azure.TypeEdge.Host.Hub 11 | { 12 | 13 | internal class EdgeHub : TypeModule, IEdgeHub 14 | { 15 | public override string Name => Agent.Constants.EdgeHubModuleIdentityName; 16 | 17 | public override async Task RunAsync(CancellationToken cancellationToken) 18 | { 19 | if (await Task.Run(() => Program.Main()) == 0) 20 | return ExecutionResult.Ok; 21 | return ExecutionResult.Error; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Hub/IEdgeHub.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Microsoft.Azure.TypeEdge.Host.Hub 7 | { 8 | [TypeModule] 9 | public interface IEdgeHub 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Microsoft.Azure.TypeEdge.Host.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Certificates\edge-hub-dev\edge-hub-server.ca.pem 5 | PreserveNewest 6 | 7 | 8 | Certificates\edge-hub-dev\edge-hub-server.pem 9 | PreserveNewest 10 | 11 | 12 | appsettings_hub.json 13 | PreserveNewest 14 | 15 | 16 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Service/CodeGeneratorSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Host.Service 2 | { 3 | public class CodeGeneratorSettings 4 | { 5 | public static CodeGeneratorSettings Default { get; } = new CodeGeneratorSettings 6 | {Namespace = "TypeEdge.Proxy", OutputPath = "./TypeEdge.Proxy"}; 7 | 8 | public string Namespace { get; set; } 9 | public string OutputPath { get; set; } 10 | public Language Language { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Service/Language.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Host.Service 2 | { 3 | public enum Language 4 | { 5 | CSharp = 0, 6 | TypeScript = 1 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Service/Service.partial.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Description; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Host.Service 4 | { 5 | partial class Service 6 | { 7 | private readonly CodeGeneratorSettings _codeGeneratorSettings; 8 | private readonly ServiceDescription _serviceDescription; 9 | 10 | public Service(ServiceDescription serviceDescription, CodeGeneratorSettings codeGeneratorSettings) 11 | { 12 | _serviceDescription = serviceDescription; 13 | _codeGeneratorSettings = codeGeneratorSettings; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/Service/Service.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" #> 2 | <#@ assembly name="System.Core" #> 3 | <#@ import namespace="System.Linq" #> 4 | <#@ import namespace="System.Text" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | 7 | using Microsoft.Azure.TypeEdge.Attributes; 8 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 9 | using Microsoft.Azure.TypeEdge.Twins; 10 | 11 | namespace <#= _codeGeneratorSettings.Namespace #> 12 | { 13 | [TypeModule] 14 | public interface I<#= _serviceDescription.Name #> 15 | { 16 | <# if(_serviceDescription.InputDescriptions!=null) 17 | foreach (var endpoint in _serviceDescription.InputDescriptions) 18 | { 19 | #> 20 | Input<<#= endpoint.TypeDescription.Name #>> <#= endpoint.Name #> { get; set; } 21 | <# 22 | } 23 | #> 24 | 25 | <# if(_serviceDescription.OutputDescriptions!=null) 26 | foreach (var endpoint in _serviceDescription.OutputDescriptions) 27 | { 28 | #> 29 | Output<<#= endpoint.TypeDescription.Name #>> <#= endpoint.Name #> { get; set; } 30 | <# 31 | } 32 | #> 33 | 34 | <# if(_serviceDescription.TwinDescriptions!=null) 35 | foreach (var twin in _serviceDescription.TwinDescriptions) 36 | { 37 | #> 38 | ModuleTwin<<#= twin.TypeDescription.Name #>> <#= twin.Name #> { get; set; } 39 | <# 40 | } 41 | #> 42 | 43 | 44 | <# if(_serviceDescription.DirectMethodDescriptions!=null) 45 | foreach (var method in _serviceDescription.DirectMethodDescriptions) 46 | { 47 | string returnType = "void"; 48 | string arguments = ""; 49 | if(method.ReturnTypeDescription!=null) 50 | returnType = method.ReturnTypeDescription.Name; 51 | if(method.ArgumentsTypeDescription!=null) 52 | arguments = string.Join( ",", method.ArgumentsTypeDescription.Select(e => $"{e.TypeDescription.Name} {e.Name}").ToArray()); 53 | #> 54 | <#= returnType #> <#= method.Name #>(<#= arguments #>); 55 | <# 56 | } 57 | #> 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Host/deviceconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema-template": "1.0.0", 3 | "modulesContent": { 4 | "$edgeAgent": { 5 | "properties.desired": { 6 | "schemaVersion": "1.0", 7 | "runtime": { 8 | "type": "docker", 9 | "settings": { 10 | "minDockerVersion": "v1.25", 11 | "loggingOptions": "", 12 | "registryCredentials": {} 13 | } 14 | }, 15 | "systemModules": { 16 | "edgeAgent": { 17 | "type": "docker", 18 | "settings": { 19 | "image": "mcr.microsoft.com/azureiotedge-agent:1.0", 20 | "createOptions": {} 21 | } 22 | }, 23 | "edgeHub": { 24 | "type": "docker", 25 | "status": "running", 26 | "restartPolicy": "always", 27 | "settings": { 28 | "image": "mcr.microsoft.com/azureiotedge-hub:1.0", 29 | "createOptions": { 30 | "HostConfig": { 31 | "PortBindings": { 32 | "5671/tcp": [ 33 | { 34 | "HostPort": "5671" 35 | } 36 | ], 37 | "8883/tcp": [ 38 | { 39 | "HostPort": "8883" 40 | } 41 | ], 42 | "443/tcp": [ 43 | { 44 | "HostPort": "443" 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | } 51 | } 52 | }, 53 | "modules": { 54 | } 55 | } 56 | }, 57 | "$edgeHub": { 58 | "properties.desired": { 59 | "schemaVersion": "1.0", 60 | "routes": { 61 | "route": "FROM /* INTO $upstream" 62 | }, 63 | "storeAndForwardConfiguration": { 64 | "timeToLiveSecs": 7200 65 | } 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Proxy/IProxy.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Microsoft.Azure.TypeEdge.Attributes; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Microsoft.Azure.TypeEdge.Proxy 8 | { 9 | [TypeModule] 10 | public interface IProxy : IInterceptor 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Proxy/ProxyFactory.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Castle.DynamicProxy; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Proxy 5 | { 6 | public static class ProxyFactory 7 | { 8 | public static string IotHubConnectionString { get; set; } 9 | public static string DeviceId { get; set; } 10 | 11 | public static T GetModuleProxy(string iotHubConnectionString, string deviceId) 12 | where T : class 13 | { 14 | var containerBuilder = new ContainerBuilder(); 15 | 16 | containerBuilder.RegisterInstance( 17 | new ProxyGenerator().CreateInterfaceProxyWithoutTarget(new Proxy(iotHubConnectionString, 18 | deviceId))); 19 | 20 | var container = containerBuilder.Build(); 21 | 22 | return container.Resolve(); 23 | } 24 | 25 | public static T GetModuleProxy() 26 | where T : class 27 | { 28 | var containerBuilder = new ContainerBuilder(); 29 | 30 | containerBuilder.RegisterInstance( 31 | new ProxyGenerator().CreateInterfaceProxyWithoutTarget( 32 | new Proxy(IotHubConnectionString, 33 | DeviceId))); 34 | 35 | var container = containerBuilder.Build(); 36 | 37 | return container.Resolve(); 38 | } 39 | 40 | public static void Configure(string iotHubConnectionString, string deviceId) 41 | { 42 | IotHubConnectionString = iotHubConnectionString; 43 | DeviceId = deviceId; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/End2EndTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 4 | using Microsoft.Azure.Devices.Edge.Util; 5 | using Microsoft.Azure.TypeEdge.Host; 6 | using Microsoft.Azure.TypeEdge.Proxy; 7 | using Microsoft.Extensions.Configuration; 8 | using Xunit; 9 | 10 | namespace Microsoft.Azure.TypeEdge.Test 11 | { 12 | public class End2EndTest 13 | { 14 | [Fact] 15 | public void TestSingleModule() 16 | { 17 | var configuration = new ConfigurationBuilder() 18 | .AddJsonFile("appSettings.json") 19 | .AddEnvironmentVariables() 20 | .Build(); 21 | 22 | var host = new TypeEdgeHost(configuration); 23 | 24 | //register the modules 25 | host.RegisterModule(); 26 | host.Upstream.Subscribe(host.GetProxy().Output); 27 | 28 | //customize the runtime configuration 29 | var dockerRegistry = configuration.GetValue("DOCKER_REGISTRY") ?? ""; 30 | var manifest = host.GenerateDeviceManifest((e, settings) => 31 | { 32 | //this is the opportunity for the host to change the hosting settings of the module e 33 | if (!settings.IsExternalModule) 34 | settings.Config = new DockerConfig($"{dockerRegistry}{e}:latest", settings.Config.CreateOptions); 35 | return settings; 36 | }); 37 | 38 | //provision a new device with the new manifest 39 | var sasToken = host.ProvisionDevice(manifest); 40 | 41 | //build an emulated device in memory 42 | host.BuildEmulatedDevice(sasToken); 43 | 44 | //run the emulated device 45 | var task = host.RunAsync(); 46 | Console.WriteLine("Waiting for 20 seconds..."); 47 | Thread.Sleep(20 * 1000); 48 | 49 | ProxyFactory.Configure(configuration["IotHubConnectionString"], 50 | configuration["DeviceId"]); 51 | 52 | var testModule = ProxyFactory.GetModuleProxy(); 53 | var offset = new Random().Next(0, 1000); 54 | var lastTwin = testModule.Twin.GetAsync().Result; 55 | lastTwin.Offset = offset; 56 | var res = testModule.Twin.PublishAsync(lastTwin).Result; 57 | var res2 = testModule.TestDirectMethod(10); 58 | 59 | Assert.Equal(res.Offset, offset); 60 | Assert.Equal(10, res2); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/ITestModule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | 5 | namespace Microsoft.Azure.TypeEdge.Test 6 | { 7 | public class TestMessage : Modules.Messages.EdgeMessage 8 | { 9 | public double Value { get; set; } 10 | } 11 | public class TestTwin : TypeTwin 12 | { 13 | public int Offset { get; set; } 14 | } 15 | 16 | [TypeModule] 17 | public interface ITestModule 18 | { 19 | Output Output { get; set; } 20 | ModuleTwin Twin { get; set; } 21 | int TestDirectMethod(int value); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/Microsoft.Azure.TypeEdge.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.0 5 | latest 6 | Debug;Release 7 | false 8 | 9 | 10 | 11 | TRACE;DEBUG 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Certificates\%(RecursiveDir)%(FileName)%(Extension) 41 | 42 | 43 | 44 | 45 | 46 | 47 | appsettings_hub.json 48 | 49 | 50 | 51 | 52 | 53 | PreserveNewest 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Microsoft.Azure.TypeEdge.Test": { 4 | "commandName": "Project" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/TestModule.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Microsoft.Azure.TypeEdge.Enums; 4 | using Microsoft.Azure.TypeEdge.Modules; 5 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 6 | using Microsoft.Azure.TypeEdge.Modules.Enums; 7 | using Microsoft.Azure.TypeEdge.Twins; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Microsoft.Azure.TypeEdge.Test 11 | { 12 | public class TestModule : TypeModule, ITestModule 13 | { 14 | //default values 15 | private static readonly TestTwin _defaultTwin = new TestTwin 16 | { 17 | Offset = 60 18 | }; 19 | 20 | public TestModule(TestTwin defaultTwin = null) 21 | { 22 | Twin.SetDefault(defaultTwin ?? _defaultTwin); 23 | 24 | Twin.Subscribe(async twin => 25 | { 26 | Logger.LogInformation("Twin update"); 27 | 28 | await Twin.ReportAsync(twin); 29 | return TwinResult.Ok; 30 | }); 31 | } 32 | 33 | public Output Output { get; set; } 34 | public ModuleTwin Twin { get; set; } 35 | 36 | public int TestDirectMethod(int value) 37 | { 38 | Logger.LogInformation($"GenerateAnomaly called with value:{value}"); 39 | return value; 40 | } 41 | 42 | public override async Task RunAsync(CancellationToken cancellationToken) 43 | { 44 | var twin = await Twin.GetAsync(); 45 | var message = new TestMessage() 46 | { 47 | Value = 1.0 48 | }; 49 | 50 | await Output.PublishAsync(message); 51 | return ExecutionResult.Ok; 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Test/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "IotHubConnectionString": "CONNECTION_STRING", 3 | "DeviceId": "UnitTestDevice", 4 | "Logging": { 5 | "LogLevel": { 6 | "Default": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge.Tests/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 6 | using Microsoft.Azure.TypeEdge; 7 | using Microsoft.Azure.TypeEdge.Attributes; 8 | using Microsoft.Azure.TypeEdge.Enums; 9 | using Microsoft.Azure.TypeEdge.Host; 10 | using Microsoft.Azure.TypeEdge.Modules; 11 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 12 | using Microsoft.Azure.TypeEdge.Modules.Enums; 13 | using Microsoft.Azure.TypeEdge.Proxy; 14 | using Microsoft.Azure.TypeEdge.Twins; 15 | using Microsoft.Extensions.Configuration; 16 | using Microsoft.Extensions.Logging; 17 | 18 | namespace Microsoft.Azure.TypeEdge.Tests 19 | { 20 | 21 | 22 | class Program 23 | { 24 | 25 | 26 | 27 | private static async Task Main(string[] args) 28 | { 29 | 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Attributes/TypeModuleAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.All)] 6 | public class TypeModuleAttribute : Attribute 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/ArgumentDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Description 4 | { 5 | public class ArgumentDescription 6 | { 7 | public ArgumentDescription(string argumentName, Type type, Func schemaGenerator) 8 | { 9 | Name = argumentName; 10 | TypeDescription = new TypeDescription(type, schemaGenerator); 11 | } 12 | 13 | public string Name { get; set; } 14 | public TypeDescription TypeDescription { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/DirectMethodDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace Microsoft.Azure.TypeEdge.Description 7 | { 8 | public class DirectMethodDescription 9 | { 10 | public DirectMethodDescription(MethodInfo mi, Func schemaGenerator) 11 | { 12 | Name = mi.Name; 13 | if (mi.ReturnType != typeof(void)) 14 | ReturnTypeDescription = new TypeDescription(mi.ReturnType, schemaGenerator); 15 | ArgumentsTypeDescription = mi.GetParameters() 16 | .Select(p => new ArgumentDescription(p.Name, p.ParameterType, schemaGenerator)).ToList(); 17 | } 18 | 19 | public string Name { get; set; } 20 | public List ArgumentsTypeDescription { get; private set; } 21 | public TypeDescription ReturnTypeDescription { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/EndpointDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Description 4 | { 5 | public class EndpointDescription 6 | { 7 | public EndpointDescription(string name, Type type, Func schemaGenerator) 8 | { 9 | Name = name; 10 | TypeDescription = new TypeDescription(type, schemaGenerator); 11 | } 12 | 13 | public string Name { get; } 14 | 15 | public TypeDescription TypeDescription { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/SchemaGenerator.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Schema.Generation; 2 | using System; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Description 5 | { 6 | public class SchemaGenerator 7 | { 8 | private readonly JSchemaGenerator JSchemaGenerator; 9 | 10 | public SchemaGenerator() 11 | { 12 | JSchemaGenerator = new JSchemaGenerator(); 13 | } 14 | 15 | public string Generate(Type type) 16 | { 17 | return JSchemaGenerator.Generate(type).ToString(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/ServiceDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Description 5 | { 6 | public class ServiceDescription 7 | { 8 | public ServiceDescription(string name, 9 | List inputDescriptions, 10 | List outputDescriptions, 11 | List twinDescriptions, 12 | List directMethodDescriptions) 13 | { 14 | Name = name; 15 | InputDescriptions = inputDescriptions; 16 | OutputDescriptions = outputDescriptions; 17 | TwinDescriptions = twinDescriptions; 18 | DirectMethodDescriptions = directMethodDescriptions; 19 | } 20 | public string Name { get; } 21 | public List InputDescriptions { get; } 22 | public List OutputDescriptions { get; } 23 | public List TwinDescriptions { get; } 24 | public List DirectMethodDescriptions { get; } 25 | } 26 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/TwinDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Description 4 | { 5 | public class TwinDescription 6 | { 7 | public TwinDescription(string name, Type type, Func schemaGenerator) 8 | { 9 | Name = name; 10 | TypeDescription = new TypeDescription(type, schemaGenerator); 11 | } 12 | 13 | public string Name { get; } 14 | 15 | public TypeDescription TypeDescription { get; } 16 | 17 | //public TwinDescription(IEnumerable types, Func schemaGenerator) 18 | //{ 19 | // if (types == null || !types.Any()) 20 | // return; 21 | 22 | // var mergeSettings = new JsonMergeSettings 23 | // { 24 | // MergeArrayHandling = MergeArrayHandling.Union 25 | // }; 26 | 27 | // var typeJObjects = types.Select(e => JObject.Parse(schemaGenerator(e))).ToArray(); 28 | // var union = typeJObjects[0]; 29 | // for (var i = 0; i < typeJObjects.Length-1; i++) 30 | // union.Merge(typeJObjects[i + 1], mergeSettings); 31 | 32 | // TypeDescription = union.ToString(Formatting.None); 33 | 34 | //} 35 | } 36 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Description/TypeDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Description 4 | { 5 | public class TypeDescription 6 | { 7 | public TypeDescription(Type type, Func schemaGenerator) 8 | { 9 | Name = type.Name; 10 | Description = schemaGenerator(type); 11 | } 12 | 13 | public string Name { get; set; } 14 | public string Description { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/DovEnv/DotΕnvConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using System.IO; 3 | 4 | namespace Microsoft.Azure.TypeEdge.DovEnv 5 | { 6 | public class DotΕnvConfigurationProvider : FileConfigurationProvider 7 | { 8 | public DotΕnvConfigurationProvider(DotΕnvConfigurationSource source) : base(source) 9 | { 10 | } 11 | 12 | public override void Load(Stream stream) 13 | { 14 | Data = DotΕnv.Read(stream).GetData(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/DovEnv/DotΕnvConfigurationSource.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | namespace Microsoft.Azure.TypeEdge.DovEnv 4 | { 5 | public class DotΕnvConfigurationSource : FileConfigurationSource 6 | { 7 | public override IConfigurationProvider Build(IConfigurationBuilder builder) 8 | { 9 | FileProvider = FileProvider ?? builder.GetFileProvider(); 10 | return new DotΕnvConfigurationProvider(this); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Enums/CompositionResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Enums 2 | { 3 | public enum CompositionResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Enums/ExecutionResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Enums 2 | { 3 | public enum ExecutionResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Enums/MethodResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Enums 2 | { 3 | public enum MethodResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Enums/PublishResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Enums 2 | { 3 | public enum PublishResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Methods/EdgeMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Methods 4 | { 5 | [AttributeUsage(AttributeTargets.All)] 6 | public class EdgeMethodAttribute : Attribute 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Methods/MethodArgument.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Methods 2 | { 3 | public class MethodArgument 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Endpoints/Endpoint.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Endpoints 2 | { 3 | public abstract class Endpoint : TypeProperty 4 | { 5 | protected Endpoint(string name, TypeModule module) 6 | : base(name, module) 7 | { 8 | } 9 | 10 | public abstract string RouteName { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Endpoints/Input.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | using Microsoft.Azure.TypeEdge.Volumes; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Azure.TypeEdge.Modules.Endpoints 7 | { 8 | public class Input : Endpoint 9 | where T : class, IEdgeMessage, new() 10 | { 11 | private readonly Volume _volume; 12 | 13 | public Input(string name, TypeModule module) : 14 | base(name, module) 15 | { 16 | if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Reference<>)) 17 | { 18 | _volume = new Volume(Name, Module); 19 | Module.RegisterVolume(name); 20 | } 21 | } 22 | 23 | public override string RouteName => $"BrokeredEndpoint(\"/modules/{Module.Name}/inputs/{Name}\")"; 24 | 25 | public virtual void Subscribe(Endpoint output, Func> handler) 26 | { 27 | var dereference = new Func>(t => 28 | { 29 | if (_volume == null) return handler(t); 30 | //todo: find a typed way to do this 31 | var fileName = typeof(T).GetProperty("FileName").GetValue(t) as string; 32 | var referenceCount = (int)typeof(T).GetProperty("ReferenceCount").GetValue(t); 33 | var message = _volume.Read(fileName); 34 | 35 | var res = handler(message); 36 | 37 | if (--referenceCount <= 0) 38 | _volume.Delete(fileName); 39 | 40 | return res; 41 | }); 42 | 43 | Module.SubscribeRoute(output.Name, 44 | output.RouteName, 45 | Name, 46 | RouteName, 47 | dereference); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Endpoints/Upstream.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Messages; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules.Endpoints 4 | { 5 | public class Upstream : Output 6 | where T : class, IEdgeMessage, new() 7 | 8 | { 9 | public Upstream(TypeModule module) : 10 | base("$upstream", module) 11 | { 12 | } 13 | 14 | public override string RouteName => "$upstream"; 15 | 16 | public void Subscribe(Output output) 17 | where TO : class, IEdgeMessage, new() 18 | { 19 | Module.SubscribeRoute(output.Name, output.RouteName, Name, RouteName); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Enums/InitializationResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Enums 2 | { 3 | public enum InitializationResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Enums/InputMessageCallbackResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Enums 2 | { 3 | public enum InputMessageCallbackResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Enums/ModuleStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Enums 2 | { 3 | //this code has been copied from the runtime 4 | 5 | public enum ModuleStatus 6 | { 7 | Unknown, 8 | Backoff, 9 | Running, 10 | Unhealthy, 11 | Stopped, 12 | Failed 13 | } 14 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Enums/RestartPolicy.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Enums 2 | { 3 | //this code has been copied from the runtime 4 | 5 | public enum RestartPolicy 6 | { 7 | Never = 0, 8 | OnFailure = 1, 9 | OnUnhealthy = 2, 10 | Always = 3, 11 | Unknown 12 | } 13 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Enums/TwinResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Enums 2 | { 3 | public enum TwinResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/ExternalModule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.Devices.Shared; 2 | using System.Collections.Generic; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Modules 5 | { 6 | public abstract class ExternalModule : TypeModule 7 | { 8 | private readonly TwinCollection _defaultTwin; 9 | private readonly HostingSettings _settings; 10 | 11 | protected ExternalModule(string name, 12 | HostingSettings settings, 13 | TwinCollection defaultTwin, 14 | List routes) 15 | { 16 | Name = name; 17 | _settings = settings; 18 | _defaultTwin = defaultTwin; 19 | Routes = routes; 20 | _settings.IsExternalModule = true; 21 | } 22 | 23 | public override string Name { get; } 24 | 25 | internal override TwinCollection DefaultTwin => _defaultTwin; 26 | internal override List Routes { get; } 27 | 28 | internal override HostingSettings HostingSettings => _settings; 29 | } 30 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/HostingSettings.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules.Enums; 2 | using System.Collections.Generic; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Modules 5 | { 6 | public class HostingSettings 7 | { 8 | public HostingSettings(string imageName, Dictionary options) 9 | { 10 | ImageName = imageName; 11 | Options = options; 12 | } 13 | 14 | public bool IsExternalModule { get; internal set; } 15 | 16 | public virtual string Version => "1.0"; 17 | 18 | public virtual string Type => "docker"; 19 | 20 | public virtual ModuleStatus DesiredStatus => ModuleStatus.Running; 21 | 22 | public virtual RestartPolicy RestartPolicy => RestartPolicy.OnFailure; 23 | 24 | public string ImageName { get; set; } 25 | 26 | public Dictionary Options { get;} 27 | } 28 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/EdgeMessage.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 6 | { 7 | public abstract class EdgeMessage : IEdgeMessage 8 | { 9 | [JsonIgnore] public IDictionary Properties { get; set; } = new Dictionary(); 10 | 11 | public byte[] GetBytes() 12 | { 13 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); 14 | } 15 | 16 | public void SetBytes(byte[] bytes) 17 | { 18 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes), GetType()); 19 | 20 | this.CopyFrom(obj); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/IEdgeMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 4 | { 5 | public interface IEdgeMessage 6 | { 7 | IDictionary Properties { get; set; } 8 | byte[] GetBytes(); 9 | void SetBytes(byte[] bytes); 10 | } 11 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/IModuleMessage.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.Devices.Client; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 4 | { 5 | public interface IModuleMessage 6 | { 7 | IModuleMessage FromMessage(Message message); 8 | string ToJson(); 9 | } 10 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/JsonMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 2 | { 3 | public class JsonMessage : EdgeMessage 4 | { 5 | public string JsonData { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/MessageResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 2 | { 3 | public enum MessageResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/PropertiesResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 2 | { 3 | public enum PropertiesResult 4 | { 5 | Ok, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/Messages/Reference.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules.Messages 2 | { 3 | public class Reference : EdgeMessage 4 | where T : IEdgeMessage 5 | { 6 | public int ReferenceCount { get; set; } 7 | 8 | public string FileName { get; set; } 9 | 10 | public T Message { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/MethodCallback.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules 4 | { 5 | public class MethodCallback 6 | { 7 | public MethodCallback(string name, MethodInfo methodInfo) 8 | { 9 | Name = name; 10 | MethodInfo = methodInfo; 11 | } 12 | 13 | public string Name { get; } 14 | 15 | public MethodInfo MethodInfo { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/ModuleCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules 4 | { 5 | public class ModuleCollection : List 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/ModuleProperties.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Modules 2 | { 3 | public class ModuleProperties 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Modules/SubscriptionCallback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.TypeEdge.Modules 4 | { 5 | public class SubscriptionCallback 6 | { 7 | public SubscriptionCallback(string name, Delegate handler, Type type) 8 | { 9 | Name = name; 10 | Handler = handler; 11 | Type = type; 12 | } 13 | 14 | public string Name { get; } 15 | public Delegate Handler { get; } 16 | 17 | public Type Type { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Proxy/IModuleProxy.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Microsoft.Azure.TypeEdge.Proxy 7 | { 8 | [TypeModule] 9 | public interface IModuleProxy 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Proxy/ModuleProxy.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Proxy 2 | { 3 | internal class ModuleProxy : ModuleProxyBase, IModuleProxy 4 | where T : class 5 | { 6 | public ModuleProxy() 7 | : base(typeof(T)) 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Proxy/ModuleProxyBase.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Microsoft.Azure.TypeEdge.Attributes; 3 | using Microsoft.Azure.TypeEdge.Modules; 4 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 5 | using Microsoft.Azure.TypeEdge.Twins; 6 | using Microsoft.Azure.TypeEdge.Volumes; 7 | using System; 8 | using System.Globalization; 9 | using System.Reflection; 10 | 11 | namespace Microsoft.Azure.TypeEdge.Proxy 12 | { 13 | internal class ModuleProxyBase : TypeModule, IInterceptor 14 | { 15 | private readonly Type _type; 16 | 17 | public ModuleProxyBase(Type type) 18 | { 19 | _type = type; 20 | if (!(_type.GetCustomAttribute(typeof(TypeModuleAttribute), true) is TypeModuleAttribute)) 21 | throw new ArgumentException($"{_type.Name} has no TypeModule annotation"); 22 | if (!_type.IsInterface) 23 | throw new ArgumentException($"{_type.Name} needs to be an interface"); 24 | } 25 | 26 | public override string Name 27 | { 28 | get 29 | { 30 | return _type.GetModuleName(); 31 | } 32 | } 33 | 34 | public void Intercept(IInvocation invocation) 35 | { 36 | if (!invocation.Method.ReturnType.IsGenericType) 37 | return; 38 | var genericDef = invocation.Method.ReturnType.GetGenericTypeDefinition(); 39 | if (!genericDef.IsAssignableFrom(typeof(Input<>)) && 40 | !genericDef.IsAssignableFrom(typeof(Output<>)) && 41 | !genericDef.IsAssignableFrom(typeof(ModuleTwin<>)) && 42 | !genericDef.IsAssignableFrom(typeof(Volume<>))) 43 | return; 44 | var value = Activator.CreateInstance( 45 | genericDef.MakeGenericType(invocation.Method.ReturnType.GenericTypeArguments), 46 | invocation.Method.Name.Replace("get_", ""), this); 47 | invocation.ReturnValue = value; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Twins/ModuleTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules; 2 | using Microsoft.Azure.TypeEdge.Modules.Enums; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Azure.TypeEdge.Twins 7 | { 8 | public class ModuleTwin : TypeProperty 9 | where T : TypeTwin, new() 10 | { 11 | public ModuleTwin(string name, TypeModule module) 12 | : base(name, module) 13 | { 14 | } 15 | 16 | public void Subscribe(Func> handler) 17 | { 18 | Module.SubscribeTwin(Name, handler); 19 | } 20 | 21 | public async Task ReportAsync(T twin) 22 | { 23 | await Module.ReportTwinAsync(Name, twin).ConfigureAwait(false); 24 | } 25 | 26 | public async Task PublishAsync(T twin) 27 | { 28 | return await Module.PublishTwinAsync(Name, twin).ConfigureAwait(false); 29 | } 30 | 31 | public async Task GetAsync() 32 | { 33 | return await Module.GetTwinAsync(Name).ConfigureAwait(false); 34 | } 35 | 36 | public void SetDefault(T twin) 37 | { 38 | Module.SetTwinDefault(Name, twin); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/TypeProperty.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules; 2 | 3 | namespace Microsoft.Azure.TypeEdge 4 | { 5 | public abstract class TypeProperty 6 | { 7 | protected TypeProperty(string name, TypeModule module) 8 | { 9 | Name = name; 10 | Module = module; 11 | } 12 | 13 | public string Name { get; set; } 14 | internal TypeModule Module { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Volumes/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Azure.TypeEdge.Volumes 2 | { 3 | internal class Constants 4 | { 5 | public const string ConfigFileName = "appsettings_compose.json"; 6 | public const string EdgeHubConnectionStringKey = "EdgeHubConnectionString"; 7 | public const string DisableSslCertificateValidationKey = "DisableSslCertificateValidation"; 8 | public const string ModuleNameConfigName = "moduleName"; 9 | public const string ComposeConfigurationPath = "/app/env"; 10 | } 11 | } -------------------------------------------------------------------------------- /Microsoft.Azure.TypeEdge/Volumes/Volume.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Modules; 2 | using Microsoft.Azure.TypeEdge.Modules.Messages; 3 | 4 | namespace Microsoft.Azure.TypeEdge.Volumes 5 | { 6 | public class Volume : TypeProperty 7 | where T : class, IEdgeMessage, new() 8 | { 9 | public Volume(string name, TypeModule module) 10 | : base(name, module) 11 | { 12 | Module.RegisterVolume(Name); 13 | } 14 | 15 | public bool TryWrite(T data, string fileName) 16 | { 17 | if (Module.SetReferenceData(Name, fileName, data)) 18 | return true; 19 | return false; 20 | } 21 | 22 | public T Read(string fileName) 23 | { 24 | return Module.GetReferenceData(Name, fileName); 25 | } 26 | 27 | public bool Delete(string fileName) 28 | { 29 | return Module.DeleteReferenceData(Name, fileName); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SignPackages/SignPackages.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\11.0.2\lib\netstandard2.0\Newtonsoft.Json.dll 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SignPackages/SignTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "CustomerCorrelationId": "47AC931C-4860-411C-A231-8C1B993B78BC", 3 | "SourceLocation": "PATH", 4 | "DestinationLocation": "PATH" 5 | } 6 | -------------------------------------------------------------------------------- /Templates/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Spyros Garyfallos 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Templates/README.md: -------------------------------------------------------------------------------- 1 | # TypeEdge.Templates 2 | Solution and project templates for various TypeEdge project types and TypeEdge applications 3 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Azure.TypeEdge.Templates.Application 5 | Creates a new Azure IoT Edge Application solution for TypeEdge, a strongly typed Azure IoT Edge framework 6 | $version$ 7 | Microsoft 8 | https://aka.ms/TypeEdge 9 | © Microsoft Corporation. All rights reserved. 10 | https://github.com/Azure/TypeEdge/blob/master/LICENSE 11 | Microsoft;Azure;IoT;Edge;TypeEdge 12 | https://github.com/Azure/TypeEdge/blob/master/Templates/favicon.ico 13 | true 14 | en-US 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .git 3 | .gitignore 4 | .vs 5 | .vscode 6 | docker-compose.yml 7 | docker-compose.*.yml 8 | */bin 9 | */obj 10 | nuget.exe 11 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.env: -------------------------------------------------------------------------------- 1 | DOCKER_REGISTRY=registry/ -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.template.config/dotnetcli.host.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbolInfo": { 3 | "module1Name": { 4 | "longName": "module1-name", 5 | "shortName": "m1" 6 | }, 7 | "module2Name": { 8 | "longName": "module2-name", 9 | "shortName": "m2" 10 | }, 11 | "connectionString": { 12 | "longName": "connection-string", 13 | "shortName": "cs" 14 | }, 15 | "containerRegistry": { 16 | "longName": "container-registry", 17 | "shortName": "cr" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "TypeEdge", "Azure", "IoT", "Edge", "Application" ], 5 | "name": "Type Edge Application", 6 | "identity": "Microsoft.Azure.TypeEdge.Templates.Application.CSharp", 7 | "groupIdentity": "TypeEdgeApplication", 8 | "shortName": "typeedgeapp", 9 | "tags": { 10 | "language": "C#", 11 | "type": "project" 12 | }, 13 | "sourceName": "TypeEdgeApplication", 14 | "preferNameDirectory": true, 15 | "symbols": { 16 | "appNameLower": { 17 | "type": "generated", 18 | "generator": "casing", 19 | "parameters": { 20 | "source": "name", 21 | "toLower": true 22 | }, 23 | "replaces": "emulatorimage" 24 | }, 25 | "module1Name": { 26 | "type": "parameter", 27 | "defaultValue": "Module1", 28 | "replaces": "TypeEdgeModule1", 29 | "fileRename": "TypeEdgeModule1", 30 | "description": "The name of the first TypeEdge Module" 31 | }, 32 | "module1NameLower": { 33 | "type": "generated", 34 | "generator": "casing", 35 | "parameters": { 36 | "source": "module1Name", 37 | "toLower": true 38 | }, 39 | "replaces": "module1image" 40 | }, 41 | "module2Name": { 42 | "type": "parameter", 43 | "defaultValue": "Module2", 44 | "replaces": "TypeEdgeModule2", 45 | "fileRename": "TypeEdgeModule2", 46 | "description": "The name of the second TypeEdge Module" 47 | }, 48 | "module2NameLower": { 49 | "type": "generated", 50 | "generator": "casing", 51 | "parameters": { 52 | "source": "module2Name", 53 | "toLower": true 54 | }, 55 | "replaces": "module2image" 56 | }, 57 | "connectionString": { 58 | "type": "parameter", 59 | "replaces": "CONNECTION_STRING", 60 | "description": "The IoT Hub owner connection string" 61 | }, 62 | "containerRegistry": { 63 | "type": "parameter", 64 | "replaces": "registry", 65 | "description": "The container registry login FQN" 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/TypeEdgeApplication.Emulator/bin/Debug/netcoreapp2.1/TypeEdgeApplication.Emulator.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/TypeEdgeApplication.Emulator", 16 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 17 | "console": "internalConsole", 18 | "stopAtEntry": false, 19 | "internalConsoleOptions": "openOnSessionStart" 20 | }, 21 | { 22 | "name": ".NET Core Attach", 23 | "type": "coreclr", 24 | "request": "attach", 25 | "processId": "${command:pickProcess}" 26 | } 27 | ,] 28 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/TypeEdgeApplication.sln" 11 | ], 12 | "problemMatcher": "$msCompile" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule1/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/TypeEdgeModule1/TypeEdgeModule1.csproj Modules/TypeEdgeModule1/ 8 | COPY TypeEdgeApplication.Shared/TypeEdgeApplication.Shared.csproj TypeEdgeApplication.Shared/ 9 | RUN dotnet restore Modules/TypeEdgeModule1/TypeEdgeModule1.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/TypeEdgeModule1 12 | RUN dotnet build TypeEdgeModule1.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish TypeEdgeModule1.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "TypeEdgeModule1.dll"] 21 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule1/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace TypeEdgeModule1 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule1/TypeEdgeModule1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.TypeEdge.Enums; 6 | using Microsoft.Azure.TypeEdge.Modules; 7 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 8 | using Microsoft.Azure.TypeEdge.Twins; 9 | using Microsoft.Extensions.Logging; 10 | using TypeEdgeApplication.Shared; 11 | using TypeEdgeApplication.Shared.Messages; 12 | using TypeEdgeApplication.Shared.Twins; 13 | 14 | namespace Modules 15 | { 16 | public class TypeEdgeModule1 : TypeModule, ITypeEdgeModule1 17 | { 18 | public Output Output { get; set; } 19 | public ModuleTwin Twin { get; set; } 20 | 21 | public bool ResetModule(int sensorThreshold) 22 | { 23 | Logger.LogInformation($"New sensor threshold:{sensorThreshold}"); 24 | return true; 25 | } 26 | 27 | public override async Task RunAsync(CancellationToken cancellationToken) 28 | { 29 | while (!cancellationToken.IsCancellationRequested) 30 | { 31 | await Output.PublishAsync(new TypeEdgeModule1Output 32 | {Data = new Random().NextDouble().ToString(CultureInfo.InvariantCulture)}); 33 | Logger.LogInformation("Generated Message"); 34 | 35 | await Task.Delay(1000, cancellationToken); 36 | } 37 | 38 | return ExecutionResult.Ok; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule1/TypeEdgeModule1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule2/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | WORKDIR /app 4 | 5 | FROM microsoft/dotnet:2.1.302-sdk AS build 6 | WORKDIR /src 7 | COPY Modules/TypeEdgeModule2/TypeEdgeModule2.csproj Modules/TypeEdgeModule2/ 8 | COPY TypeEdgeApplication.Shared/TypeEdgeApplication.Shared.csproj TypeEdgeApplication.Shared/ 9 | RUN dotnet restore Modules/TypeEdgeModule2/TypeEdgeModule2.csproj 10 | COPY . . 11 | WORKDIR /src/Modules/TypeEdgeModule2 12 | RUN dotnet build TypeEdgeModule2.csproj -c Release -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish TypeEdgeModule2.csproj -c Release -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "TypeEdgeModule2.dll"] 21 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule2/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace TypeEdgeModule2 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule2/TypeEdgeModule2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Azure.TypeEdge.Modules; 3 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 4 | using Microsoft.Azure.TypeEdge.Modules.Messages; 5 | using Microsoft.Azure.TypeEdge.Twins; 6 | using Microsoft.Extensions.Logging; 7 | using TypeEdgeApplication.Shared; 8 | using TypeEdgeApplication.Shared.Messages; 9 | using TypeEdgeApplication.Shared.Twins; 10 | 11 | namespace Modules 12 | { 13 | public class TypeEdgeModule2 : TypeModule, ITypeEdgeModule2 14 | { 15 | public TypeEdgeModule2(ITypeEdgeModule1 proxy) 16 | { 17 | proxy.Output.Subscribe(this, async msg => 18 | { 19 | await Output.PublishAsync(new TypeEdgeModule2Output 20 | { 21 | Data = msg.Data, 22 | Metadata = DateTime.UtcNow.ToShortTimeString() 23 | }); 24 | Logger.LogInformation("Generated Message"); 25 | return MessageResult.Ok; 26 | }); 27 | } 28 | 29 | public Output Output { get; set; } 30 | public ModuleTwin Twin { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/Modules/TypeEdgeModule2/TypeEdgeModule2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Emulator/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_tag=2.1.2-runtime-bionic 2 | FROM microsoft/dotnet:${base_tag} AS base 3 | 4 | # Add an unprivileged user account for running Edge Hub 5 | RUN useradd -ms /bin/bash edgehubuser 6 | ENV EdgeHubUser=edgehubuser 7 | 8 | ARG EXE_DIR=. 9 | ENV SSL_CERTIFICATE_PATH=/app/certs 10 | ENV SSL_CERTIFICATE_NAME=mqtt-server.pfx 11 | 12 | # Install snappy and set up symlinks that are absent from the base image 13 | # Required by RocksDb 14 | RUN apt-get update && \ 15 | apt-get install -y libsnappy1v5 libcap2-bin && \ 16 | ln -s /lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so && \ 17 | ln -s /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc.so && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # add the CAP_NET_BIND_SERVICE capability to the dotnet binary because 21 | # we are starting edge hub as a non-root user 22 | RUN setcap 'cap_net_bind_service=+ep' /usr/share/dotnet/dotnet 23 | 24 | WORKDIR /app 25 | 26 | COPY $EXE_DIR/ ./ 27 | 28 | # Expose MQTT and HTTPS ports 29 | EXPOSE 8883/tcp 30 | EXPOSE 443/tcp 31 | 32 | 33 | WORKDIR /app 34 | 35 | FROM microsoft/dotnet:2.1.302-sdk AS build 36 | WORKDIR /src 37 | COPY TypeEdgeApplication.Emulator/TypeEdgeApplication.Emulator.csproj TypeEdgeApplication.Emulator/ 38 | COPY TypeEdgeApplication.Shared/TypeEdgeApplication.Shared.csproj TypeEdgeApplication.Shared/ 39 | COPY Modules/TypeEdgeModule2/TypeEdgeModule2.csproj Modules/TypeEdgeModule2/ 40 | COPY Modules/TypeEdgeModule1/TypeEdgeModule1.csproj Modules/TypeEdgeModule1/ 41 | 42 | COPY ./.env Thermostat.Emulator/ 43 | COPY NuGet.Config ./ 44 | RUN dotnet restore TypeEdgeApplication.Emulator/TypeEdgeApplication.Emulator.csproj 45 | COPY . . 46 | WORKDIR /src/TypeEdgeApplication.Emulator 47 | RUN dotnet build TypeEdgeApplication.Emulator.csproj -c Release -o /app 48 | 49 | FROM build AS publish 50 | RUN dotnet publish TypeEdgeApplication.Emulator.csproj -c Release -o /app 51 | 52 | FROM base AS final 53 | WORKDIR /app 54 | COPY --from=publish /app . 55 | ENTRYPOINT ["dotnet", "TypeEdgeApplication.Emulator.dll"] 56 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Emulator/DockerfileEmpty: -------------------------------------------------------------------------------- 1 | FROM scratch -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Emulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 5 | using Microsoft.Azure.TypeEdge; 6 | using Microsoft.Azure.TypeEdge.Host; 7 | using Microsoft.Extensions.Configuration; 8 | using TypeEdgeApplication.Shared; 9 | using TypeEdgeModule1 = Modules.TypeEdgeModule1; 10 | using TypeEdgeModule2 = Modules.TypeEdgeModule2; 11 | 12 | namespace TypeEdgeApplication 13 | { 14 | internal class Program 15 | { 16 | public static async Task Main(string[] args) 17 | { 18 | //TODO: Set your IoT Hub iothubowner connection string in appsettings.json 19 | var configuration = new ConfigurationBuilder() 20 | .AddJsonFile("appSettings.json") 21 | .AddEnvironmentVariables() 22 | .AddDotΕnv() 23 | .AddCommandLine(args) 24 | .Build(); 25 | 26 | var host = new TypeEdgeHost(configuration); 27 | 28 | //TODO: Register your TypeEdge Modules here 29 | host.RegisterModule(); 30 | host.RegisterModule(); 31 | 32 | //TODO: Define all cross-module subscriptions 33 | host.Upstream.Subscribe(host.GetProxy().Output); 34 | 35 | //customize the runtime configuration 36 | var dockerRegistry = configuration.GetValue("DOCKER_REGISTRY") ?? ""; 37 | var manifest = host.GenerateDeviceManifest((e, settings) => 38 | { 39 | //this is the opportunity for the host to change the hosting settings of the module e 40 | if (!settings.IsExternalModule && !settings.IsSystemModule) 41 | settings.Config = new DockerConfig($"{dockerRegistry}{e}:latest", settings.Config.CreateOptions); 42 | return settings; 43 | }); 44 | File.WriteAllText("../../../manifest.json", manifest); 45 | 46 | //provision a new device with the new manifest 47 | var sasToken = host.ProvisionDevice(manifest); 48 | 49 | //build an emulated device in memory 50 | host.BuildEmulatedDevice(sasToken); 51 | 52 | //run the emulated device 53 | await host.RunAsync(); 54 | 55 | Console.WriteLine("Press to exit.."); 56 | Console.ReadLine(); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Emulator/TypeEdgeApplication.Emulator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | NU1603 8 | 9 | 10 | 11 | 12 | PreserveNewest 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | PreserveNewest 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Proxy/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Azure.TypeEdge.Proxy; 3 | using Microsoft.Extensions.Configuration; 4 | using TypeEdgeApplication.Shared; 5 | 6 | namespace TypeEdgeApplication.Proxy 7 | { 8 | internal class Program 9 | { 10 | private static void Main(string[] args) 11 | { 12 | Console.WriteLine("Press to start.."); 13 | Console.ReadLine(); 14 | 15 | var configuration = new ConfigurationBuilder() 16 | .AddJsonFile("appSettings.json") 17 | .AddEnvironmentVariables() 18 | .Build(); 19 | 20 | ProxyFactory.Configure(configuration["IotHubConnectionString"], 21 | configuration["DeviceId"]); 22 | 23 | //TODO: Get your module proxies by contract 24 | var proxy = ProxyFactory.GetModuleProxy(); 25 | proxy.ResetModule(100); 26 | 27 | Console.WriteLine("Press to exit.."); 28 | Console.ReadLine(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Proxy/TypeEdgeApplication.Proxy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/ITypeEdgeModule1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using TypeEdgeApplication.Shared.Messages; 5 | using TypeEdgeApplication.Shared.Twins; 6 | 7 | namespace TypeEdgeApplication.Shared 8 | { 9 | [TypeModule] 10 | public interface ITypeEdgeModule1 11 | { 12 | Output Output { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | 15 | bool ResetModule(int sensorThreshold); 16 | } 17 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/ITypeEdgeModule2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using TypeEdgeApplication.Shared.Messages; 5 | using TypeEdgeApplication.Shared.Twins; 6 | 7 | namespace TypeEdgeApplication.Shared 8 | { 9 | [TypeModule] 10 | public interface ITypeEdgeModule2 11 | { 12 | Output Output { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/Messages/TypeEdgeModule1Output.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using Microsoft.Azure.TypeEdge.Modules.Messages; 4 | using Newtonsoft.Json; 5 | 6 | namespace TypeEdgeApplication.Shared.Messages 7 | { 8 | public class TypeEdgeModule1Output : IEdgeMessage 9 | { 10 | public string Data { get; set; } 11 | public IDictionary Properties { get; set; } 12 | 13 | public byte[] GetBytes() 14 | { 15 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); 16 | } 17 | 18 | public void SetBytes(byte[] bytes) 19 | { 20 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes)); 21 | Properties = obj.Properties; 22 | 23 | Data = obj.Data; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/Messages/TypeEdgeModule2Output.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using Microsoft.Azure.TypeEdge.Modules.Messages; 4 | using Newtonsoft.Json; 5 | 6 | namespace TypeEdgeApplication.Shared.Messages 7 | { 8 | public class TypeEdgeModule2Output : IEdgeMessage 9 | { 10 | public string Data { get; set; } 11 | public string Metadata { get; set; } 12 | public IDictionary Properties { get; set; } 13 | 14 | public byte[] GetBytes() 15 | { 16 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); 17 | } 18 | 19 | public void SetBytes(byte[] bytes) 20 | { 21 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes)); 22 | Properties = obj.Properties; 23 | 24 | Data = obj.Data; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/Twins/TypeEdgeModule1Twin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace TypeEdgeApplication.Shared.Twins 4 | { 5 | public class TypeEdgeModule1Twin : TypeTwin 6 | { 7 | public int Threshold { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/Twins/TypeEdgeModule2Twin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace TypeEdgeApplication.Shared.Twins 4 | { 5 | public class TypeEdgeModule2Twin : TypeTwin 6 | { 7 | public int Threshold { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/TypeEdgeApplication.Shared/TypeEdgeApplication.Shared.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | Linux 6 | 6603bb40-94eb-4afc-83de-9ef235f45237 7 | 8 | 9 | 10 | 11 | docker-compose.yml 12 | 13 | 14 | docker-compose.yml 15 | 16 | 17 | docker-compose.yml 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | emulatorimage: 5 | image: ${DOCKER_REGISTRY}emulatorimage 6 | build: 7 | context: . 8 | dockerfile: TypeEdgeApplication.Emulator/Dockerfile 9 | volumes: 10 | - env:/app/env -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/docker-compose.vs.debug.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/docker-compose.vs.release.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | -------------------------------------------------------------------------------- /Templates/TypeEdgeApplication/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | volumes: 3 | env: 4 | 5 | services: 6 | emulatorimage: 7 | image: ${DOCKER_REGISTRY}emulatorimage 8 | build: 9 | context: . 10 | dockerfile: TypeEdgeApplication.Emulator/DockerfileEmpty 11 | volumes: 12 | - env:/app/env 13 | 14 | module1image: 15 | image: ${DOCKER_REGISTRY}module1image 16 | build: 17 | context: . 18 | dockerfile: Modules/TypeEdgeModule1/Dockerfile 19 | volumes: 20 | - env:/app/env 21 | 22 | module2image: 23 | image: ${DOCKER_REGISTRY}module2image 24 | build: 25 | context: . 26 | dockerfile: Modules/TypeEdgeModule2/Dockerfile 27 | volumes: 28 | - env:/app/env 29 | 30 | -------------------------------------------------------------------------------- /Templates/TypeEdgeEmulator.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Azure.TypeEdge.Templates.Emulator 5 | Creates a new Azure IoT Edge Emulator project for TypeEdge, a strongly typed Azure IoT Edge framework 6 | $version$ 7 | Microsoft 8 | https://aka.ms/TypeEdge 9 | © Microsoft Corporation. All rights reserved. 10 | https://github.com/Azure/TypeEdge/blob/master/LICENSE 11 | Microsoft;Azure;IoT;Edge;TypeEdge 12 | https://github.com/Azure/TypeEdge/blob/master/Templates/favicon.ico 13 | true 14 | en-US 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Templates/TypeEdgeEmulator/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "TypeEdge", "Azure", "IoT", "Edge", "Emulator" ], 5 | "name": "Type Edge Emulator", 6 | "identity": "Microsoft.Azure.TypeEdge.Templates.Emulator.CSharp", 7 | "groupIdentity": "TypeEdgeEmulator", 8 | "shortName": "typeedgeemulator", 9 | "tags": { 10 | "language": "C#", 11 | "type": "project" 12 | }, 13 | "sourceName": "TypeEdgeEmulator", 14 | "preferNameDirectory": true 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeEmulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.Azure.Devices.Edge.Agent.Docker; 5 | using Microsoft.Azure.TypeEdge.Host; 6 | using Microsoft.Extensions.Configuration; 7 | 8 | namespace TypeEdgeEmulator 9 | { 10 | internal class Program 11 | { 12 | public static async Task Main(string[] args) 13 | { 14 | //TODO: Set your IoT Hub iothubowner connection string in appsettings.json 15 | var configuration = new ConfigurationBuilder() 16 | .AddJsonFile("appSettings.json") 17 | .AddEnvironmentVariables() 18 | .AddCommandLine(args) 19 | .Build(); 20 | 21 | var host = new TypeEdgeHost(configuration); 22 | 23 | //TODO: Register your TypeEdge Modules here 24 | //host.RegisterModule(); 25 | 26 | //TODO: Define all cross-module subscriptions 27 | //host.Upstream.Subscribe(host.GetProxy().NormalizedTemperature); 28 | 29 | //customize the runtime configuration 30 | var dockerRegistry = configuration.GetValue("DOCKER_REGISTRY") ?? ""; 31 | var manifest = host.GenerateDeviceManifest((e, settings) => 32 | { 33 | //this is the opportunity for the host to change the hosting settings of the module e 34 | if (!settings.IsExternalModule && !settings.IsSystemModule) 35 | settings.Config = new DockerConfig($"{dockerRegistry}{e}:latest", settings.Config.CreateOptions); 36 | return settings; 37 | }); 38 | File.WriteAllText("../../../manifest.json", manifest); 39 | 40 | //provision a new device with the new manifest 41 | var sasToken = host.ProvisionDevice(manifest); 42 | 43 | //build an emulated device in memory 44 | host.BuildEmulatedDevice(sasToken); 45 | 46 | //run the emulated device 47 | await host.RunAsync(); 48 | 49 | Console.WriteLine("Press to exit.."); 50 | Console.ReadLine(); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeEmulator/TypeEdgeEmulator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Templates/TypeEdgeModule.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Azure.TypeEdge.Templates.Module 5 | Creates a new Azure IoT Edge Module project for TypeEdge, a strongly typed Azure IoT Edge framework 6 | $version$ 7 | Microsoft 8 | https://aka.ms/TypeEdge 9 | © Microsoft Corporation. All rights reserved. 10 | https://github.com/Azure/TypeEdge/blob/master/LICENSE 11 | Microsoft;Azure;IoT;Edge;TypeEdge 12 | https://github.com/Azure/TypeEdge/blob/master/Templates/favicon.ico 13 | true 14 | en-US 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "TypeEdge", "Azure", "IoT", "Edge", "Module" ], 5 | "name": "Type Edge Module", 6 | "identity": "Microsoft.Azure.TypeEdge.Templates.Module.CSharp", 7 | "groupIdentity": "TypeEdgeModule", 8 | "shortName": "typeedgemodule", 9 | "tags": { 10 | "language": "C#", 11 | "type": "project" 12 | }, 13 | "sourceName": "TypeEdgeModule", 14 | "preferNameDirectory": true 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace TypeEdgeModule 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/Shared/ITypeEdgeModule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using Shared.Messages; 5 | using Shared.Twins; 6 | 7 | namespace Shared 8 | { 9 | [TypeModule] 10 | public interface ITypeEdgeModule 11 | { 12 | Output Output { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/Shared/Messages/TypeEdgeModuleOutput.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using Microsoft.Azure.TypeEdge.Modules.Messages; 4 | using Newtonsoft.Json; 5 | 6 | namespace Shared.Messages 7 | { 8 | public class TypeEdgeModuleOutput : IEdgeMessage 9 | { 10 | public string Data { get; set; } 11 | public IDictionary Properties { get; set; } 12 | 13 | public byte[] GetBytes() 14 | { 15 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); 16 | } 17 | 18 | public void SetBytes(byte[] bytes) 19 | { 20 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes)); 21 | Properties = obj.Properties; 22 | 23 | Data = obj.Data; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/Shared/Twins/TypeEdgeModuleTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace Shared.Twins 4 | { 5 | public class TypeEdgeModuleTwin : TypeTwin 6 | { 7 | public int Threshold { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/TypeEdgeModule.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Microsoft.Azure.TypeEdge.Enums; 4 | using Microsoft.Azure.TypeEdge.Modules; 5 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 6 | using Microsoft.Azure.TypeEdge.Twins; 7 | using Shared; 8 | using Shared.Messages; 9 | using Shared.Twins; 10 | 11 | namespace Modules 12 | { 13 | public class TypeEdgeModule : TypeModule, ITypeEdgeModule 14 | { 15 | public Output Output { get; set; } 16 | public ModuleTwin Twin { get; set; } 17 | 18 | public override async Task RunAsync(CancellationToken cancellationToken) 19 | { 20 | while (!cancellationToken.IsCancellationRequested) 21 | { 22 | await Output.PublishAsync(new TypeEdgeModuleOutput()); 23 | await Task.Delay(1000, cancellationToken); 24 | } 25 | 26 | return ExecutionResult.Ok; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModule/TypeEdgeModule.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Azure.TypeEdge.Templates.Module.VsCode 5 | A TypeEdge Module project template for VsCode Azure IoT Edge extension 6 | $version$ 7 | Microsoft 8 | https://aka.ms/TypeEdge 9 | © Microsoft Corporation. All rights reserved. 10 | https://github.com/Azure/TypeEdge/blob/master/LICENSE 11 | Microsoft;Azure;IoT;Edge;TypeEdge 12 | https://github.com/Azure/TypeEdge/blob/master/Templates/favicon.ico 13 | true 14 | en-US 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/.template.config/dotnetcli.host.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbolInfo": { 3 | "repository": { 4 | "longName": "repository", 5 | "shortName": "r" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "TypeEdge", "Azure", "IoT", "Edge", "Module", "VsCode" ], 5 | "name": "TypeEdge VsCode Module", 6 | "identity": "Microsoft.Azure.TypeEdge.Templates.Module.VsCode.CSharp", 7 | "groupIdentity": "TypeEdgeModuleVsCode", 8 | "shortName": "typeedgemodulevscode", 9 | "tags": { 10 | "language": "C#", 11 | "type": "project" 12 | }, 13 | "sourceName": "TypeEdgeModuleVsCode", 14 | "preferNameDirectory": true, 15 | "symbols": { 16 | "repository": { 17 | "type": "parameter", 18 | "defaultValue": "repository", 19 | "replaces": "repositoryName", 20 | "fileRename": "repositoryName", 21 | "description": "The name of the container repository name" 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Dockerfile.amd64: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1-sdk AS build-env 2 | WORKDIR /app 3 | 4 | COPY *.csproj ./ 5 | RUN dotnet restore 6 | 7 | COPY . ./ 8 | RUN dotnet publish -c Release -o out 9 | 10 | FROM microsoft/dotnet:2.1-runtime-stretch-slim 11 | WORKDIR /app 12 | COPY --from=build-env /app/out ./ 13 | 14 | RUN useradd -ms /bin/bash moduleuser 15 | USER moduleuser 16 | 17 | ENTRYPOINT ["dotnet", "TypeEdgeModuleVsCode.dll"] -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Dockerfile.amd64.debug: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1-runtime-stretch-slim AS base 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y --no-install-recommends unzip procps && \ 5 | rm -rf /var/lib/apt/lists/* 6 | 7 | RUN useradd -ms /bin/bash moduleuser 8 | USER moduleuser 9 | RUN curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg 10 | 11 | FROM microsoft/dotnet:2.1-sdk AS build-env 12 | WORKDIR /app 13 | 14 | COPY *.csproj ./ 15 | RUN dotnet restore 16 | 17 | COPY . ./ 18 | RUN dotnet publish -c Debug -o out 19 | 20 | FROM base 21 | WORKDIR /app 22 | COPY --from=build-env /app/out ./ 23 | 24 | ENTRYPOINT ["dotnet", "TypeEdgeModuleVsCode.dll"] -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Dockerfile.arm32v7: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1-sdk AS build-env 2 | WORKDIR /app 3 | 4 | COPY *.csproj ./ 5 | RUN dotnet restore 6 | 7 | COPY . ./ 8 | RUN dotnet publish -c Release -o out 9 | 10 | FROM microsoft/dotnet:2.1-runtime-stretch-slim-arm32v7 11 | WORKDIR /app 12 | COPY --from=build-env /app/out ./ 13 | 14 | RUN useradd -ms /bin/bash moduleuser 15 | USER moduleuser 16 | 17 | ENTRYPOINT ["dotnet", "TypeEdgeModuleVsCode.dll"] -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Dockerfile.windows-amd64: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1-sdk AS build-env 2 | WORKDIR /app 3 | 4 | COPY *.csproj ./ 5 | RUN dotnet restore 6 | 7 | COPY . ./ 8 | RUN dotnet publish -c Release -o out 9 | 10 | FROM microsoft/dotnet:2.1-runtime-nanoserver-1803 11 | WORKDIR /app 12 | COPY --from=build-env /app/out ./ 13 | ENTRYPOINT ["dotnet", "TypeEdgeModuleVsCode.dll"] -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.Azure.TypeEdge; 3 | 4 | namespace TypeEdgeModuleVsCode 5 | { 6 | internal class Program 7 | { 8 | public static async Task Main(string[] args) 9 | { 10 | await Startup.DockerEntryPoint(args); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Shared/ITypeEdgeModuleVsCode.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Attributes; 2 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 3 | using Microsoft.Azure.TypeEdge.Twins; 4 | using Shared.Messages; 5 | using Shared.Twins; 6 | 7 | namespace Shared 8 | { 9 | [TypeModule] 10 | public interface ITypeEdgeModuleVsCode 11 | { 12 | Output Output { get; set; } 13 | ModuleTwin Twin { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Shared/Messages/TypeEdgeModuleVsCodeOutput.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using Microsoft.Azure.TypeEdge.Modules.Messages; 4 | using Newtonsoft.Json; 5 | 6 | namespace Shared.Messages 7 | { 8 | public class TypeEdgeModuleVsCodeOutput : IEdgeMessage 9 | { 10 | public string Data { get; set; } 11 | public IDictionary Properties { get; set; } 12 | 13 | public byte[] GetBytes() 14 | { 15 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this)); 16 | } 17 | 18 | public void SetBytes(byte[] bytes) 19 | { 20 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes)); 21 | Properties = obj.Properties; 22 | 23 | Data = obj.Data; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/Shared/Twins/TypeEdgeModuleVsCodeTwin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.TypeEdge.Twins; 2 | 3 | namespace Shared.Twins 4 | { 5 | public class TypeEdgeModuleVsCodeTwin : TypeTwin 6 | { 7 | public int Threshold { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/TypeEdgeModuleVsCode.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Microsoft.Azure.TypeEdge.Enums; 4 | using Microsoft.Azure.TypeEdge.Modules; 5 | using Microsoft.Azure.TypeEdge.Modules.Endpoints; 6 | using Microsoft.Azure.TypeEdge.Twins; 7 | using Shared; 8 | using Shared.Messages; 9 | using Shared.Twins; 10 | 11 | namespace Modules 12 | { 13 | public class TypeEdgeModuleVsCode : TypeModule, ITypeEdgeModuleVsCode 14 | { 15 | public Output Output { get; set; } 16 | public ModuleTwin Twin { get; set; } 17 | 18 | public override async Task RunAsync(CancellationToken cancellationToken) 19 | { 20 | while (!cancellationToken.IsCancellationRequested) 21 | { 22 | await Output.PublishAsync(new TypeEdgeModuleVsCodeOutput()); 23 | await Task.Delay(1000, cancellationToken); 24 | } 25 | 26 | return ExecutionResult.Ok; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/TypeEdgeModuleVsCode.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Templates/TypeEdgeModuleVsCode/module.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema-version": "0.0.1", 3 | "description": "", 4 | "image": { 5 | "repository": "repositoryName", 6 | "tag": { 7 | "version": "0.0.1", 8 | "platforms": { 9 | "amd64": "./Dockerfile.amd64", 10 | "amd64.debug": "./Dockerfile.amd64.debug", 11 | "arm32v7": "./Dockerfile.arm32v7", 12 | "windows-amd64": "./Dockerfile.windows-amd64" 13 | } 14 | }, 15 | "buildOptions": [] 16 | }, 17 | "language": "csharp" 18 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeServiceProxy.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Azure.TypeEdge.Templates.ServiceProxy 5 | Creates a new Azure IoT Edge Service Proxy project for TypeEdge, a strongly typed Azure IoT Edge framework 6 | $version$ 7 | Microsoft 8 | https://aka.ms/TypeEdge 9 | © Microsoft Corporation. All rights reserved. 10 | https://github.com/Azure/TypeEdge/blob/master/LICENSE 11 | Microsoft;Azure;IoT;Edge;TypeEdge 12 | https://github.com/Azure/TypeEdge/blob/master/Templates/favicon.ico 13 | true 14 | en-US 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Templates/TypeEdgeServiceProxy/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "TypeEdge", "Azure", "IoT", "Edge", "Service", "Proxy" ], 5 | "name": "Type Edge Service Proxy", 6 | "identity": "Microsoft.Azure.TypeEdge.Templates.ServiceProxy.CSharp", 7 | "groupIdentity": "TypeEdgeServiceProxy", 8 | "shortName": "typeedgeserviceproxy", 9 | "tags": { 10 | "language": "C#", 11 | "type": "project" 12 | }, 13 | "sourceName": "TypeEdgeServiceProxy", 14 | "preferNameDirectory": true 15 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeServiceProxy/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Azure.TypeEdge.Proxy; 3 | using Microsoft.Extensions.Configuration; 4 | 5 | namespace TypeEdgeProxy 6 | { 7 | internal class Program 8 | { 9 | private static void Main(string[] args) 10 | { 11 | Console.WriteLine("Press to start.."); 12 | Console.ReadLine(); 13 | 14 | var configuration = new ConfigurationBuilder() 15 | .AddJsonFile("appSettings.json") 16 | .AddEnvironmentVariables() 17 | .Build(); 18 | 19 | ProxyFactory.Configure(configuration["IotHubConnectionString"], 20 | configuration["DeviceId"]); 21 | 22 | //TODO: Get your module proxies by contract 23 | //var result = ProxyFactory.GetModuleProxy().ResetSensor(10); 24 | 25 | Console.WriteLine("Press to exit.."); 26 | Console.ReadLine(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Templates/TypeEdgeServiceProxy/TypeEdgeServiceProxy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | latest 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Templates/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Templates/favicon.ico -------------------------------------------------------------------------------- /Templates/list-of-excluded-files.txt: -------------------------------------------------------------------------------- 1 | \obj\ 2 | \bin\ 3 | \.vs\ -------------------------------------------------------------------------------- /Templates/nuget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/Templates/nuget.exe -------------------------------------------------------------------------------- /Templates/nugetBuild.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | set version=%1 3 | rd /s /q build 4 | mkdir build 5 | cd build 6 | mkdir TypeEdgeEmulator 7 | cd TypeEdgeEmulator 8 | mkdir content 9 | cd .. 10 | mkdir TypeEdgeModuleVsCode 11 | cd TypeEdgeModuleVsCode 12 | mkdir content 13 | cd .. 14 | mkdir TypeEdgeApplication 15 | cd TypeEdgeApplication 16 | mkdir content 17 | cd .. 18 | mkdir TypeEdgeModule 19 | cd TypeEdgeModule 20 | mkdir content 21 | cd .. 22 | mkdir TypeEdgeServiceProxy 23 | cd TypeEdgeServiceProxy 24 | mkdir content 25 | cd .. 26 | cd .. 27 | copy TypeEdgeEmulator.nuspec build\TypeEdgeEmulator 28 | copy TypeEdgeModuleVsCode.nuspec build\TypeEdgeModuleVsCode 29 | copy TypeEdgeApplication.nuspec build\TypeEdgeApplication 30 | copy TypeEdgeModule.nuspec build\TypeEdgeModule 31 | copy TypeEdgeServiceProxy.nuspec build\TypeEdgeServiceProxy 32 | 33 | dotnet build TypeEdgeEmulator 34 | dotnet build TypeEdgeModuleVsCode 35 | dotnet build TypeEdgeApplication\TypeEdgeApplication.sln 36 | dotnet build TypeEdgeModule 37 | dotnet build TypeEdgeServiceProxy 38 | 39 | dotnet nuget locals http-cache --clear 40 | dotnet new --debug:reinit 41 | 42 | dotnet new --install TypeEdgeModule 43 | dotnet new --install TypeEdgeApplication 44 | dotnet new --install TypeEdgeServiceProxy 45 | dotnet new --install TypeEdgeEmulator 46 | dotnet new --install TypeEdgeModuleVsCode 47 | 48 | dotnet clean TypeEdgeModule 49 | dotnet clean TypeEdgeApplication 50 | dotnet clean TypeEdgeServiceProxy 51 | dotnet clean TypeEdgeModuleVsCode 52 | dotnet clean TypeEdgeEmulator 53 | 54 | xcopy TypeEdgeModuleVsCode build\TypeEdgeModuleVsCode\content /s /e /EXCLUDE:list-of-excluded-files.txt 55 | xcopy TypeEdgeEmulator build\TypeEdgeEmulator\content /s /e /EXCLUDE:list-of-excluded-files.txt 56 | xcopy TypeEdgeServiceProxy build\TypeEdgeServiceProxy\content /s /e /EXCLUDE:list-of-excluded-files.txt 57 | xcopy TypeEdgeModule build\TypeEdgeModule\content /s /e /EXCLUDE:list-of-excluded-files.txt 58 | xcopy TypeEdgeApplication build\TypeEdgeApplication\content /s /e /EXCLUDE:list-of-excluded-files.txt 59 | 60 | nuget.exe pack build\TypeEdgeEmulator -Version %version% 61 | nuget.exe pack build\TypeEdgeModuleVsCode -Version %version% 62 | nuget.exe pack build\TypeEdgeServiceProxy -Version %version% 63 | nuget.exe pack build\TypeEdgeModule -Version %version% 64 | nuget.exe pack build\TypeEdgeApplication -Version %version% 65 | 66 | move /Y *.nupkg ..\..\TypeEdgeNuGets 67 | 68 | REM nuget.exe push ..\..\TypeEdgeNuGets\*%version%.nupkg -ApiKey VSTS 69 | 70 | REM dotnet nuget locals http-cache --clear 71 | REM dotnet new --debug:reinit 72 | 73 | REM dotnet new -i TypeEdge.Application::* 74 | REM dotnet new -i TypeEdge.ML::* 75 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # .NET Desktop 2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net 5 | 6 | pool: 7 | vmImage: 'VS2017-Win2016' 8 | 9 | variables: 10 | solution: 'Microsoft.Azure.TypeEdge.sln' 11 | buildPlatform: 'Any CPU' 12 | buildConfiguration: 'Release' 13 | 14 | steps: 15 | - task: NuGetToolInstaller@0 16 | 17 | - task: NuGetCommand@2 18 | inputs: 19 | restoreSolution: '$(solution)' 20 | 21 | - task: VSBuild@1 22 | inputs: 23 | solution: '$(solution)' 24 | platform: '$(buildPlatform)' 25 | configuration: '$(buildConfiguration)' 26 | 27 | # Azure Key Vault 28 | # Download Azure Key Vault Secrets 29 | - task: AzureKeyVault@1 30 | inputs: 31 | azureSubscription: 'SpyrosgKeyVaultConnection' 32 | keyVaultName: 'TypeEdgePipeline' 33 | secretsFilter: '*' 34 | 35 | - task: VSTest@2 36 | displayName: 'Run Unit Tests' 37 | inputs: 38 | testAssemblyVer2: | 39 | **\$(BuildConfiguration)\*test*.dll 40 | **\$(BuildConfiguration)\**\*test*.dll 41 | !**\*Microsoft.VisualStudio.TestPlatform* 42 | !**\obj\** 43 | vstestLocationMethod: 'location' 44 | vstestLocation: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\TestPlatform\' 45 | codeCoverageEnabled: True 46 | otherConsoleOptions: '/platform:x64 /Framework:.NETCoreApp,Version=v2.1 /logger:console;verbosity="normal" ' 47 | platform: '$(buildPlatform)' 48 | configuration: '$(buildConfiguration)' 49 | 50 | # - task: VSTest@2 51 | # inputs: 52 | # platform: '$(buildPlatform)' 53 | # configuration: '$(buildConfiguration)' 54 | 55 | -------------------------------------------------------------------------------- /images/IoTEdge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/IoTEdge.png -------------------------------------------------------------------------------- /images/hqdefault.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/hqdefault.jpg -------------------------------------------------------------------------------- /images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/image.png -------------------------------------------------------------------------------- /images/incontainer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/incontainer.png -------------------------------------------------------------------------------- /images/iothubowner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/iothubowner.png -------------------------------------------------------------------------------- /images/maxresdefault.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/maxresdefault.jpg -------------------------------------------------------------------------------- /images/messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/messages.png -------------------------------------------------------------------------------- /images/solution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/solution.png -------------------------------------------------------------------------------- /images/vstsSecurity.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/vstsSecurity.jpg -------------------------------------------------------------------------------- /images/vstsSecurity2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/images/vstsSecurity2.jpg -------------------------------------------------------------------------------- /nuget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/TypeEdge/156023ce3543e423227f8ed309f46e8dd3dc5f81/nuget.exe --------------------------------------------------------------------------------