├── .azurecomponent └── azureconfig.json ├── .gitignore ├── AirTrafficSim ├── AirTrafficSim.sln └── AirTrafficSim │ ├── AirTrafficSim.csproj │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ ├── AppIcon.scale-100.png │ ├── LargeTile.scale-100.png │ ├── MediumTile.scale-100.png │ ├── SmallTile.scale-100.png │ ├── SplashScreen.scale-100.png │ ├── StoreLogo.scale-100.png │ └── WideTile.scale-100.png │ ├── Classes │ ├── FilteredPlaneStatusInfo.cs │ ├── FlightAnalysisData.cs │ ├── FlightInfo.cs │ ├── NewFlightInfo.cs │ └── PlaneStatusInfo.cs │ ├── Common │ ├── CoreConstants.cs │ ├── CoreConverters.cs │ ├── CoreEnums.cs │ ├── ObservableBase.cs │ └── RelayCommand.cs │ ├── Controls │ ├── ActivePlaneControl.xaml │ └── ActivePlaneControl.xaml.cs │ ├── Extensions │ ├── CompassExtensions.cs │ ├── ControlExtensions.cs │ └── ListExtensions.cs │ ├── Helpers │ ├── ControlHelper.cs │ ├── MapHelper.cs │ ├── ThemeHelper.cs │ └── TimerHelper.cs │ ├── Images │ ├── AirTrafficSim_back.jpg │ ├── FlySim_back.jpg │ ├── PlaneViewBorder.png │ ├── PlaneViewHorizon.png │ ├── dashedarrow.png │ └── planeimage.png │ ├── Listeners │ ├── AirTrafficListener.cs │ └── FlightActivityListener.cs │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Models │ ├── ActivePlaneInformation.cs │ ├── FlightInformation.cs │ └── PlaneStatusInformation.cs │ ├── Package.appxmanifest │ ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml │ └── ViewModels │ └── MainViewModel.cs ├── FlySim.code-workspace ├── FlySim ├── FlySim.sln └── FlySim │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ ├── AppIcon.scale-100.png │ ├── LargeTile.scale-100.png │ ├── MediumTile.scale-100.png │ ├── SmallTile.scale-100.png │ ├── SplashScreen.scale-100.png │ ├── StoreLogo.scale-100.png │ └── WideTile.scale-100.png │ ├── Classes │ ├── FilteredPlaneStatusInfo.cs │ ├── FlightInfo.cs │ ├── NewFlightInfo.cs │ └── PlaneStatusInfo.cs │ ├── Common │ ├── CoreConstants.cs │ ├── CoreConverters.cs │ ├── CoreEnums.cs │ ├── ObservableBase.cs │ └── RelayCommand.cs │ ├── Controls │ ├── ActivePlaneControl.xaml │ └── ActivePlaneControl.xaml.cs │ ├── Extensions │ ├── ActivityExtensions.cs │ ├── CompassExtensions.cs │ └── ControlExtensions.cs │ ├── FlySim.csproj │ ├── Helpers │ ├── ControlHelper.cs │ ├── MapHelper.cs │ ├── StorageHelper.cs │ ├── ThemeHelper.cs │ ├── TimerHelper.cs │ └── TranslationHelper.cs │ ├── Images │ ├── FlySim_back.jpg │ ├── PlaneViewBorder.png │ ├── PlaneViewHorizon.png │ ├── PlaneViewHorizon_front.png │ ├── dashedarrow.png │ ├── horizon_border.png │ └── planeimage.png │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Models │ ├── ActivePlaneInformation.cs │ ├── FlightInformation.cs │ ├── LanguageInformation.cs │ └── PlaneStatusInformation.cs │ ├── Package.appxmanifest │ ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml │ └── ViewModels │ └── MainViewModel.cs ├── FlySimEmbedded ├── .iotworkbenchproject ├── .vscode │ ├── arduino.json │ └── settings.json ├── FlySim.ino ├── config.h ├── utility.cpp └── utility.h ├── FlySimFunctions ├── .gitignore ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── FlySimIoTFlightData.cs ├── Functions.csproj └── host.json ├── FlySimTest ├── FlySimTest.sln └── FlySimTest │ ├── App.config │ ├── FlySimTest.csproj │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ └── packages.config ├── HOL 1 ├── HOL 1 - MXChip.md └── Images │ ├── architecture.png │ ├── atc-app.png │ ├── cable-and-chip.png │ ├── chip-in-flight.png │ ├── iot-workbench-cloud-provision.png │ ├── iot-workbench-connection-done.png │ ├── iot-workbench-device-settings.png │ ├── iot-workbench-device-string1.png │ ├── iot-workbench-device-upload.png │ ├── iot-workbench-examples-board.png │ ├── iot-workbench-examples-cmd.png │ ├── iot-workbench-examples.png │ ├── open-iot-hub.png │ ├── open-resource-group.png │ ├── open-workspace.png │ ├── portal-device-explorer.png │ ├── portal-enter-device-login.png │ ├── portal-hub-usage.png │ ├── view-ssid-and-ip.png │ ├── vs-azure-login.png │ ├── vs-board-manager.png │ ├── vs-check-board-installed.png │ ├── vs-click-baud-rate.png │ ├── vs-click-connect.png │ ├── vs-enter-display-name.png │ ├── vs-getting-started.png │ ├── vs-install-json.png │ ├── vs-viewing-com-data.png │ └── vscode-open-example.png ├── HOL 2 ├── HOL 2 - Functions and Event Hubs.md └── Images │ ├── add-event-hub.png │ ├── app-ascending.png │ ├── app-in-flight.png │ ├── app-turning.png │ ├── chip-in-flight.png │ ├── create-event-hub.png │ ├── create-namespace.png │ ├── event_hub_instance.png │ ├── flysim-event-hub.png │ ├── function_settings.png │ ├── iot-workbench-cloud-deploy.png │ ├── new-event-hub.png │ ├── open-event-hub-2.png │ ├── open-event-hub.png │ ├── open-function-app.png │ ├── open-iot-hub.png │ ├── open-resource-group.png │ ├── portal-click-event-hub-policy.png │ ├── portal-click-iot-endpoints.png │ ├── portal-copy-event-hub-sas.png │ ├── portal-function-running.png │ ├── portal-save-new-event-hub.png │ ├── resolve_dependency.png │ ├── restart-function-app.png │ └── vs-add-project.png ├── HOL 3 ├── HOL 3 - Stream Analytics.md ├── Images │ ├── add-event-hub.png │ ├── add-input-1.png │ ├── add-input-2.png │ ├── add-output-1.png │ ├── add-output-2.png │ ├── add-query.png │ ├── app-environment-labels.png │ ├── confirm-input.png │ ├── confirm-output.png │ ├── copy-connection-string.png │ ├── create-gist.png │ ├── create-input-hub.png │ ├── create-input.png │ ├── create-namespace.png │ ├── create-output-hub.png │ ├── create-output.png │ ├── create-stream-analytics-job.png │ ├── event-hubs.png │ ├── new-event-hub.png │ ├── new-stream-analytics-job.png │ ├── open-namespace.png │ ├── open-resource-group.png │ ├── open-shared-access-key.png │ ├── open-stream-analytics-job.png │ ├── query-results.png │ ├── start-stream-analytics-job-1.png │ ├── start-stream-analytics-job-2.png │ ├── test-query.png │ ├── upload-test-data-1.png │ └── upload-test-data-2.png └── resources │ └── flysim-2-in-proximity.json ├── HOL 4 ├── HOL 4 - Putting It All Together.md └── Images │ ├── app-in-flight.png │ ├── architecture.png │ ├── atc-app.png │ ├── chip-warning.png │ ├── copy-api-key.png │ ├── copy-from-gist.png │ ├── function_settings.png │ ├── modified-function-1.png │ ├── modified-function-2.png │ ├── new-application-setting.png │ ├── new-translator-text-1.png │ ├── new-translator-text-2.png │ ├── new-translator-text-3.png │ ├── new-translator-text-4.png │ ├── open-api-key.png │ ├── open-application-settings.png │ ├── open-shared-access-policies.png │ ├── portal-iot-hub-endpoint.png │ ├── restart-function-app.png │ ├── select-language.png │ ├── two-approaching.png │ ├── two-at-risk.png │ └── warning-messages.png ├── LICENSE └── README.md /.azurecomponent/azureconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentConfigs": [ 3 | { 4 | "id": "69873a09-475b-8076-6ec4-4bd8940e9e20", 5 | "folder": "", 6 | "name": "", 7 | "dependencies": [], 8 | "type": "IoTHub" 9 | }, 10 | { 11 | "id": "28003ce8-f2f6-d28a-0647-ded467e7ac7c", 12 | "folder": "FlySimFunctions", 13 | "name": "", 14 | "dependencies": [ 15 | { 16 | "id": "69873a09-475b-8076-6ec4-4bd8940e9e20", 17 | "type": 1 18 | } 19 | ], 20 | "type": "AzureFunctions", 21 | "componentInfo": { 22 | "values": { 23 | "functionLanguage": "C#" 24 | } 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | 290 | # Build folder 291 | .build/ -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AirTrafficSim", "AirTrafficSim\AirTrafficSim.csproj", "{8CBAC47A-C7B5-4C8B-8296-34450A586568}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM = Release|ARM 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|ARM.ActiveCfg = Debug|ARM 19 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|ARM.Build.0 = Debug|ARM 20 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|ARM.Deploy.0 = Debug|ARM 21 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x64.ActiveCfg = Debug|x64 22 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x64.Build.0 = Debug|x64 23 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x64.Deploy.0 = Debug|x64 24 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x86.ActiveCfg = Debug|x86 25 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x86.Build.0 = Debug|x86 26 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Debug|x86.Deploy.0 = Debug|x86 27 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|ARM.ActiveCfg = Release|ARM 28 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|ARM.Build.0 = Release|ARM 29 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|ARM.Deploy.0 = Release|ARM 30 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x64.ActiveCfg = Release|x64 31 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x64.Build.0 = Release|x64 32 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x64.Deploy.0 = Release|x64 33 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x86.ActiveCfg = Release|x86 34 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x86.Build.0 = Release|x86 35 | {8CBAC47A-C7B5-4C8B-8296-34450A586568}.Release|x86.Deploy.0 = Release|x86 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {DD8B2566-3F31-4DBD-B5DE-7BA88D939940} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/App.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 11 | #FFEBEBEB 12 | #FF1A1A1A 13 | #FF000000 14 | #FF555555 15 | #66000000 16 | 17 | #FFB8D432 18 | #FFD90000 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.ApplicationModel; 7 | using Windows.ApplicationModel.Activation; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Controls.Primitives; 13 | using Windows.UI.Xaml.Data; 14 | using Windows.UI.Xaml.Input; 15 | using Windows.UI.Xaml.Media; 16 | using Windows.UI.Xaml.Navigation; 17 | 18 | namespace AirTrafficSim 19 | { 20 | /// 21 | /// Provides application-specific behavior to supplement the default Application class. 22 | /// 23 | sealed partial class App : Application 24 | { 25 | public static MainViewModel ViewModel { get; set; } 26 | 27 | /// 28 | /// Initializes the singleton application object. This is the first line of authored code 29 | /// executed, and as such is the logical equivalent of main() or WinMain(). 30 | /// 31 | public App() 32 | { 33 | this.InitializeComponent(); 34 | this.Suspending += OnSuspending; 35 | } 36 | 37 | /// 38 | /// Invoked when the application is launched normally by the end user. Other entry points 39 | /// will be used such as when the application is launched to open a specific file. 40 | /// 41 | /// Details about the launch request and process. 42 | protected override void OnLaunched(LaunchActivatedEventArgs e) 43 | { 44 | Helpers.ThemeHelper.ApplyTitleSyling(); 45 | 46 | Frame rootFrame = Window.Current.Content as Frame; 47 | 48 | // Do not repeat app initialization when the Window already has content, 49 | // just ensure that the window is active 50 | if (rootFrame == null) 51 | { 52 | // Create a Frame to act as the navigation context and navigate to the first page 53 | rootFrame = new Frame(); 54 | 55 | rootFrame.NavigationFailed += OnNavigationFailed; 56 | 57 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 58 | { 59 | //TODO: Load state from previously suspended application 60 | } 61 | 62 | // Place the frame in the current Window 63 | Window.Current.Content = rootFrame; 64 | } 65 | 66 | if (e.PrelaunchActivated == false) 67 | { 68 | if (rootFrame.Content == null) 69 | { 70 | // When the navigation stack isn't restored navigate to the first page, 71 | // configuring the new page by passing required information as a navigation 72 | // parameter 73 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 74 | } 75 | // Ensure the current window is active 76 | Window.Current.Activate(); 77 | } 78 | } 79 | 80 | /// 81 | /// Invoked when Navigation to a certain page fails 82 | /// 83 | /// The Frame which failed navigation 84 | /// Details about the navigation failure 85 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 86 | { 87 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 88 | } 89 | 90 | /// 91 | /// Invoked when application execution is being suspended. Application state is saved 92 | /// without knowing whether the application will be terminated or resumed with the contents 93 | /// of memory still intact. 94 | /// 95 | /// The source of the suspend request. 96 | /// Details about the suspend request. 97 | private void OnSuspending(object sender, SuspendingEventArgs e) 98 | { 99 | var deferral = e.SuspendingOperation.GetDeferral(); 100 | //TODO: Save application state and stop any background activity 101 | deferral.Complete(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/AppIcon.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/AppIcon.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/MediumTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/MediumTile.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Assets/WideTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Assets/WideTile.scale-100.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Classes/FilteredPlaneStatusInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class FilteredPlaneStatusInfo 10 | { 11 | public string DisplayName { get; set; } 12 | public double Distance { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Classes/FlightAnalysisData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class FlightAnalysisData 10 | { 11 | public string Label { get; set; } 12 | public int Value { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Classes/FlightInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class FlightInfo 10 | { 11 | public string deviceId { get; set; } 12 | public int messageId { get; set; } 13 | public string timestamp { get; set; } 14 | public float x { get; set; } 15 | public float y { get; set; } 16 | public float z { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Classes/NewFlightInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class NewFlightInfo 10 | { 11 | public string deviceId { get; set; } 12 | public double airspeed { get; set; } 13 | public double heading { get; set; } 14 | public double altitude { get; set; } 15 | public double latitude { get; set; } 16 | public double longitude { get; set; } 17 | public double pitch { get; set; } 18 | public double roll { get; set; } 19 | public double temperature { get; set; } 20 | public double humidity { get; set; } 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Classes/PlaneStatusInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class PlaneStatusInfo 10 | { 11 | public string plane1 { get; set; } 12 | public string plane2 { get; set; } 13 | public string distance { get; set; } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Common/CoreConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim.Common 8 | { 9 | public class CoreConstants 10 | { 11 | public const string SharedEventHubEndpoint = "SHARED_EVENT_HUB_ENDPOINT"; 12 | public const string SharedFlightActivityHubName = "flysim-shared-input-hub"; 13 | public const string SharedAirTrafficHubName = "flysim-shared-output-hub"; 14 | 15 | public static string MapServiceToken = "HvD1WpB9MyrWv30BaZCP~-DZBRQGBV2rbPRfQqjBZUQ~AkD5MLW_Sj2_nCY3sesLC3Ldua1j84cVqhnL2Pl5MpY1lbLLnVrmmHoqAVjjvbhO"; 16 | public const double AreaRadius = 80467.0; 17 | public const double AtRiskThreshold = 10560.0; 18 | 19 | public static Windows.Devices.Geolocation.BasicGeoposition DefaultStartingLocation = new Windows.Devices.Geolocation.BasicGeoposition() 20 | { 21 | Latitude = 37.242, 22 | Longitude = -115.8191, 23 | }; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Common/CoreConverters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI; 7 | using Windows.UI.Xaml; 8 | using Windows.UI.Xaml.Data; 9 | using Windows.UI.Xaml.Media; 10 | 11 | namespace AirTrafficSim.Common 12 | { 13 | public sealed class BooleanToFalseConverter : IValueConverter 14 | { 15 | public object Convert(object value, Type targetType, object parameter, string language) 16 | { 17 | return !(bool)value; 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, string language) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | 26 | public sealed class StatusToFillConverter : IValueConverter 27 | { 28 | public object Convert(object value, Type targetType, object parameter, string language) 29 | { 30 | var flightStatus = (FlightStatus)value; 31 | 32 | if (flightStatus == FlightStatus.Inactive) 33 | { 34 | return new SolidColorBrush(Colors.Transparent); 35 | } 36 | else 37 | { 38 | return (flightStatus == FlightStatus.Ok) ? App.Current.Resources["AppStatusOkBrush"] as SolidColorBrush : App.Current.Resources["AppStatusAtRiskBrush"] as SolidColorBrush; 39 | } 40 | 41 | } 42 | 43 | public object ConvertBack(object value, Type targetType, object parameter, string language) 44 | { 45 | throw new NotImplementedException(); 46 | } 47 | } 48 | 49 | public sealed class HasContentToVisibilityConverter : IValueConverter 50 | { 51 | public object Convert(object value, Type targetType, object parameter, string language) 52 | { 53 | return string.IsNullOrEmpty(((string)value).Trim()) ? Visibility.Collapsed : Visibility.Visible; 54 | } 55 | 56 | public object ConvertBack(object value, Type targetType, object parameter, string language) 57 | { 58 | throw new NotImplementedException(); 59 | } 60 | } 61 | 62 | public sealed class ActiveLabelConverter : IValueConverter 63 | { 64 | public object Convert(object value, Type targetType, object parameter, string language) 65 | { 66 | int labelValue = System.Convert.ToInt16(value); 67 | 68 | return labelValue.ToString("00#"); 69 | } 70 | 71 | public object ConvertBack(object value, Type targetType, object parameter, string language) 72 | { 73 | throw new NotImplementedException(); 74 | } 75 | } 76 | 77 | public sealed class TemperatureLabelConverter : IValueConverter 78 | { 79 | public object Convert(object value, Type targetType, object parameter, string language) 80 | { 81 | double temperature = System.Convert.ToDouble(value); 82 | 83 | return (temperature == 0) ? "" : ((temperature * 9 / 5) + 32).ToString("N1") + "° F"; 84 | } 85 | 86 | public object ConvertBack(object value, Type targetType, object parameter, string language) 87 | { 88 | throw new NotImplementedException(); 89 | } 90 | } 91 | 92 | public sealed class LocalTimeConverter : IValueConverter 93 | { 94 | public object Convert(object value, Type targetType, object parameter, string language) 95 | { 96 | var time = (DateTime)value; 97 | 98 | return (time.ToLocalTime().ToString("hh:mm:ss")); 99 | } 100 | 101 | public object ConvertBack(object value, Type targetType, object parameter, string language) 102 | { 103 | throw new NotImplementedException(); 104 | } 105 | } 106 | 107 | public class NumberDisplayLabelConverter : IValueConverter 108 | { 109 | public object Convert(object value, Type targetType, object parameter, string language) 110 | { 111 | return $"{System.Convert.ToDouble(value).ToString("N0")} ft"; 112 | } 113 | 114 | public object ConvertBack(object value, Type targetType, object parameter, string language) 115 | { 116 | throw new NotImplementedException(); 117 | } 118 | } 119 | 120 | public class MilesDisplayLabelConverter : IValueConverter 121 | { 122 | public object Convert(object value, Type targetType, object parameter, string language) 123 | { 124 | double distance = System.Convert.ToDouble(value); 125 | 126 | return (distance == 0.0) ? "--" : $"{System.Convert.ToDouble(value).ToString("N0")} miles"; 127 | } 128 | 129 | public object ConvertBack(object value, Type targetType, object parameter, string language) 130 | { 131 | throw new NotImplementedException(); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Common/CoreEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim.Common 8 | { 9 | public enum CompassDirection 10 | { 11 | North = 0, 12 | NorthEast = 1, 13 | East = 2, 14 | SouthEast = 3, 15 | South = 4, 16 | SouthWest = 5, 17 | West = 6, 18 | NorthWest = 7 19 | } 20 | 21 | public enum FlightStatus 22 | { 23 | Ok, 24 | Warning, 25 | AtRisk, 26 | Inactive, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Common/ObservableBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.CompilerServices; 4 | using Windows.UI.Xaml.Data; 5 | 6 | namespace AirTrafficSim.Common 7 | { 8 | /// 9 | /// Implementation of to simplify models. 10 | /// 11 | [Windows.Foundation.Metadata.WebHostHidden] 12 | public abstract class ObservableBase : INotifyPropertyChanged 13 | { 14 | /// 15 | /// Multicast event for property change notifications. 16 | /// 17 | public event PropertyChangedEventHandler PropertyChanged; 18 | 19 | /// 20 | /// Checks if a property already matches a desired value. Sets the property and 21 | /// notifies listeners only when necessary. 22 | /// 23 | /// Type of the property. 24 | /// Reference to a property with both getter and setter. 25 | /// Desired value for the property. 26 | /// Name of the property used to notify listeners. This 27 | /// value is optional and can be provided automatically when invoked from compilers that 28 | /// support CallerMemberName. 29 | /// True if the value was changed, false if the existing value matched the 30 | /// desired value. 31 | protected bool SetProperty(ref T storage, T value, [CallerMemberName] String propertyName = null) 32 | { 33 | if (object.Equals(storage, value)) return false; 34 | 35 | storage = value; 36 | this.OnPropertyChanged(propertyName); 37 | return true; 38 | } 39 | 40 | /// 41 | /// Notifies listeners that a property value has changed. 42 | /// 43 | /// Name of the property used to notify listeners. This 44 | /// value is optional and can be provided automatically when invoked from compilers 45 | /// that support . 46 | protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 47 | { 48 | var eventHandler = this.PropertyChanged; 49 | if (eventHandler != null) 50 | { 51 | try 52 | { 53 | eventHandler(this, new PropertyChangedEventArgs(propertyName)); 54 | } 55 | catch 56 | { 57 | } 58 | 59 | 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Common/RelayCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace AirTrafficSim.Common 5 | { 6 | public class RelayCommand : ICommand 7 | { 8 | private readonly Action _execute; 9 | private readonly Func _canExecute; 10 | 11 | public event EventHandler CanExecuteChanged; 12 | public RelayCommand(Action execute) : this(execute, null) { } 13 | 14 | public RelayCommand(Action execute, Func canExecute) 15 | { 16 | this._execute = execute ?? throw new ArgumentNullException("execute"); 17 | this._canExecute = canExecute; 18 | } 19 | 20 | public bool CanExecute(object parameter) => _canExecute == null || _canExecute(); 21 | public void Execute(object parameter) => _execute(); 22 | public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); 23 | } 24 | 25 | public class RelayCommand : ICommand 26 | { 27 | private readonly Action _execute; 28 | private readonly Func _canExecute; 29 | 30 | public event EventHandler CanExecuteChanged; 31 | public RelayCommand(Action execute) : this(execute, null) { } 32 | 33 | public RelayCommand(Action execute, Func canExecute) 34 | { 35 | this._execute = execute ?? throw new ArgumentNullException("execute"); 36 | this._canExecute = canExecute; 37 | } 38 | 39 | public bool CanExecute(object parameter) => _canExecute == null || _canExecute((T)parameter); 40 | public void Execute(object parameter) => _execute((T)parameter); 41 | public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Controls/ActivePlaneControl.xaml: -------------------------------------------------------------------------------- 1 |  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 | 36 | 37 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Controls/ActivePlaneControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.Foundation; 7 | using Windows.Foundation.Collections; 8 | using Windows.UI.Xaml; 9 | using Windows.UI.Xaml.Controls; 10 | using Windows.UI.Xaml.Controls.Primitives; 11 | using Windows.UI.Xaml.Data; 12 | using Windows.UI.Xaml.Input; 13 | using Windows.UI.Xaml.Media; 14 | using Windows.UI.Xaml.Navigation; 15 | 16 | // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 17 | 18 | namespace AirTrafficSim.Controls 19 | { 20 | public sealed partial class ActivePlaneControl : UserControl 21 | { 22 | public string PilotId 23 | { 24 | get { return base.GetValue(PilotIdProperty) as string; } 25 | set { base.SetValue(PilotIdProperty, value); } 26 | } 27 | 28 | public static readonly DependencyProperty PilotIdProperty = DependencyProperty.Register("PilotId", typeof(string), typeof(ActivePlaneControl), null); 29 | 30 | public Visibility ZoomDeepLevel 31 | { 32 | get { return (Visibility)base.GetValue(ZoomDeepLevelProperty); } 33 | set { base.SetValue(ZoomDeepLevelProperty, value); } 34 | } 35 | 36 | public static readonly DependencyProperty ZoomDeepLevelProperty = DependencyProperty.Register("ZoomDeepLevel", typeof(Visibility), typeof(ActivePlaneControl), null); 37 | 38 | 39 | public ActivePlaneControl() 40 | { 41 | this.InitializeComponent(); 42 | this.Loaded += ActivePlaneControl_Loaded; 43 | } 44 | 45 | private void ActivePlaneControl_Loaded(object sender, RoutedEventArgs e) 46 | { 47 | //this.DataContext = App.ViewModel; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Extensions/CompassExtensions.cs: -------------------------------------------------------------------------------- 1 | using AirTrafficSim.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace AirTrafficSim 9 | { 10 | public static class DirectionExtensions 11 | { 12 | private static readonly Dictionary 13 | mapping = new Dictionary 14 | { 15 | { CompassDirection.North, "N" }, 16 | { CompassDirection.NorthEast, "NE" }, 17 | { CompassDirection.East, "E" }, 18 | { CompassDirection.SouthEast, "SE" }, 19 | { CompassDirection.South, "S" }, 20 | { CompassDirection.SouthWest, "SW" }, 21 | { CompassDirection.West, "W" }, 22 | { CompassDirection.NorthWest, "NW" } 23 | }; 24 | 25 | public static CompassDirection AsDirectionLabel(this double heading) 26 | { 27 | var adjusted = (heading + 22) % 360; 28 | var sector = adjusted / 45; 29 | return (CompassDirection)sector; 30 | } 31 | 32 | 33 | public static string GetSuffix(this CompassDirection direction) 34 | { 35 | return mapping[direction]; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Extensions/ControlExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI; 7 | using Windows.UI.Text; 8 | using Windows.UI.Xaml.Controls; 9 | using Windows.UI.Xaml.Data; 10 | using Windows.UI.Xaml.Media; 11 | 12 | namespace AirTrafficSim 13 | { 14 | public static class ControlExtensions 15 | { 16 | public static void AddMapOverlay(this Grid grid) 17 | { 18 | var border = new Border() 19 | { 20 | IsHitTestVisible = false, 21 | Background = App.Current.Resources["AppAccentBrush"] as SolidColorBrush, 22 | Opacity = 0.4 23 | }; 24 | 25 | grid.Children.Add(Helpers.ControlHelper.GenerateMapGrid()); 26 | grid.Children.Add(border); 27 | 28 | TextBlock scaleLabel = new TextBlock() 29 | { 30 | Margin = new Windows.UI.Xaml.Thickness(10, 5, 10, 7), 31 | VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center, 32 | HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center, 33 | TextAlignment = Windows.UI.Xaml.TextAlignment.Center, 34 | }; 35 | 36 | scaleLabel.SetBinding(TextBlock.TextProperty, new Binding() 37 | { 38 | Path = new Windows.UI.Xaml.PropertyPath("CurrentGridScale"), 39 | Source = App.ViewModel, 40 | Converter = new Common.MilesDisplayLabelConverter(), 41 | }); 42 | 43 | Grid scaleGrid = new Grid() 44 | { 45 | Background = new SolidColorBrush(Color.FromArgb(200, 0, 0, 0)), 46 | HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right, 47 | VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top, 48 | Margin = new Windows.UI.Xaml.Thickness(10), 49 | RequestedTheme = Windows.UI.Xaml.ElementTheme.Dark, 50 | }; 51 | 52 | scaleGrid.Children.Add(scaleLabel); 53 | 54 | grid.Children.Add(scaleGrid); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Extensions/ListExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public static class ListExtensions 10 | { 11 | public static void ForEach(this IEnumerable enumeration, Action action) 12 | { 13 | foreach (T item in enumeration) 14 | { 15 | action(item); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Helpers/ControlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI; 7 | using Windows.UI.Xaml; 8 | using Windows.UI.Xaml.Controls; 9 | using Windows.UI.Xaml.Media; 10 | using Windows.UI.Xaml.Shapes; 11 | 12 | namespace AirTrafficSim.Helpers 13 | { 14 | public static class ControlHelper 15 | { 16 | public static Grid GenerateMapGrid() 17 | { 18 | Grid grid = new Grid(); 19 | 20 | for (int i = 0; i <= 11; i++) 21 | { 22 | grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(8.0, GridUnitType.Star) }); 23 | } 24 | 25 | for (int i = 0; i <= 11; i++) 26 | { 27 | grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(8.0, GridUnitType.Star) }); 28 | } 29 | 30 | Border border = null; 31 | 32 | for (int row = 0; row <= 11; row++) 33 | { 34 | 35 | for (int col = 0; col <= 11; col++) 36 | { 37 | border = new Border() { BorderBrush = new SolidColorBrush(Colors.White), BorderThickness = new Thickness(1.0), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch }; 38 | 39 | 40 | border.SetValue(Grid.RowProperty, row); 41 | border.SetValue(Grid.ColumnProperty, col); 42 | 43 | grid.Children.Add(border); 44 | } 45 | 46 | 47 | } 48 | 49 | return grid; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Helpers/ThemeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.ApplicationModel.Core; 7 | using Windows.Foundation.Metadata; 8 | using Windows.UI; 9 | using Windows.UI.ViewManagement; 10 | using Windows.UI.Xaml.Media; 11 | 12 | namespace AirTrafficSim.Helpers 13 | { 14 | public static class ThemeHelper 15 | { 16 | public static void ApplyTitleSyling() 17 | { 18 | if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView")) 19 | { 20 | CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar; 21 | coreTitleBar.ExtendViewIntoTitleBar = false; 22 | 23 | var titleBar = ApplicationView.GetForCurrentView().TitleBar; 24 | if (titleBar != null) 25 | { 26 | 27 | var brandColor = (App.Current.Resources["AppAccentBrush"] as SolidColorBrush).Color; 28 | var brandColorLight = (App.Current.Resources["AppAccentBrushLight"] as SolidColorBrush).Color; 29 | 30 | titleBar.ButtonBackgroundColor = brandColor; 31 | titleBar.ButtonInactiveBackgroundColor = brandColorLight; 32 | 33 | titleBar.ButtonForegroundColor = Colors.White; 34 | titleBar.ButtonInactiveForegroundColor = Colors.Black; 35 | 36 | titleBar.BackgroundColor = brandColor; 37 | titleBar.InactiveBackgroundColor = (App.Current.Resources["AppAccentBrushLight"] as SolidColorBrush).Color; 38 | } 39 | 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Helpers/TimerHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reactive.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace AirTrafficSim.Helpers 9 | { 10 | public class TimerHelper 11 | { 12 | IDisposable TrafficTimer = null; 13 | IDisposable ClockTimer = null; 14 | 15 | public void StartTrafficTimer() 16 | { 17 | TrafficTimer = Observable 18 | .Timer(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(4)) 19 | .Subscribe(q => 20 | { 21 | UpdateTrafficTimer(); 22 | }); 23 | } 24 | 25 | private async void UpdateTrafficTimer() 26 | { 27 | var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; 28 | 29 | await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 30 | { 31 | App.ViewModel.LastTrafficTimestamp = DateTime.Now.ToString("hh:mm:ss"); 32 | }); 33 | } 34 | 35 | public void StopTrafficTimer() 36 | { 37 | if (this.TrafficTimer != null) this.TrafficTimer.Dispose(); 38 | } 39 | 40 | public void StartLocalTimer() 41 | { 42 | ClockTimer = Observable 43 | .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) 44 | .Subscribe(q => 45 | { 46 | UpdateClock(); 47 | }); 48 | } 49 | 50 | private async void UpdateClock() 51 | { 52 | var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; 53 | 54 | await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () => 55 | { 56 | App.ViewModel.CurrentTime = DateTime.Now; 57 | 58 | }); 59 | 60 | } 61 | 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/AirTrafficSim_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/AirTrafficSim_back.jpg -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/FlySim_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/FlySim_back.jpg -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/PlaneViewBorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/PlaneViewBorder.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/PlaneViewHorizon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/PlaneViewHorizon.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/dashedarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/dashedarrow.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Images/planeimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/AirTrafficSim/AirTrafficSim/Images/planeimage.png -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Listeners/AirTrafficListener.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using ppatierno.AzureSBLite.Messaging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Collections.ObjectModel; 6 | using System.Linq; 7 | using System.Numerics; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Windows.UI.Core; 11 | 12 | namespace AirTrafficSim.Listeners 13 | { 14 | public class AirTrafficListener 15 | { 16 | private EventHubClient client { get; set; } 17 | private EventHubConsumerGroup consumerGroup { get; set; } 18 | private EventHubReceiver primaryReceiver { get; set; } 19 | private EventHubReceiver secondaryReceiver { get; set; } 20 | 21 | private List statusInfo = new List(); 22 | 23 | public bool IsConfigured => Common.CoreConstants.SharedEventHubEndpoint.ToLower().Contains("endpoint=sb://"); 24 | 25 | public async void StartListeningAsync() 26 | { 27 | this.client = EventHubClient.CreateFromConnectionString(Common.CoreConstants.SharedEventHubEndpoint, Common.CoreConstants.SharedAirTrafficHubName); 28 | 29 | this.consumerGroup = this.client.GetDefaultConsumerGroup(); 30 | this.primaryReceiver = this.consumerGroup.CreateReceiver("0", DateTime.Now.ToUniversalTime()); 31 | this.secondaryReceiver = this.consumerGroup.CreateReceiver("1", DateTime.Now.ToUniversalTime()); 32 | 33 | await Task.Run(() => StartListeningForTrafficCommands()); 34 | } 35 | 36 | private async void StartListeningForTrafficCommands() 37 | { 38 | 39 | 40 | while (true) 41 | { 42 | await Task.Delay(1); 43 | 44 | try 45 | { 46 | var primaryEventData = this.primaryReceiver.Receive(); 47 | 48 | if (primaryEventData != null) 49 | { 50 | GeneratePlaneStatus(primaryEventData.GetBytes()); 51 | } 52 | 53 | var secondaryEventData = this.primaryReceiver.Receive(); 54 | 55 | if (secondaryEventData != null) 56 | { 57 | GeneratePlaneStatus(secondaryEventData.GetBytes()); 58 | } 59 | 60 | List filteredStatus = new List(); 61 | 62 | filteredStatus.AddRange(from op in statusInfo select new FilteredPlaneStatusInfo() { DisplayName = op.Plane1, Distance = op.Distance, }); 63 | filteredStatus.AddRange(from op in statusInfo select new FilteredPlaneStatusInfo() { DisplayName = op.Plane2, Distance = op.Distance, }); 64 | 65 | var orderedPlanes = filteredStatus.OrderBy(o => o.Distance).GroupBy(g => g.DisplayName); 66 | 67 | var finalPlaneStatus = from plane in orderedPlanes 68 | select new 69 | { 70 | displayName = plane.Key, 71 | minimumDistance = plane.First().Distance, 72 | }; 73 | 74 | var atRiskPlanes = (from item in finalPlaneStatus 75 | where item.minimumDistance < Common.CoreConstants.AtRiskThreshold 76 | select item.displayName).Distinct().ToList(); 77 | 78 | App.ViewModel.AtRiskPlanes = atRiskPlanes; 79 | } 80 | catch { } 81 | 82 | } 83 | } 84 | 85 | private void GeneratePlaneStatus(byte[] bytes) 86 | { 87 | if (bytes == null) return; 88 | 89 | statusInfo.Clear(); 90 | 91 | try 92 | { 93 | var payload = Encoding.UTF8.GetString(bytes); 94 | 95 | foreach (var info in payload.Split("\r\n".ToCharArray(), 96 | StringSplitOptions.RemoveEmptyEntries)) 97 | { 98 | var status = JsonConvert.DeserializeObject(info); 99 | 100 | statusInfo.Add(new PlaneStatusInformation() 101 | { 102 | Plane1 = status.plane1, 103 | Plane2 = status.plane2, 104 | Distance = Convert.ToDouble(status.distance), 105 | }); 106 | } 107 | } 108 | catch { } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Listeners/FlightActivityListener.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using ppatierno.AzureSBLite.Messaging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Numerics; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Windows.UI.Core; 10 | using System.Collections.ObjectModel; 11 | 12 | namespace AirTrafficSim.Listeners 13 | { 14 | public class FlightActivityListener 15 | { 16 | private EventHubClient client { get; set; } 17 | private EventHubConsumerGroup consumerGroup { get; set; } 18 | private EventHubReceiver primaryReceiver { get; set; } 19 | private EventHubReceiver secondaryReceiver { get; set; } 20 | 21 | public List PendingFlightInfo = new List(); 22 | 23 | public int CurrentDelay = 1; 24 | 25 | internal bool IsConfigured => Common.CoreConstants.SharedEventHubEndpoint.ToLower().Contains("endpoint=sb://"); 26 | 27 | public async void StartListeningAsync() 28 | { 29 | this.client = EventHubClient.CreateFromConnectionString(Common.CoreConstants.SharedEventHubEndpoint, Common.CoreConstants.SharedFlightActivityHubName); 30 | 31 | this.consumerGroup = this.client.GetDefaultConsumerGroup(); 32 | this.primaryReceiver = this.consumerGroup.CreateReceiver("0", DateTime.Now.ToUniversalTime()); 33 | this.secondaryReceiver = this.consumerGroup.CreateReceiver("1", DateTime.Now.ToUniversalTime()); 34 | 35 | await Task.Run(() => StartListeningForNavigationCommands()); 36 | } 37 | 38 | private async void StartListeningForNavigationCommands() 39 | { 40 | while (true) 41 | { 42 | try 43 | { 44 | var primaryEventData = this.primaryReceiver.Receive(); 45 | 46 | if (primaryEventData != null) 47 | { 48 | byte[] bytes = primaryEventData.GetBytes(); 49 | 50 | var payload = Encoding.UTF8.GetString(bytes); 51 | 52 | try 53 | { 54 | var flightInfo = JsonConvert.DeserializeObject(payload); 55 | 56 | this.PendingFlightInfo.Add(flightInfo); 57 | 58 | if (this.PendingFlightInfo.Count >= App.ViewModel.ActivePlaneCount) 59 | { 60 | CurrentDelay = 1000; 61 | 62 | App.ViewModel.UpdateFlightInformation(this.PendingFlightInfo); 63 | 64 | this.PendingFlightInfo.Clear(); 65 | } 66 | 67 | } 68 | catch 69 | { 70 | } 71 | 72 | } 73 | 74 | var secondaryEventData = this.secondaryReceiver.Receive(); 75 | 76 | if (secondaryEventData != null) 77 | { 78 | byte[] bytes = secondaryEventData.GetBytes(); 79 | 80 | var payload = Encoding.UTF8.GetString(bytes); 81 | 82 | try 83 | { 84 | var flightInfo = JsonConvert.DeserializeObject(payload); 85 | 86 | this.PendingFlightInfo.Add(flightInfo); 87 | 88 | if (this.PendingFlightInfo.Count >= App.ViewModel.ActivePlaneCount) 89 | { 90 | CurrentDelay = 1000; 91 | 92 | App.ViewModel.UpdateFlightInformation(this.PendingFlightInfo); 93 | 94 | this.PendingFlightInfo.Clear(); 95 | } 96 | } 97 | catch 98 | { 99 | } 100 | } 101 | } 102 | catch 103 | { 104 | 105 | } 106 | 107 | await Task.Delay(CurrentDelay); 108 | 109 | } 110 | 111 | } 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using AirTrafficSim.Helpers; 2 | using Microsoft.Toolkit.Uwp.UI.Extensions; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Runtime.InteropServices.WindowsRuntime; 8 | using Windows.Devices.Geolocation; 9 | using Windows.Foundation; 10 | using Windows.Foundation.Collections; 11 | using Windows.UI.Xaml; 12 | using Windows.UI.Xaml.Controls; 13 | using Windows.UI.Xaml.Controls.Maps; 14 | using Windows.UI.Xaml.Controls.Primitives; 15 | using Windows.UI.Xaml.Data; 16 | using Windows.UI.Xaml.Input; 17 | using Windows.UI.Xaml.Media; 18 | using Windows.UI.Xaml.Navigation; 19 | 20 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 21 | 22 | namespace AirTrafficSim 23 | { 24 | /// 25 | /// An empty page that can be used on its own or navigated to within a Frame. 26 | /// 27 | public sealed partial class MainPage : Page 28 | { 29 | public string MapServiceToken 30 | { 31 | get { return Common.CoreConstants.MapServiceToken; } 32 | } 33 | 34 | public MainPage() 35 | { 36 | this.InitializeComponent(); 37 | this.Loaded += OnLoaded; 38 | } 39 | 40 | private void OnLoaded(object sender, RoutedEventArgs e) 41 | { 42 | if (App.ViewModel == null) 43 | { 44 | App.ViewModel = new MainViewModel(this.flightMap); 45 | 46 | App.ViewModel.InitializeSystem(); 47 | } 48 | 49 | this.DataContext = App.ViewModel; 50 | 51 | EnsureMapView(); 52 | } 53 | 54 | private async void EnsureMapView() 55 | { 56 | 57 | await System.Threading.Tasks.Task.Delay(2000); 58 | 59 | var toolbar = flightMap.FindDescendant(); 60 | if (toolbar != null) 61 | { 62 | toolbar.Visibility = Visibility.Visible; 63 | } 64 | 65 | var swapchainpanel = flightMap.FindDescendant(); 66 | if (swapchainpanel != null && swapchainpanel.Parent != null) 67 | { 68 | (swapchainpanel.Parent as Grid).AddMapOverlay(); 69 | } 70 | 71 | flightMap.Style = MapStyle.Aerial3DWithRoads; 72 | 73 | await flightMap.TrySetSceneAsync(MapScene.CreateFromLocationAndRadius(Helpers.MapHelper.AreaCenter, 74 | Common.CoreConstants.AreaRadius)); 75 | } 76 | 77 | private async void OnIntoViewClicked(object sender, RoutedEventArgs e) 78 | { 79 | await App.ViewModel.BringPlanesIntoViewAsync(this.flightMap); 80 | } 81 | 82 | private async void OnViewAreaClicked(object sender, RoutedEventArgs e) 83 | { 84 | await App.ViewModel.ViewAreaBoundingBox(this.flightMap); 85 | } 86 | 87 | private void OnZoomChanged(MapControl sender, object args) 88 | { 89 | if (App.ViewModel != null) App.ViewModel.CurrentGridScale = flightMap.TryGetDistance(); 90 | } 91 | 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Models/ActivePlaneInformation.cs: -------------------------------------------------------------------------------- 1 | using AirTrafficSim.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Geolocation; 8 | using Windows.UI.Xaml; 9 | 10 | namespace AirTrafficSim 11 | { 12 | public class ActivePlaneInformation : Common.ObservableBase 13 | { 14 | private string _displayName; 15 | public string DisplayName 16 | { 17 | get { return this._displayName; } 18 | set { this.SetProperty(ref this._displayName, value); } 19 | } 20 | 21 | private Geopoint _location; 22 | public Geopoint Location 23 | { 24 | get { return this._location; } 25 | set { this.SetProperty(ref this._location, value); } 26 | } 27 | 28 | private FlightInformation _flightInformation; 29 | public FlightInformation FlightInformation 30 | { 31 | get { return this._flightInformation; } 32 | set { this.SetProperty(ref this._flightInformation, value); } 33 | } 34 | 35 | private FlightStatus _status; 36 | public FlightStatus Status 37 | { 38 | get { return this._status; } 39 | set { this.SetProperty(ref this._status, value); } 40 | } 41 | 42 | private Visibility _zoomDeepLevel; 43 | public Visibility ZoomDeepLevel 44 | { 45 | get { return this._zoomDeepLevel; } 46 | set { this.SetProperty(ref this._zoomDeepLevel, value); } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Models/FlightInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AirTrafficSim 8 | { 9 | public class FlightInformation : Common.ObservableBase 10 | { 11 | public FlightInformation(double altitude) 12 | { 13 | this.CurrentAltitude = altitude; 14 | } 15 | 16 | private double _currentPitch; 17 | public double CurrentPitch 18 | { 19 | get { return this._currentPitch; } 20 | set { this.SetProperty(ref this._currentPitch, value); } 21 | } 22 | 23 | private double _currentAltitude; 24 | public double CurrentAltitude 25 | { 26 | get { return this._currentAltitude; } 27 | set { this.SetProperty(ref this._currentAltitude, value); } 28 | } 29 | 30 | private double _currentHeading; 31 | public double CurrentHeading 32 | { 33 | get { return this._currentHeading; } 34 | set { this.SetProperty(ref this._currentHeading, value); } 35 | } 36 | 37 | private double _currentSpeed; 38 | public double CurrentSpeed 39 | { 40 | get { return this._currentSpeed; } 41 | set { this.SetProperty(ref this._currentSpeed, value); } 42 | } 43 | 44 | private double _currentTemperature; 45 | public double CurrentTemperature 46 | { 47 | get { return this._currentTemperature; } 48 | set { this.SetProperty(ref this._currentTemperature, value); } 49 | } 50 | 51 | private double _currentHumidity; 52 | public double CurrentHumidity 53 | { 54 | get { return this._currentHumidity; } 55 | set { this.SetProperty(ref this._currentHumidity, value); } 56 | } 57 | 58 | private double _currentRoll; 59 | public double CurrentRoll 60 | { 61 | get { return this._currentRoll; } 62 | set { this.SetProperty(ref this._currentRoll, value); } 63 | } 64 | 65 | 66 | private double _currentLatitude; 67 | public double CurrentLatitude 68 | { 69 | get { return this._currentLatitude; } 70 | set { this.SetProperty(ref this._currentLatitude, value); } 71 | } 72 | 73 | private double _currentLongitude; 74 | public double CurrentLongitude 75 | { 76 | get { return this._currentLongitude; } 77 | set { this.SetProperty(ref this._currentLongitude, value); } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Models/PlaneStatusInformation.cs: -------------------------------------------------------------------------------- 1 | using AirTrafficSim.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace AirTrafficSim 9 | { 10 | public class PlaneStatusInformation : Common.ObservableBase 11 | { 12 | private string _plane1; 13 | public string Plane1 14 | { 15 | get { return this._plane1; } 16 | set { this.SetProperty(ref this._plane1, value); } 17 | } 18 | 19 | private string _plane2; 20 | public string Plane2 21 | { 22 | get { return this._plane2; } 23 | set { this.SetProperty(ref this._plane2, value); } 24 | } 25 | 26 | private double _distance; 27 | public double Distance 28 | { 29 | get { return this._distance; } 30 | set { this.SetProperty(ref this._distance, value); } 31 | } 32 | 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | AirTrafficSim 18 | codes 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("AirTrafficSim")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("AirTrafficSim")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /AirTrafficSim/AirTrafficSim/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /FlySim.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "FlySimEmbedded" 5 | }, 6 | { 7 | "path": "FlySimFunctions" 8 | } 9 | ], 10 | "settings": { 11 | "IoTWorkbench.BoardId": "devkit", 12 | "IoTWorkbench.DevicePath": "FlySimEmbedded", 13 | "IoTWorkbench.FunctionPath": "FlySimFunctions" 14 | } 15 | } -------------------------------------------------------------------------------- /FlySim/FlySim.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlySim", "FlySim\FlySim.csproj", "{E283660A-CD75-4293-BDB8-9231389EF3A3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM = Release|ARM 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|ARM.ActiveCfg = Debug|ARM 19 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|ARM.Build.0 = Debug|ARM 20 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|ARM.Deploy.0 = Debug|ARM 21 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x64.ActiveCfg = Debug|x64 22 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x64.Build.0 = Debug|x64 23 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x64.Deploy.0 = Debug|x64 24 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x86.ActiveCfg = Debug|x86 25 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x86.Build.0 = Debug|x86 26 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Debug|x86.Deploy.0 = Debug|x86 27 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|ARM.ActiveCfg = Release|ARM 28 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|ARM.Build.0 = Release|ARM 29 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|ARM.Deploy.0 = Release|ARM 30 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x64.ActiveCfg = Release|x64 31 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x64.Build.0 = Release|x64 32 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x64.Deploy.0 = Release|x64 33 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x86.ActiveCfg = Release|x86 34 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x86.Build.0 = Release|x86 35 | {E283660A-CD75-4293-BDB8-9231389EF3A3}.Release|x86.Deploy.0 = Release|x86 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {917A790A-3276-4E53-9EEF-375E87D70801} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /FlySim/FlySim/App.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 11 | #FFEBEBEB 12 | #FF1A1A1A 13 | #FF000000 14 | #FF555555 15 | #66000000 16 | 17 | #FF00A3D9 18 | #FFD90000 19 | 20 | #AAFFFFFF 21 | #55D90000 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /FlySim/FlySim/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.ApplicationModel; 7 | using Windows.ApplicationModel.Activation; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Controls.Primitives; 13 | using Windows.UI.Xaml.Data; 14 | using Windows.UI.Xaml.Input; 15 | using Windows.UI.Xaml.Media; 16 | using Windows.UI.Xaml.Navigation; 17 | 18 | namespace FlySim 19 | { 20 | /// 21 | /// Provides application-specific behavior to supplement the default Application class. 22 | /// 23 | sealed partial class App : Application 24 | { 25 | public static MainViewModel ViewModel { get; set; } 26 | 27 | /// 28 | /// Initializes the singleton application object. This is the first line of authored code 29 | /// executed, and as such is the logical equivalent of main() or WinMain(). 30 | /// 31 | public App() 32 | { 33 | this.InitializeComponent(); 34 | this.Suspending += OnSuspending; 35 | } 36 | 37 | /// 38 | /// Invoked when the application is launched normally by the end user. Other entry points 39 | /// will be used such as when the application is launched to open a specific file. 40 | /// 41 | /// Details about the launch request and process. 42 | protected override void OnLaunched(LaunchActivatedEventArgs e) 43 | { 44 | Helpers.ThemeHelper.ApplyTitleSyling(); 45 | 46 | //Helpers.StorageHelper.SaveRetrievedObjectActivity(new List()); 47 | 48 | ElementSoundPlayer.State = ElementSoundPlayerState.On; 49 | 50 | Frame rootFrame = Window.Current.Content as Frame; 51 | 52 | // Do not repeat app initialization when the Window already has content, 53 | // just ensure that the window is active 54 | if (rootFrame == null) 55 | { 56 | // Create a Frame to act as the navigation context and navigate to the first page 57 | rootFrame = new Frame(); 58 | 59 | rootFrame.NavigationFailed += OnNavigationFailed; 60 | 61 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 62 | { 63 | //TODO: Load state from previously suspended application 64 | } 65 | 66 | // Place the frame in the current Window 67 | Window.Current.Content = rootFrame; 68 | } 69 | 70 | if (e.PrelaunchActivated == false) 71 | { 72 | if (rootFrame.Content == null) 73 | { 74 | // When the navigation stack isn't restored navigate to the first page, 75 | // configuring the new page by passing required information as a navigation 76 | // parameter 77 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 78 | } 79 | // Ensure the current window is active 80 | Window.Current.Activate(); 81 | } 82 | } 83 | 84 | /// 85 | /// Invoked when Navigation to a certain page fails 86 | /// 87 | /// The Frame which failed navigation 88 | /// Details about the navigation failure 89 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 90 | { 91 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 92 | } 93 | 94 | /// 95 | /// Invoked when application execution is being suspended. Application state is saved 96 | /// without knowing whether the application will be terminated or resumed with the contents 97 | /// of memory still intact. 98 | /// 99 | /// The source of the suspend request. 100 | /// Details about the suspend request. 101 | private void OnSuspending(object sender, SuspendingEventArgs e) 102 | { 103 | var deferral = e.SuspendingOperation.GetDeferral(); 104 | //TODO: Save application state and stop any background activity 105 | deferral.Complete(); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/AppIcon.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/AppIcon.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/MediumTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/MediumTile.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Assets/WideTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Assets/WideTile.scale-100.png -------------------------------------------------------------------------------- /FlySim/FlySim/Classes/FilteredPlaneStatusInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class FilteredPlaneStatusInfo 10 | { 11 | public string DisplayName { get; set; } 12 | public double Distance { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /FlySim/FlySim/Classes/FlightInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class FlightInfo 10 | { 11 | public string deviceId { get; set; } 12 | public int messageId { get; set; } 13 | public string timestamp { get; set; } 14 | public float temperature { get; set; } 15 | public float humidity { get; set; } 16 | public float x { get; set; } 17 | public float y { get; set; } 18 | public float z { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /FlySim/FlySim/Classes/NewFlightInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class NewFlightInfo 10 | { 11 | public string deviceId { get; set; } 12 | public double airspeed { get; set; } 13 | public double heading { get; set; } 14 | public double altitude { get; set; } 15 | public double latitude { get; set; } 16 | public double longitude { get; set; } 17 | public double pitch { get; set; } 18 | public double roll { get; set; } 19 | public double temperature { get; set; } 20 | public double humidity { get; set; } 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /FlySim/FlySim/Classes/PlaneStatusInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class PlaneStatusInfo 10 | { 11 | public string plane1 { get; set; } 12 | public string plane2 { get; set; } 13 | public string distance { get; set; } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /FlySim/FlySim/Common/CoreConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim.Common 8 | { 9 | public class CoreConstants 10 | { 11 | public static string FlightActivityEventHubEndpoint = "EVENT_HUB_ENDPOINT"; 12 | public static string FlightActivityEventHubName = "flysim"; 13 | 14 | public static double AreaRadius = 80467.0; 15 | public static double InitialZoomLevel = 9.0; 16 | public static double AtRiskThreshold = 10560.0; 17 | 18 | public static Windows.Devices.Geolocation.BasicGeoposition DefaultStartingLocation = new Windows.Devices.Geolocation.BasicGeoposition() 19 | { 20 | Latitude = 37.242, 21 | Longitude = -115.8191, 22 | }; 23 | 24 | public static string MapServiceToken = "HvD1WpB9MyrWv30BaZCP~-DZBRQGBV2rbPRfQqjBZUQ~AkD5MLW_Sj2_nCY3sesLC3Ldua1j84cVqhnL2Pl5MpY1lbLLnVrmmHoqAVjjvbhO"; 25 | 26 | public static string TranslatorTextSubscriptionKey = "797b91afb8e9402cb16f3dc3eb21691e"; 27 | public static string TranslatorServicesBaseUrl = $"http://api.microsofttranslator.com/"; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /FlySim/FlySim/Common/CoreEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim.Common 8 | { 9 | public enum CompassDirection 10 | { 11 | North = 0, 12 | NorthEast = 1, 13 | East = 2, 14 | SouthEast = 3, 15 | South = 4, 16 | SouthWest = 5, 17 | West = 6, 18 | NorthWest = 7 19 | } 20 | 21 | public enum FlightStatus 22 | { 23 | Ok, 24 | Warning, 25 | AtRisk 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /FlySim/FlySim/Common/ObservableBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.CompilerServices; 4 | using Windows.UI.Xaml.Data; 5 | 6 | namespace FlySim.Common 7 | { 8 | /// 9 | /// Implementation of to simplify models. 10 | /// 11 | [Windows.Foundation.Metadata.WebHostHidden] 12 | public abstract class ObservableBase : INotifyPropertyChanged 13 | { 14 | /// 15 | /// Multicast event for property change notifications. 16 | /// 17 | public event PropertyChangedEventHandler PropertyChanged; 18 | 19 | /// 20 | /// Checks if a property already matches a desired value. Sets the property and 21 | /// notifies listeners only when necessary. 22 | /// 23 | /// Type of the property. 24 | /// Reference to a property with both getter and setter. 25 | /// Desired value for the property. 26 | /// Name of the property used to notify listeners. This 27 | /// value is optional and can be provided automatically when invoked from compilers that 28 | /// support CallerMemberName. 29 | /// True if the value was changed, false if the existing value matched the 30 | /// desired value. 31 | protected bool SetProperty(ref T storage, T value, [CallerMemberName] String propertyName = null) 32 | { 33 | if (object.Equals(storage, value)) return false; 34 | 35 | storage = value; 36 | this.OnPropertyChanged(propertyName); 37 | return true; 38 | } 39 | 40 | /// 41 | /// Notifies listeners that a property value has changed. 42 | /// 43 | /// Name of the property used to notify listeners. This 44 | /// value is optional and can be provided automatically when invoked from compilers 45 | /// that support . 46 | protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 47 | { 48 | var eventHandler = this.PropertyChanged; 49 | if (eventHandler != null) 50 | { 51 | try 52 | { 53 | eventHandler(this, new PropertyChangedEventArgs(propertyName)); 54 | } 55 | catch 56 | { 57 | } 58 | 59 | 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FlySim/FlySim/Common/RelayCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace FlySim.Common 5 | { 6 | public class RelayCommand : ICommand 7 | { 8 | private readonly Action _execute; 9 | private readonly Func _canExecute; 10 | 11 | public event EventHandler CanExecuteChanged; 12 | public RelayCommand(Action execute) : this(execute, null) { } 13 | 14 | public RelayCommand(Action execute, Func canExecute) 15 | { 16 | this._execute = execute ?? throw new ArgumentNullException("execute"); 17 | this._canExecute = canExecute; 18 | } 19 | 20 | public bool CanExecute(object parameter) => _canExecute == null || _canExecute(); 21 | public void Execute(object parameter) => _execute(); 22 | public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); 23 | } 24 | 25 | public class RelayCommand : ICommand 26 | { 27 | private readonly Action _execute; 28 | private readonly Func _canExecute; 29 | 30 | public event EventHandler CanExecuteChanged; 31 | public RelayCommand(Action execute) : this(execute, null) { } 32 | 33 | public RelayCommand(Action execute, Func canExecute) 34 | { 35 | this._execute = execute ?? throw new ArgumentNullException("execute"); 36 | this._canExecute = canExecute; 37 | } 38 | 39 | public bool CanExecute(object parameter) => _canExecute == null || _canExecute((T)parameter); 40 | public void Execute(object parameter) => _execute((T)parameter); 41 | public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /FlySim/FlySim/Controls/ActivePlaneControl.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 16 | 17 | 19 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /FlySim/FlySim/Controls/ActivePlaneControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using System.Threading.Tasks; 7 | using Windows.Foundation; 8 | using Windows.Foundation.Collections; 9 | using Windows.UI.Xaml; 10 | using Windows.UI.Xaml.Controls; 11 | using Windows.UI.Xaml.Controls.Primitives; 12 | using Windows.UI.Xaml.Data; 13 | using Windows.UI.Xaml.Input; 14 | using Windows.UI.Xaml.Media; 15 | using Windows.UI.Xaml.Navigation; 16 | 17 | // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 18 | 19 | namespace FlySim.Controls 20 | { 21 | public sealed partial class ActivePlaneControl : UserControl 22 | { 23 | 24 | public ActivePlaneControl() 25 | { 26 | this.InitializeComponent(); 27 | this.Loaded += ActivePlaneControl_Loaded; 28 | } 29 | 30 | private void ActivePlaneControl_Loaded(object sender, RoutedEventArgs e) 31 | { 32 | this.DataContext = App.ViewModel; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FlySim/FlySim/Extensions/ActivityExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public static class ActivityExtensions 10 | { 11 | public static void Hydrate(this FlightInformation flightInfo, NewFlightInfo info) 12 | { 13 | flightInfo.DisplayName = info.deviceId; 14 | flightInfo.CurrentAltitude = info.altitude; 15 | flightInfo.CurrentHeading = info.heading; 16 | flightInfo.CurrentTemperature = info.temperature; 17 | flightInfo.CurrentHumidity = info.humidity; 18 | flightInfo.CurrentRoll = info.roll * -1; 19 | flightInfo.CurrentSpeed = info.airspeed; 20 | flightInfo.CurrentPitch = info.pitch * 4.0 * -1; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /FlySim/FlySim/Extensions/CompassExtensions.cs: -------------------------------------------------------------------------------- 1 | using FlySim.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Geolocation; 8 | 9 | namespace FlySim 10 | { 11 | public static class DirectionExtensions 12 | { 13 | private static readonly Dictionary 14 | mapping = new Dictionary 15 | { 16 | { CompassDirection.North, "N" }, 17 | { CompassDirection.NorthEast, "NE" }, 18 | { CompassDirection.East, "E" }, 19 | { CompassDirection.SouthEast, "SE" }, 20 | { CompassDirection.South, "S" }, 21 | { CompassDirection.SouthWest, "SW" }, 22 | { CompassDirection.West, "W" }, 23 | { CompassDirection.NorthWest, "NW" } 24 | }; 25 | 26 | public static CompassDirection AsDirectionLabel(this double heading) 27 | { 28 | var adjusted = (heading + 22) % 360; 29 | var sector = adjusted / 45; 30 | return (CompassDirection)sector; 31 | } 32 | 33 | public static string GetSuffix(this CompassDirection direction) 34 | { 35 | return mapping.ContainsKey(direction) ? mapping[direction] : "N"; 36 | } 37 | 38 | public static Boolean IsWithin(this BasicGeoposition pt, BasicGeoposition nw, BasicGeoposition se) 39 | { 40 | return pt.Latitude <= nw.Latitude && 41 | pt.Longitude >= nw.Longitude && 42 | pt.Latitude >= se.Latitude && 43 | pt.Longitude <= se.Longitude; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /FlySim/FlySim/Extensions/ControlExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI; 7 | using Windows.UI.Xaml.Controls; 8 | using Windows.UI.Xaml.Data; 9 | using Windows.UI.Xaml.Media; 10 | 11 | namespace FlySim 12 | { 13 | public static class ControlExtensions 14 | { 15 | public static void AddMapOverlay(this Grid grid) 16 | { 17 | var border = new Border() 18 | { 19 | IsHitTestVisible = false, 20 | Background = App.Current.Resources["AppAccentBrush"] as SolidColorBrush, 21 | Opacity = 0.4 22 | }; 23 | 24 | grid.Children.Add(Helpers.ControlHelper.GenerateMapGrid()); 25 | grid.Children.Add(border); 26 | 27 | TextBlock scaleLabel = new TextBlock() 28 | { 29 | Margin = new Windows.UI.Xaml.Thickness(10, 5, 10, 7), 30 | VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center, 31 | HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center, 32 | TextAlignment = Windows.UI.Xaml.TextAlignment.Center, 33 | }; 34 | 35 | scaleLabel.SetBinding(TextBlock.TextProperty, new Binding() 36 | { 37 | Path = new Windows.UI.Xaml.PropertyPath("CurrentGridScale"), 38 | Source = App.ViewModel, 39 | Converter = new Common.MilesDisplayLabelConverter(), 40 | }); 41 | 42 | Grid scaleGrid = new Grid() 43 | { 44 | Background = new SolidColorBrush(Color.FromArgb(200, 0, 0, 0)), 45 | HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right, 46 | VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top, 47 | Margin = new Windows.UI.Xaml.Thickness(10), 48 | RequestedTheme = Windows.UI.Xaml.ElementTheme.Dark, 49 | }; 50 | 51 | scaleGrid.Children.Add(scaleLabel); 52 | 53 | grid.Children.Add(scaleGrid); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/ControlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI; 7 | using Windows.UI.Xaml; 8 | using Windows.UI.Xaml.Controls; 9 | using Windows.UI.Xaml.Media; 10 | using Windows.UI.Xaml.Shapes; 11 | 12 | namespace FlySim.Helpers 13 | { 14 | public static class ControlHelper 15 | { 16 | public static Grid GenerateMapGrid() 17 | { 18 | Grid grid = new Grid(); 19 | 20 | for (int i = 0; i <= 11; i++) 21 | { 22 | grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(8.0, GridUnitType.Star) }); 23 | } 24 | 25 | for (int i = 0; i <= 11; i++) 26 | { 27 | grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(8.0, GridUnitType.Star) }); 28 | } 29 | 30 | for (int row = 0; row <= 11; row++) 31 | { 32 | for (int col = 0; col <= 11; col++) 33 | { 34 | var border = new Border() { BorderBrush = new SolidColorBrush(Colors.White), BorderThickness = new Thickness(1.0), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch }; 35 | 36 | border.SetValue(Grid.RowProperty, row); 37 | border.SetValue(Grid.ColumnProperty, col); 38 | 39 | grid.Children.Add(border); 40 | } 41 | 42 | 43 | } 44 | 45 | return grid; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/MapHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Windows.Devices.Geolocation; 4 | using Windows.Foundation; 5 | using Windows.UI.Xaml.Controls.Maps; 6 | 7 | namespace FlySim.Helpers 8 | { 9 | public static class MapHelper 10 | { 11 | public enum GeoCodeCalcMeasurement 12 | { 13 | Miles = 0, 14 | Kilometers = 1 15 | } 16 | 17 | public const double EarthRadiusInMiles = 3956.0; 18 | public const double EarthRadiusInKilometers = 6367.0; 19 | 20 | private const double Wgs84A = 6378137.0; // Major semiaxis [m] 21 | private const double Wgs84B = 6356752.3; // Minor semiaxis [m] 22 | 23 | public static Geopoint AreaCenter => new Geopoint(new BasicGeoposition 24 | { 25 | Latitude = 37.242, 26 | Longitude = -115.8191 27 | }); 28 | 29 | public static double ToRadian(double val) 30 | { 31 | return val * (Math.PI / 180); 32 | } 33 | 34 | public static double DiffRadian(double val1, double val2) 35 | { 36 | return ToRadian(val2) - ToRadian(val1); 37 | } 38 | 39 | public static GeoboundingBox GenerateGeoboundingBox(this BasicGeoposition point, double altitude, 40 | double halfSideInKm) 41 | { 42 | // Bounding box surrounding the point at given coordinates, 43 | // assuming local approximation of Earth surface as a sphere 44 | // of radius given by WGS84 45 | var lat = DegreesToRadians(point.Latitude); 46 | var lon = DegreesToRadians(point.Longitude); 47 | var halfSide = 1000 * halfSideInKm; 48 | 49 | // Radius of Earth at given latitude 50 | var radius = EarthRadius(lat); 51 | // Radius of the parallel at given latitude 52 | var pradius = radius * Math.Cos(lat); 53 | 54 | var latMin = lat - halfSide / radius; 55 | var latMax = lat + halfSide / radius; 56 | var lonMin = lon - halfSide / pradius; 57 | var lonMax = lon + halfSide / pradius; 58 | 59 | var nwCorner = new BasicGeoposition 60 | { 61 | Latitude = RadiansToDegrees(latMax), 62 | Longitude = RadiansToDegrees(lonMin), 63 | Altitude = altitude - 500 64 | }; 65 | var seCorner = new BasicGeoposition 66 | { 67 | Latitude = RadiansToDegrees(latMin), 68 | Longitude = RadiansToDegrees(lonMax), 69 | Altitude = altitude + 500 70 | }; 71 | 72 | return new GeoboundingBox(nwCorner, seCorner); 73 | } 74 | 75 | private static double DegreesToRadians(double degrees) 76 | { 77 | return Math.PI * degrees / 180.0; 78 | } 79 | 80 | private static double RadiansToDegrees(double radians) 81 | { 82 | return 180.0 * radians / Math.PI; 83 | } 84 | 85 | private static double EarthRadius(double lat) 86 | { 87 | var an = Wgs84A * Wgs84A * Math.Cos(lat); 88 | var bn = Wgs84B * Wgs84B * Math.Sin(lat); 89 | var ad = Wgs84A * Math.Cos(lat); 90 | var bd = Wgs84B * Math.Sin(lat); 91 | return Math.Sqrt((an * an + bn * bn) / (ad * ad + bd * bd)); 92 | } 93 | 94 | public static double CalcDistance(double lat1, double lng1, double lat2, double lng2) 95 | { 96 | return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles); 97 | } 98 | 99 | public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m) 100 | { 101 | var radius = EarthRadiusInMiles; 102 | 103 | if (m == GeoCodeCalcMeasurement.Kilometers) radius = EarthRadiusInKilometers; 104 | return radius * 2 * Math.Asin(Math.Min(1, 105 | Math.Sqrt(Math.Pow(Math.Sin(DiffRadian(lat1, lat2) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * 106 | Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin(DiffRadian(lng1, lng2) / 2.0), 2.0)))); 107 | } 108 | 109 | public static double TryGetDistance(this MapControl map) 110 | { 111 | var mapDistance = 0.0; 112 | 113 | try 114 | { 115 | map.GetLocationFromOffset(new Point(0, 0), out var northWest); 116 | map.GetLocationFromOffset(new Point(map.ActualWidth, map.ActualHeight), out var southEast); 117 | 118 | mapDistance = CalcDistance(northWest.Position.Latitude, northWest.Position.Longitude, 119 | southEast.Position.Latitude, southEast.Position.Longitude, GeoCodeCalcMeasurement.Miles); 120 | 121 | App.ViewModel.CurrentGridScale = mapDistance; // / 12.0; 122 | } 123 | catch (Exception) 124 | { 125 | } 126 | 127 | return mapDistance; 128 | } 129 | 130 | 131 | public static List GetAreaBoundaries() 132 | { 133 | var areaBounds = new List 134 | { 135 | new BasicGeoposition {Latitude = 37.917388162022256, Longitude = -117.3781194436157}, 136 | new BasicGeoposition {Latitude = 37.916074924119656, Longitude = -114.27100862192687}, 137 | new BasicGeoposition {Latitude = 36.569446939023756, Longitude = -114.30248033933273}, 138 | new BasicGeoposition {Latitude = 36.550956322695271, Longitude = -117.34996151882672} 139 | }; 140 | 141 | return areaBounds; 142 | } 143 | } 144 | } -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/StorageHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim.Helpers 8 | { 9 | public static class StorageHelper 10 | { 11 | public static List GetRetrievedMarkerActivity() 12 | { 13 | List retrievedMarkers = new List(); 14 | 15 | try 16 | { 17 | Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; 18 | var composite = (Windows.Storage.ApplicationDataCompositeValue)localSettings.Values["RetrievedMarkerActivity"]; 19 | 20 | if (composite != null) 21 | { 22 | retrievedMarkers = ((string)composite["RetrievedMarkers"]).Split(',').ToList(); 23 | } 24 | 25 | } 26 | catch (Exception) 27 | { 28 | } 29 | 30 | return retrievedMarkers; 31 | } 32 | 33 | public static bool SaveRetrievedMarkerActivity(IEnumerable retrievedMarkers) 34 | { 35 | bool successful = false; 36 | 37 | try 38 | { 39 | Windows.Storage.ApplicationDataCompositeValue composite = 40 | new Windows.Storage.ApplicationDataCompositeValue 41 | { 42 | ["RetrievedMarkers"] = string.Join(",", retrievedMarkers) 43 | }; 44 | 45 | 46 | Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; 47 | localSettings.Values["RetrievedMarkerActivity"] = composite; 48 | 49 | successful = true; 50 | } 51 | catch (Exception) 52 | { 53 | } 54 | 55 | return successful; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/ThemeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.ApplicationModel.Core; 7 | using Windows.Foundation.Metadata; 8 | using Windows.UI; 9 | using Windows.UI.ViewManagement; 10 | using Windows.UI.Xaml.Media; 11 | 12 | namespace FlySim.Helpers 13 | { 14 | public static class ThemeHelper 15 | { 16 | public static void ApplyTitleSyling() 17 | { 18 | if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView")) 19 | { 20 | CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar; 21 | coreTitleBar.ExtendViewIntoTitleBar = false; 22 | 23 | var titleBar = ApplicationView.GetForCurrentView().TitleBar; 24 | if (titleBar != null){ 25 | 26 | var brandColor = (App.Current.Resources["AppAccentBrush"] as SolidColorBrush).Color; 27 | var brandColorLight = (App.Current.Resources["AppAccentBrushLight"] as SolidColorBrush).Color; 28 | 29 | titleBar.ButtonBackgroundColor = brandColor; 30 | titleBar.ButtonInactiveBackgroundColor = brandColorLight; 31 | 32 | titleBar.ButtonForegroundColor = Colors.White; 33 | titleBar.ButtonInactiveForegroundColor = Colors.Black; 34 | 35 | titleBar.BackgroundColor = brandColor; 36 | titleBar.InactiveBackgroundColor = (App.Current.Resources["AppAccentBrushLight"] as SolidColorBrush).Color; 37 | } 38 | 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/TimerHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reactive.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FlySim.Helpers 9 | { 10 | public class TimerHelper 11 | { 12 | //IDisposable MissionTimer = null; 13 | IDisposable CurrentTimer = null; 14 | 15 | //public void StartMissionTimer() 16 | //{ 17 | // MissionTimer = Observable 18 | // .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) 19 | // .Subscribe(q => 20 | // { 21 | // UpdateTimer(); 22 | // }); 23 | //} 24 | 25 | public void StartClock() 26 | { 27 | CurrentTimer = Observable 28 | .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) 29 | .Subscribe(q => 30 | { 31 | UpdateClock(); 32 | }); 33 | } 34 | 35 | private async void UpdateClock() 36 | { 37 | var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; 38 | 39 | await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 40 | { 41 | App.ViewModel.CurrentTime = DateTime.Now; 42 | 43 | }); 44 | 45 | } 46 | 47 | //private async void UpdateTimer() 48 | //{ 49 | // var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; 50 | 51 | // await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 52 | // { 53 | // App.ViewModel.CurrentTime = DateTime.Now; 54 | // }); 55 | 56 | //} 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /FlySim/FlySim/Helpers/TranslationHelper.cs: -------------------------------------------------------------------------------- 1 | using FlySim.Translation; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Web.Http; 8 | 9 | namespace FlySim.Helpers 10 | { 11 | public static class TranslationHelper 12 | { 13 | public static async Task GetTextTranslationAsync(string content, string languageCode) 14 | { 15 | string translatedText = ""; 16 | 17 | HttpClient client = new HttpClient(); 18 | 19 | client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Common.CoreConstants.TranslatorTextSubscriptionKey); 20 | 21 | var result = await client.GetAsync(new Uri($"{Common.CoreConstants.TranslatorServicesBaseUrl}v2/Http.svc/Translate?text={Uri.EscapeDataString(content)}&to={languageCode}")); 22 | 23 | var resultDocument = await result.Content.ReadAsStringAsync(); 24 | 25 | System.Xml.XmlDocument xTranslation = new System.Xml.XmlDocument(); 26 | 27 | xTranslation.LoadXml(resultDocument); 28 | 29 | translatedText = xTranslation.InnerText; 30 | 31 | return translatedText; 32 | } 33 | 34 | private static async Task> GetTextTranslationLanguagesAsync() 35 | { 36 | HttpClient client = new HttpClient(); 37 | 38 | client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Common.CoreConstants.TranslatorTextSubscriptionKey); 39 | 40 | var result = await client.GetAsync(new Uri($"{Common.CoreConstants.TranslatorServicesBaseUrl}v2/Http.svc/GetLanguagesForTranslate")); 41 | 42 | var resultDocument = await result.Content.ReadAsStringAsync(); 43 | 44 | Windows.Data.Xml.Dom.XmlDocument languageDocument = new Windows.Data.Xml.Dom.XmlDocument(); 45 | 46 | languageDocument.LoadXml(resultDocument); 47 | 48 | var translationLanguages = (from node in languageDocument.DocumentElement.ChildNodes 49 | select node.InnerText).ToList(); 50 | 51 | return translationLanguages; 52 | } 53 | 54 | public static async Task> GetTextTranslationLanguageNamesAsync() 55 | { 56 | List translationLanguages = new List(); 57 | 58 | var languageAbbreviations = await Helpers.TranslationHelper.GetTextTranslationLanguagesAsync(); 59 | 60 | HttpClient client = new HttpClient(); 61 | 62 | client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Common.CoreConstants.TranslatorTextSubscriptionKey); 63 | 64 | var result = await client.GetAsync(new Uri($"{Common.CoreConstants.TranslatorServicesBaseUrl}v1/http.svc/GetLanguageNames")); 65 | 66 | var resultDocument = await result.Content.ReadAsStringAsync(); 67 | 68 | var languageNames = resultDocument.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 69 | 70 | for (int i = 0; i < languageAbbreviations.Count; i++) 71 | { 72 | translationLanguages.Add(new LanguageInformation() { DisplayName = languageNames[i], Abbreviation = languageAbbreviations[i] }); 73 | } 74 | 75 | return translationLanguages.OrderBy(o => o.DisplayName).ToList(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FlySim/FlySim/Images/FlySim_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/FlySim_back.jpg -------------------------------------------------------------------------------- /FlySim/FlySim/Images/PlaneViewBorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/PlaneViewBorder.png -------------------------------------------------------------------------------- /FlySim/FlySim/Images/PlaneViewHorizon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/PlaneViewHorizon.png -------------------------------------------------------------------------------- /FlySim/FlySim/Images/PlaneViewHorizon_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/PlaneViewHorizon_front.png -------------------------------------------------------------------------------- /FlySim/FlySim/Images/dashedarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/dashedarrow.png -------------------------------------------------------------------------------- /FlySim/FlySim/Images/horizon_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/horizon_border.png -------------------------------------------------------------------------------- /FlySim/FlySim/Images/planeimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/FlySim/FlySim/Images/planeimage.png -------------------------------------------------------------------------------- /FlySim/FlySim/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using FlySim.Helpers; 2 | using Microsoft.Toolkit.Uwp.UI.Extensions; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Runtime.InteropServices.WindowsRuntime; 8 | using Windows.Devices.Geolocation; 9 | using Windows.Foundation; 10 | using Windows.Foundation.Collections; 11 | using Windows.UI.Xaml; 12 | using Windows.UI.Xaml.Controls; 13 | using Windows.UI.Xaml.Controls.Maps; 14 | using Windows.UI.Xaml.Controls.Primitives; 15 | using Windows.UI.Xaml.Data; 16 | using Windows.UI.Xaml.Input; 17 | using Windows.UI.Xaml.Media; 18 | using Windows.UI.Xaml.Navigation; 19 | using System.Xml.Linq; 20 | using FlySim.Common; 21 | 22 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 23 | 24 | namespace FlySim 25 | { 26 | /// 27 | /// An empty page that can be used on its own or navigated to within a Frame. 28 | /// 29 | public sealed partial class MainPage : Page 30 | { 31 | public string MapServiceToken => Common.CoreConstants.MapServiceToken; 32 | 33 | public MainPage() 34 | { 35 | this.InitializeComponent(); 36 | this.Loaded += OnLoaded; 37 | } 38 | 39 | private void OnLoaded(object sender, RoutedEventArgs e) 40 | { 41 | if (App.ViewModel == null) 42 | { 43 | App.ViewModel = new MainViewModel(this.flightMap); 44 | 45 | App.ViewModel.InitializeSystem(); 46 | } 47 | 48 | this.DataContext = App.ViewModel; 49 | 50 | EnsureMapView(); 51 | } 52 | 53 | private async void EnsureMapView() 54 | { 55 | await System.Threading.Tasks.Task.Delay(2000); 56 | 57 | var toolbar = flightMap.FindDescendant(); 58 | if (toolbar != null) 59 | { 60 | toolbar.Visibility = Visibility.Collapsed; 61 | } 62 | 63 | var swapchainpanel = flightMap.FindDescendant(); 64 | (swapchainpanel?.Parent as Grid)?.AddMapOverlay(); 65 | 66 | flightMap.Style = MapStyle.Aerial3DWithRoads; 67 | } 68 | 69 | private void OnZoomChanged(MapControl sender, object args) 70 | { 71 | if (App.ViewModel != null) App.ViewModel.CurrentGridScale = flightMap.TryGetDistance(); 72 | } 73 | 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /FlySim/FlySim/Models/ActivePlaneInformation.cs: -------------------------------------------------------------------------------- 1 | using FlySim.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Geolocation; 8 | 9 | namespace FlySim 10 | { 11 | public class ActivePlaneInformation : Common.ObservableBase 12 | { 13 | private string _displayName; 14 | public string DisplayName 15 | { 16 | get => this._displayName; 17 | set => this.SetProperty(ref this._displayName, value); 18 | } 19 | 20 | private Geopoint _location; 21 | public Geopoint Location 22 | { 23 | get => this._location; 24 | set => this.SetProperty(ref this._location, value); 25 | } 26 | 27 | private long _lastUpdated; 28 | public long LastUpdated 29 | { 30 | get => this._lastUpdated; 31 | set => this.SetProperty(ref this._lastUpdated, value); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FlySim/FlySim/Models/FlightInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class FlightInformation : Common.ObservableBase 10 | { 11 | public FlightInformation(double altitude) 12 | { 13 | this.DisplayName = "(initializing...)"; 14 | this.CurrentAltitude = altitude; 15 | } 16 | 17 | private string _displayName; 18 | public string DisplayName 19 | { 20 | get => this._displayName; 21 | set => this.SetProperty(ref this._displayName, value); 22 | } 23 | 24 | private double _currentPitch; 25 | public double CurrentPitch 26 | { 27 | get => this._currentPitch; 28 | set => this.SetProperty(ref this._currentPitch, value); 29 | } 30 | 31 | private double _currentAltitude; 32 | public double CurrentAltitude 33 | { 34 | get => this._currentAltitude; 35 | set => this.SetProperty(ref this._currentAltitude, value); 36 | } 37 | 38 | private double _currentHeading; 39 | public double CurrentHeading 40 | { 41 | get => this._currentHeading; 42 | set => this.SetProperty(ref this._currentHeading, value); 43 | } 44 | 45 | private double _currentSpeed; 46 | public double CurrentSpeed 47 | { 48 | get => this._currentSpeed; 49 | set => this.SetProperty(ref this._currentSpeed, value); 50 | } 51 | 52 | private double _currentTemperature; 53 | public double CurrentTemperature 54 | { 55 | get => this._currentTemperature; 56 | set => this.SetProperty(ref this._currentTemperature, value); 57 | } 58 | 59 | private double _currentHumidity; 60 | public double CurrentHumidity 61 | { 62 | get => this._currentHumidity; 63 | set => this.SetProperty(ref this._currentHumidity, value); 64 | } 65 | 66 | private double _currentRoll; 67 | public double CurrentRoll 68 | { 69 | get => this._currentRoll; 70 | set => this.SetProperty(ref this._currentRoll, value); 71 | } 72 | 73 | 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /FlySim/FlySim/Models/LanguageInformation.cs: -------------------------------------------------------------------------------- 1 |  2 | using FlySim.Common; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace FlySim.Translation 10 | { 11 | public class LanguageInformation : ObservableBase 12 | { 13 | private string _displayName; 14 | public string DisplayName 15 | { 16 | get => _displayName; 17 | set => this.SetProperty(ref _displayName, value); 18 | } 19 | 20 | private string _abbreviation; 21 | public string Abbreviation 22 | { 23 | get => _abbreviation; 24 | set => this.SetProperty(ref _abbreviation, value); 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /FlySim/FlySim/Models/PlaneStatusInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FlySim 8 | { 9 | public class PlaneStatusInformation : Common.ObservableBase 10 | { 11 | private string _plane1; 12 | public string Plane1 13 | { 14 | get => this._plane1; 15 | set => this.SetProperty(ref this._plane1, value); 16 | } 17 | 18 | private string _plane2; 19 | public string Plane2 20 | { 21 | get => this._plane2; 22 | set => this.SetProperty(ref this._plane2, value); 23 | } 24 | 25 | private double _distance; 26 | public double Distance 27 | { 28 | get => this._distance; 29 | set => this.SetProperty(ref this._distance, value); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /FlySim/FlySim/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | FlySim 7 | codes 8 | Assets\StoreLogo.png 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FlySim/FlySim/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FlySim")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FlySim")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /FlySim/FlySim/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /FlySim/FlySim/ViewModels/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using System.Windows.Input; 7 | using Windows.Devices.Geolocation; 8 | using Windows.UI.Xaml.Controls.Maps; 9 | using FlySim.Common; 10 | using FlySim.Helpers; 11 | using FlySim.Translation; 12 | 13 | namespace FlySim 14 | { 15 | public class MainViewModel : ObservableBase 16 | { 17 | private ObservableCollection _activePlanes = 18 | new ObservableCollection(); 19 | 20 | private ObservableCollection _availableLanguages = 21 | new ObservableCollection(); 22 | 23 | private FlightInformation _currentFlightInformation = new FlightInformation(0); 24 | 25 | private double _currentGridScale; 26 | 27 | private DateTime _currentTime; 28 | 29 | private MapControl _flightMap; 30 | 31 | private double _planeRotation; 32 | 33 | private LanguageInformation _selectedLanguage; 34 | 35 | private FlightStatus _status; 36 | 37 | public List AtRiskPlanes = new List(); 38 | 39 | 40 | public MainViewModel(MapControl map) 41 | { 42 | FlightMap = map; 43 | 44 | InitializeClocks(); 45 | 46 | InitializePlanes(); 47 | 48 | InitializeLanguages(); 49 | } 50 | 51 | 52 | public ICommand TryCenterPlaneCommand { get; private set; } 53 | 54 | public TimerHelper CurrentClock { get; set; } 55 | 56 | public double CurrentGridScale 57 | { 58 | get => _currentGridScale; 59 | set => SetProperty(ref _currentGridScale, value); 60 | } 61 | 62 | public DateTime CurrentTime 63 | { 64 | get => _currentTime; 65 | set => SetProperty(ref _currentTime, value); 66 | } 67 | 68 | public FlightInformation CurrentFlightInformation 69 | { 70 | get => _currentFlightInformation; 71 | set => SetProperty(ref _currentFlightInformation, value); 72 | } 73 | 74 | public FlightStatus Status 75 | { 76 | get => _status; 77 | set => SetProperty(ref _status, value); 78 | } 79 | 80 | public MapControl FlightMap 81 | { 82 | get => _flightMap; 83 | set => SetProperty(ref _flightMap, value); 84 | } 85 | 86 | public double PlaneRotation 87 | { 88 | get => _planeRotation; 89 | set => SetProperty(ref _planeRotation, value); 90 | } 91 | 92 | public ObservableCollection ActivePlanes 93 | { 94 | get => _activePlanes; 95 | set => SetProperty(ref _activePlanes, value); 96 | } 97 | 98 | public LanguageInformation SelectedLanguage 99 | { 100 | get => _selectedLanguage; 101 | set => SetProperty(ref _selectedLanguage, value); 102 | } 103 | 104 | public ObservableCollection AvailableLanguages 105 | { 106 | get => _availableLanguages; 107 | set => SetProperty(ref _availableLanguages, value); 108 | } 109 | 110 | internal async void BringPlaneIntoView(double latitude, double longitude) 111 | { 112 | await FlightMap.TrySetViewAsync(new Geopoint(new BasicGeoposition 113 | { 114 | Latitude = latitude, 115 | Longitude = longitude 116 | }), CoreConstants.InitialZoomLevel); 117 | 118 | this.CurrentGridScale = this.FlightMap.TryGetDistance(); 119 | } 120 | 121 | public void InitializeSystem() 122 | { 123 | } 124 | 125 | private void InitializeClocks() 126 | { 127 | CurrentClock = new TimerHelper(); 128 | CurrentClock.StartClock(); 129 | 130 | CurrentTime = DateTime.Now.ToLocalTime(); 131 | } 132 | 133 | private void InitializePlanes() 134 | { 135 | ActivePlanes.Add(new ActivePlaneInformation 136 | { 137 | DisplayName = "...", 138 | Location = new Geopoint(CoreConstants.DefaultStartingLocation) 139 | }); 140 | 141 | TryCenterPlaneCommand = new RelayCommand(async () => { await TryCenterPlaneAsync(); }); 142 | } 143 | 144 | public async void InitializeLanguages() 145 | { 146 | var languages = await TranslationHelper.GetTextTranslationLanguageNamesAsync(); 147 | 148 | AvailableLanguages.Clear(); 149 | 150 | foreach (var language in languages) 151 | AvailableLanguages.Add(language); 152 | 153 | SelectedLanguage = AvailableLanguages.FirstOrDefault(w => 154 | w.DisplayName.Equals("English", StringComparison.OrdinalIgnoreCase)); 155 | } 156 | 157 | public void SetFlightStatus(string deviceId) 158 | { 159 | var oldStatus = Status; 160 | 161 | Status = AtRiskPlanes.Contains(deviceId, StringComparer.OrdinalIgnoreCase) 162 | ? FlightStatus.AtRisk 163 | : FlightStatus.Ok; 164 | 165 | if (oldStatus == FlightStatus.Ok && Status == FlightStatus.AtRisk) 166 | SendWarningMessage(); 167 | } 168 | 169 | private async void SendWarningMessage() 170 | { 171 | var message = "Warning"; 172 | 173 | if (!SelectedLanguage.DisplayName.Equals("English")) 174 | message = await TranslationHelper.GetTextTranslationAsync(message, SelectedLanguage.Abbreviation); 175 | } 176 | 177 | public async Task TryCenterPlaneAsync() 178 | { 179 | var activePlane = ActivePlanes.FirstOrDefault(); 180 | 181 | if (activePlane != null) 182 | await FlightMap.TrySetViewAsync(activePlane.Location, 8.0); 183 | } 184 | } 185 | } -------------------------------------------------------------------------------- /FlySimEmbedded/.iotworkbenchproject: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /FlySimEmbedded/.vscode/arduino.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "AZ3166:stm32f4:MXCHIP_AZ3166", 3 | "sketch": "FlySim.ino", 4 | "configuration": "upload_method=OpenOCDMethod", 5 | "output": "./.build" 6 | } -------------------------------------------------------------------------------- /FlySimEmbedded/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | ".build": true, 4 | ".iotworkbenchproject": true 5 | } 6 | } -------------------------------------------------------------------------------- /FlySimEmbedded/FlySim.ino: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. 3 | // To get started please visit https://microsoft.github.io/azure-iot-developer-kit/docs/projects/connect-iot-hub?utm_source=ArduinoExtension&utm_medium=ReleaseNote&utm_campaign=VSCode 4 | #include "AZ3166WiFi.h" 5 | #include "AzureIotHub.h" 6 | #include "DevKitMQTTClient.h" 7 | 8 | #include "config.h" 9 | #include "utility.h" 10 | #include "SystemTickCounter.h" 11 | 12 | static bool hasWifi = false; 13 | int messageCount = 1; 14 | static bool messageSending = true; 15 | static uint64_t send_interval_ms; 16 | 17 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 18 | // Utilities 19 | void initWifi() 20 | { 21 | Screen.print("IoT DevKit\r\n \r\nConnecting...\r\n"); 22 | 23 | if (WiFi.begin() == WL_CONNECTED) 24 | { 25 | IPAddress ip = WiFi.localIP(); 26 | Screen.print(1, ip.get_address()); 27 | hasWifi = true; 28 | Screen.print(2, "Running... \r\n"); 29 | } 30 | else 31 | { 32 | Screen.print(1, "No Wi-Fi\r\n "); 33 | } 34 | } 35 | 36 | static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result) 37 | { 38 | if (IOTHUB_CLIENT_CONFIRMATION_OK == result) 39 | { 40 | LogInfo("Flight data received by your Azure IoT Hub successfully."); 41 | blinkSendConfirmation(); 42 | } 43 | else 44 | { 45 | LogInfo("Failed to send flight data to your Azure IoT Hub."); 46 | } 47 | } 48 | 49 | static void sendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result) 50 | { 51 | if (result == IOTHUB_CLIENT_CONFIRMATION_OK) 52 | { 53 | blinkSendConfirmation(); 54 | } 55 | } 56 | 57 | static void messageCallback(const char* payLoad, int size) 58 | { 59 | char buff[128]; 60 | 61 | //Get the flight status coming from Azure 62 | snprintf(buff, 128, "FLIGHT WARNING\r\n \r\n %s \r\n \r\n", payLoad); 63 | Screen.print(buff); 64 | 65 | LogInfo("Message received from the Azure IoT Portal: %s", payLoad); 66 | 67 | //Show message with LED for a while 68 | for (int i = 0; i < 5; i++) 69 | { 70 | blinkLED(); 71 | delay(500); 72 | } 73 | } 74 | 75 | int deviceMethodCallback(const char *methodName, const unsigned char *payload, int size, unsigned char **response, int *response_size) 76 | { 77 | LogInfo("Try to invoke method %s", methodName); 78 | const char *responseMessage = "\"Successfully invoke device method\""; 79 | int result = 200; 80 | 81 | if (strcmp(methodName, "start") == 0) 82 | { 83 | LogInfo("Starting transmission of flight data..."); 84 | messageSending = true; 85 | } 86 | else if (strcmp(methodName, "stop") == 0) 87 | { 88 | LogInfo("Stopping transmision of flight data..."); 89 | messageSending = false; 90 | } 91 | else 92 | { 93 | LogInfo("No method %s found", methodName); 94 | responseMessage = "\"No method found\""; 95 | result = 404; 96 | } 97 | 98 | *response_size = strlen(responseMessage); 99 | *response = (unsigned char *)malloc(*response_size); 100 | strncpy((char *)(*response), responseMessage, *response_size); 101 | 102 | return result; 103 | } 104 | 105 | static void deviceTwinCallback(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char *payLoad, int size) 106 | { 107 | char *temp = (char *)malloc(size + 1); 108 | if (temp == NULL) 109 | { 110 | return; 111 | } 112 | memcpy(temp, payLoad, size); 113 | temp[size] = '\0'; 114 | parseTwinMessage(updateState, temp); 115 | free(temp); 116 | } 117 | 118 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 119 | // Arduino sketch 120 | void setup() 121 | { 122 | Screen.init(); 123 | Screen.print(0, "IoT DevKit"); 124 | Screen.print(2, "Initializing..."); 125 | 126 | Screen.print(3, " > Serial"); 127 | Serial.begin(115200); 128 | 129 | hasWifi = false; 130 | Screen.print(3, " > WiFi"); 131 | initWifi(); 132 | if (!hasWifi) 133 | { 134 | LogInfo("Please make sure the wifi connected!"); 135 | return; 136 | } 137 | 138 | LogTrace("FlySim", NULL); 139 | 140 | Screen.print(3, " > Sensors"); 141 | sensorInit(); 142 | 143 | Screen.print(3, " > IoT Hub"); 144 | DevKitMQTTClient_Init(true); 145 | 146 | DevKitMQTTClient_SetSendConfirmationCallback(sendConfirmationCallback); 147 | DevKitMQTTClient_SetMessageCallback(messageCallback); 148 | DevKitMQTTClient_SetDeviceTwinCallback(deviceTwinCallback); 149 | DevKitMQTTClient_SetDeviceMethodCallback(deviceMethodCallback); 150 | } 151 | 152 | void loop() 153 | { 154 | if (hasWifi) 155 | { 156 | if (messageSending && 157 | (int)(SystemTickCounterRead() - send_interval_ms) >= getInterval()) 158 | { 159 | char messagePayload[MESSAGE_MAX_LEN]; 160 | 161 | bool temperatureAlert = readMessage(messageCount++, messagePayload, MESSAGE_MAX_LEN); 162 | LogInfo("Sending flight data: %s", messagePayload); 163 | EVENT_INSTANCE* message = DevKitMQTTClient_Event_Generate(messagePayload, MESSAGE); 164 | DevKitMQTTClient_Event_AddProp(message, "temperatureAlert", temperatureAlert ? "true" : "false"); 165 | if (DevKitMQTTClient_SendEventInstance(message)) 166 | { 167 | LogInfo("Flight data sent to your Azure IoT Hub successfully."); 168 | } 169 | else 170 | { 171 | LogInfo("Failed to send flight data to your Azure IoT Hub."); 172 | } 173 | 174 | send_interval_ms = SystemTickCounterRead(); 175 | } 176 | else 177 | { 178 | DevKitMQTTClient_Check(); 179 | } 180 | } 181 | delay(10); 182 | } 183 | -------------------------------------------------------------------------------- /FlySimEmbedded/config.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | // Interval time(ms) for sending message to IoT Hub 5 | #define INTERVAL 500 6 | 7 | #define MESSAGE_MAX_LEN 256 8 | 9 | #define DISPLAY_NAME "YOUR_DISPLAY_NAME" 10 | 11 | #define TEMPERATURE_ALERT 30 -------------------------------------------------------------------------------- /FlySimEmbedded/utility.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | #include "Arduino.h" 5 | #include "AzureIotHub.h" 6 | 7 | #include "HTS221Sensor.h" 8 | #include "LSM6DSLSensor.h" 9 | #include "RGB_LED.h" 10 | 11 | #include "parson.h" 12 | #include "config.h" 13 | 14 | #define RGB_LED_BRIGHTNESS 32 15 | 16 | DevI2C *i2c; 17 | HTS221Sensor *sensor; 18 | LSM6DSLSensor *acc_gyro; 19 | static RGB_LED rgbLed; 20 | static int interval = INTERVAL; 21 | int axes[3]; 22 | float xMovement; 23 | float yMovement; 24 | float zMovement; 25 | 26 | int getInterval() 27 | { 28 | return interval; 29 | } 30 | 31 | void blinkLEDLonger() 32 | { 33 | rgbLed.turnOff(); 34 | rgbLed.setColor(RGB_LED_BRIGHTNESS, 0, 0); 35 | delay(5000); 36 | rgbLed.turnOff(); 37 | } 38 | 39 | void blinkLED() 40 | { 41 | rgbLed.turnOff(); 42 | rgbLed.setColor(RGB_LED_BRIGHTNESS, 0, 0); 43 | delay(500); 44 | rgbLed.turnOff(); 45 | } 46 | 47 | void blinkSendConfirmation() 48 | { 49 | rgbLed.turnOff(); 50 | rgbLed.setColor(0, 0, RGB_LED_BRIGHTNESS); 51 | delay(500); 52 | rgbLed.turnOff(); 53 | } 54 | 55 | void parseTwinMessage(DEVICE_TWIN_UPDATE_STATE updateState, const char *message) 56 | { 57 | JSON_Value *root_value; 58 | root_value = json_parse_string(message); 59 | if (json_value_get_type(root_value) != JSONObject) 60 | { 61 | if (root_value != NULL) 62 | { 63 | json_value_free(root_value); 64 | } 65 | LogError("parse %s failed", message); 66 | return; 67 | } 68 | JSON_Object *root_object = json_value_get_object(root_value); 69 | 70 | double val = 0; 71 | if (updateState == DEVICE_TWIN_UPDATE_COMPLETE) 72 | { 73 | JSON_Object *desired_object = json_object_get_object(root_object, "desired"); 74 | if (desired_object != NULL) 75 | { 76 | val = json_object_get_number(desired_object, "interval"); 77 | } 78 | } 79 | else 80 | { 81 | val = json_object_get_number(root_object, "interval"); 82 | } 83 | if (val > 500) 84 | { 85 | interval = (int)val; 86 | LogInfo(">>>Device twin updated: set interval to %d", interval); 87 | } 88 | json_value_free(root_value); 89 | } 90 | 91 | void sensorInit() 92 | { 93 | i2c = new DevI2C(D14, D15); 94 | 95 | acc_gyro = new LSM6DSLSensor(*i2c, D4, D5); 96 | acc_gyro->init(NULL); 97 | acc_gyro->enableAccelerator(); 98 | acc_gyro->enableGyroscope(); 99 | 100 | sensor = new HTS221Sensor(*i2c); 101 | sensor->init(NULL); 102 | } 103 | 104 | void setMotionGyroSensor() 105 | { 106 | acc_gyro->getXAxes(axes); 107 | char buff[128]; 108 | 109 | xMovement = axes[0]; 110 | yMovement = axes[1]; 111 | zMovement = axes[2]; 112 | 113 | snprintf(buff, 128, "IN FLIGHT: \r\n x:%d \r\n y:%d \r\n z:%d ", axes[0], axes[1], axes[2]); 114 | Screen.print(buff); 115 | } 116 | 117 | float readTemperature() 118 | { 119 | sensor->reset(); 120 | 121 | float temperature = 0; 122 | sensor->getTemperature(&temperature); 123 | 124 | return temperature; 125 | } 126 | 127 | float readHumidity() 128 | { 129 | sensor->reset(); 130 | 131 | float humidity = 0; 132 | sensor->getHumidity(&humidity); 133 | 134 | return humidity; 135 | } 136 | 137 | float readXMovement() 138 | { 139 | 140 | return xMovement; 141 | } 142 | 143 | float readYMovement() 144 | { 145 | 146 | return yMovement; 147 | } 148 | 149 | float readZMovement() 150 | { 151 | 152 | return zMovement; 153 | } 154 | 155 | bool readMessage(int messageId, char *payload, size_t len) 156 | { 157 | float temperature = readTemperature(); 158 | float humidity = readHumidity(); 159 | 160 | setMotionGyroSensor(); 161 | 162 | float xMovement = readXMovement(); 163 | float yMovement = readYMovement(); 164 | float zMovement = readZMovement(); 165 | 166 | JSON_Value *root_value = json_value_init_object(); 167 | JSON_Object *root_object = json_value_get_object(root_value); 168 | 169 | json_object_set_string(root_object, "deviceId", DISPLAY_NAME); 170 | json_object_set_number(root_object, "messageId", messageId); 171 | 172 | bool temperatureAlert = false; 173 | 174 | time_t rawtime; 175 | struct tm * timeinfo; 176 | char buffer [80]; 177 | time (&rawtime); 178 | timeinfo = localtime (&rawtime); 179 | strftime (buffer, 80,"%m/%d/%y %H:%M:%S",timeinfo); 180 | 181 | json_object_set_string(root_object, "timestamp", buffer); 182 | 183 | json_object_set_number(root_object, "temperature", ceil(temperature)); 184 | if(temperature > TEMPERATURE_ALERT) 185 | { 186 | temperatureAlert = true; 187 | } 188 | 189 | json_object_set_number(root_object, "humidity", ceil(humidity)); 190 | 191 | json_object_set_number(root_object, "x", xMovement); 192 | json_object_set_number(root_object, "y", yMovement); 193 | json_object_set_number(root_object, "z", zMovement); 194 | 195 | char *serialized_string = json_serialize_to_string(root_value); 196 | 197 | strncpy(payload, serialized_string, len); 198 | payload[len - 1] = 0; 199 | 200 | json_free_serialized_string(serialized_string); 201 | json_value_free(root_value); 202 | 203 | return temperatureAlert; 204 | } -------------------------------------------------------------------------------- /FlySimEmbedded/utility.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. 3 | 4 | #ifndef UTILITY_H 5 | #define UTILITY_H 6 | 7 | void parseTwinMessage(DEVICE_TWIN_UPDATE_STATE, const char *); 8 | bool readMessage(int, char *, size_t); 9 | 10 | void sensorInit(void); 11 | 12 | void blinkLED(void); 13 | void blinkLEDLonger(void); 14 | void blinkSendConfirmation(void); 15 | int getInterval(void); 16 | 17 | #endif /* UTILITY_H */ -------------------------------------------------------------------------------- /FlySimFunctions/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Azure Functions localsettings file 5 | local.settings.json 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | project.fragment.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # NCrunch 117 | _NCrunch_* 118 | .*crunch*.local.xml 119 | nCrunchTemp_* 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | # TODO: Comment the next line if you want to checkin your web deploy settings 148 | # but database connection strings (with potential passwords) will be unencrypted 149 | #*.pubxml 150 | *.publishproj 151 | 152 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 153 | # checkin your Azure Web App publish settings, but sensitive information contained 154 | # in these scripts will be unencrypted 155 | PublishScripts/ 156 | 157 | # NuGet Packages 158 | *.nupkg 159 | # The packages folder can be ignored because of Package Restore 160 | **/packages/* 161 | # except build/, which is used as an MSBuild target. 162 | !**/packages/build/ 163 | # Uncomment if necessary however generally it will be regenerated when needed 164 | #!**/packages/repositories.config 165 | # NuGet v3's project.json files produces more ignoreable files 166 | *.nuget.props 167 | *.nuget.targets 168 | 169 | # Microsoft Azure Build Output 170 | csx/ 171 | *.build.csdef 172 | 173 | # Microsoft Azure Emulator 174 | ecf/ 175 | rcf/ 176 | 177 | # Windows Store app package directories and files 178 | AppPackages/ 179 | BundleArtifacts/ 180 | Package.StoreAssociation.xml 181 | _pkginfo.txt 182 | 183 | # Visual Studio cache files 184 | # files ending in .cache can be ignored 185 | *.[Cc]ache 186 | # but keep track of directories ending in .cache 187 | !*.[Cc]ache/ 188 | 189 | # Others 190 | ClientBin/ 191 | ~$* 192 | *~ 193 | *.dbmdl 194 | *.dbproj.schemaview 195 | *.jfm 196 | *.pfx 197 | *.publishsettings 198 | node_modules/ 199 | orleans.codegen.cs 200 | 201 | # Since there are multiple workflows, uncomment next line to ignore bower_components 202 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 203 | #bower_components/ 204 | 205 | # RIA/Silverlight projects 206 | Generated_Code/ 207 | 208 | # Backup & report files from converting an old project file 209 | # to a newer Visual Studio version. Backup files are not needed, 210 | # because we have git ;-) 211 | _UpgradeReport_Files/ 212 | Backup*/ 213 | UpgradeLog*.XML 214 | UpgradeLog*.htm 215 | 216 | # SQL Server files 217 | *.mdf 218 | *.ldf 219 | 220 | # Business Intelligence projects 221 | *.rdl.data 222 | *.bim.layout 223 | *.bim_*.settings 224 | 225 | # Microsoft Fakes 226 | FakesAssemblies/ 227 | 228 | # GhostDoc plugin setting file 229 | *.GhostDoc.xml 230 | 231 | # Node.js Tools for Visual Studio 232 | .ntvs_analysis.dat 233 | 234 | # Visual Studio 6 build log 235 | *.plg 236 | 237 | # Visual Studio 6 workspace options file 238 | *.opt 239 | 240 | # Visual Studio LightSwitch build output 241 | **/*.HTMLClient/GeneratedArtifacts 242 | **/*.DesktopClient/GeneratedArtifacts 243 | **/*.DesktopClient/ModelManifest.xml 244 | **/*.Server/GeneratedArtifacts 245 | **/*.Server/ModelManifest.xml 246 | _Pvt_Extensions 247 | 248 | # Paket dependency manager 249 | .paket/paket.exe 250 | paket-files/ 251 | 252 | # FAKE - F# Make 253 | .fake/ 254 | 255 | # JetBrains Rider 256 | .idea/ 257 | *.sln.iml 258 | 259 | # CodeRush 260 | .cr/ 261 | 262 | # Python Tools for Visual Studio (PTVS) 263 | __pycache__/ 264 | *.pyc -------------------------------------------------------------------------------- /FlySimFunctions/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-azuretools.vscode-azurefunctions", 4 | "ms-vscode.csharp" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /FlySimFunctions/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Attach to C# Functions", 6 | "type": "coreclr", 7 | "request": "attach", 8 | "processId": "${command:azureFunctions.pickProcess}" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /FlySimFunctions/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "azureFunctions.projectRuntime": "~2", 3 | "azureFunctions.projectLanguage": "C#", 4 | "azureFunctions.templateFilter": "Verified", 5 | "azureFunctions.deploySubpath": "bin/Release/netcoreapp2.1/publish", 6 | "azureFunctions.preDeployTask": "publish", 7 | "debug.internalConsoleOptions": "neverOpen" 8 | } 9 | -------------------------------------------------------------------------------- /FlySimFunctions/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "clean", 6 | "command": "dotnet clean", 7 | "type": "shell", 8 | "problemMatcher": "$msCompile" 9 | }, 10 | { 11 | "label": "build", 12 | "command": "dotnet build", 13 | "type": "shell", 14 | "dependsOn": "clean", 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | }, 19 | "problemMatcher": "$msCompile" 20 | }, 21 | { 22 | "label": "clean release", 23 | "command": "dotnet clean --configuration Release", 24 | "type": "shell", 25 | "problemMatcher": "$msCompile" 26 | }, 27 | { 28 | "label": "publish", 29 | "command": "dotnet publish --configuration Release", 30 | "type": "shell", 31 | "dependsOn": "clean release", 32 | "problemMatcher": "$msCompile" 33 | }, 34 | { 35 | "label": "runFunctionsHost", 36 | "type": "shell", 37 | "dependsOn": "build", 38 | "options": { 39 | "cwd": "${workspaceFolder}/bin/Debug/netcoreapp2.1" 40 | }, 41 | "command": "func host start", 42 | "isBackground": true, 43 | "problemMatcher": "$func-watch" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /FlySimFunctions/FlySimIoTFlightData.cs: -------------------------------------------------------------------------------- 1 | using IoTHubTrigger = Microsoft.Azure.WebJobs.EventHubTriggerAttribute; 2 | 3 | using Microsoft.Azure.WebJobs; 4 | using Microsoft.Azure.WebJobs.Host; 5 | using Microsoft.Azure.EventHubs; 6 | using Newtonsoft.Json; 7 | using Newtonsoft.Json.Converters; 8 | using System; 9 | using System.Threading.Tasks; 10 | using System.Text; 11 | using System.Net.Http; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace FlySimFunctions 15 | { 16 | public static class FlySimIoTFlightData 17 | { 18 | private static HttpClient client = new HttpClient(); 19 | 20 | private static DateTime? _last = null; 21 | private static double _airspeed = 384.0; 22 | private static double _heading = 0.0; 23 | private static double _altitude = 32000.0; 24 | private static double _latitude = 37.242; 25 | private static double _longitude = -115.8190; 26 | private static double _pitch = 0.0; 27 | private static double _roll = 0.0; 28 | 29 | [FunctionName("FlySimIoTFlightData")] 30 | public async static Task Run([IoTHubTrigger("%eventHubConnectionPath%", Connection = "eventHubConnectionString")]EventData message, [EventHub("flysim", Connection = "cloudcityEventHubConnection")] IAsyncCollector outputMessage, ILogger log) 31 | { 32 | log.LogInformation($"C# IoT Hub trigger function processed a message: {Encoding.UTF8.GetString(message.Body.Array)}"); 33 | 34 | var converter = new IsoDateTimeConverter { DateTimeFormat = "MM/dd/yy HH:mm:ss" }; 35 | var input = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Body.Array), converter); 36 | var outputPayload = ""; 37 | if (_last != null && input.timestamp > _last.Value) 38 | { 39 | // Compute milliseconds elapsed since last event was received 40 | var milliseconds = (input.timestamp - _last.Value).TotalMilliseconds; 41 | _last = input.timestamp; 42 | 43 | // Constrain pitch to +/-15 degrees (positive == nose down) 44 | _pitch = Math.Max(Math.Min(input.y / 11.0, 15.0), -15.0); 45 | 46 | // Constrain roll to +/-30 degrees (positive == rolling right) 47 | _roll = Math.Max(Math.Min(input.x / 11.0, 30.0), -30.0); 48 | 49 | // Compute new heading assuming hard left or right turns 10 degrees per second 50 | var delta = (milliseconds / 100.0) * (_roll / 30.0); 51 | _heading += delta; 52 | 53 | if (_heading < 0.0) 54 | _heading += 360.0; 55 | else if (_heading >= 360.0) 56 | _heading -= 360.0; 57 | 58 | // Compute new latitude and longitude 59 | var radians = _heading * Math.PI / 180.0; 60 | var distance = (milliseconds / 1000) * (_airspeed * 0.000277778); // 1 MPH == 0.000277778 miles per second 61 | var dx = distance * Math.Sin(radians); 62 | var dy = distance * Math.Cos(radians); 63 | _latitude += (dy / 69.0); // Assume 69 miles per 1 degree of latitude 64 | _longitude += (dx / 69.0); // Assume 69 miles per 1 degree of longitude 65 | 66 | // Compute new altitude and constrain it to 1,000 to 40,000 feet 67 | _altitude = _altitude - (distance * 5280.0 * Math.Sin(_pitch * Math.PI / 180.0)); 68 | _altitude = Math.Max(Math.Min(_altitude, 40000.0), 1000.0); 69 | 70 | // Send JSON output 71 | var output = new Output { deviceId = input.deviceId, timestamp = input.timestamp, temperature = input.temperature, humidity = input.humidity, airspeed = _airspeed, altitude = _altitude, heading = _heading, latitude = _latitude, longitude = _longitude, pitch = _pitch, roll = _roll }; 72 | outputPayload = JsonConvert.SerializeObject(output); 73 | } 74 | else 75 | { 76 | // This is the first event received, so compute initial parameters 77 | _last = input.timestamp; 78 | 79 | var hash = (uint)input.deviceId.GetHashCode(); 80 | _heading = hash % 360; 81 | _altitude = 10000.0 + ((hash % 25) * 1000); 82 | _latitude = 36.7 + ((double)((hash / 100) % 100) / 100.0); 83 | _longitude = -116.8 + ((double)(hash % 100) / 50.0); 84 | 85 | var output = new Output { deviceId = input.deviceId, timestamp = input.timestamp, temperature = input.temperature, humidity = input.humidity, airspeed = _airspeed, altitude = _altitude, heading = _heading, latitude = _latitude, longitude = _longitude, pitch = _pitch, roll = _roll }; 86 | outputPayload = JsonConvert.SerializeObject(output); 87 | 88 | log.LogInformation("First event received"); 89 | } 90 | 91 | await outputMessage.AddAsync(outputPayload); 92 | log.LogInformation(String.Format("Heading={0}, Altitude={1}, Latitude={2}, Longitude={3}", _heading, _altitude, _latitude, _longitude)); 93 | return; 94 | } 95 | } 96 | 97 | class Input 98 | { 99 | public string deviceId; 100 | public DateTime timestamp; 101 | public string messageId; 102 | public double temperature; 103 | public double humidity; 104 | public double x; 105 | public double y; 106 | public double z; 107 | } 108 | 109 | class Output 110 | { 111 | public string deviceId; 112 | public DateTime timestamp; 113 | public double airspeed; 114 | public double heading; 115 | public double altitude; 116 | public double latitude; 117 | public double longitude; 118 | public double pitch; 119 | public double roll; 120 | public double temperature; 121 | public double humidity; 122 | } 123 | } -------------------------------------------------------------------------------- /FlySimFunctions/Functions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netcoreapp2.1 4 | v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | PreserveNewest 13 | 14 | 15 | PreserveNewest 16 | Never 17 | 18 | 19 | -------------------------------------------------------------------------------- /FlySimFunctions/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0" 3 | } -------------------------------------------------------------------------------- /FlySimTest/FlySimTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.6 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlySimTest", "FlySimTest\FlySimTest.csproj", "{8F34A5FC-BB47-41FF-B9A5-F2DB479709AC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8F34A5FC-BB47-41FF-B9A5-F2DB479709AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8F34A5FC-BB47-41FF-B9A5-F2DB479709AC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8F34A5FC-BB47-41FF-B9A5-F2DB479709AC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8F34A5FC-BB47-41FF-B9A5-F2DB479709AC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /FlySimTest/FlySimTest/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FlySimTest/FlySimTest/FlySimTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8F34A5FC-BB47-41FF-B9A5-F2DB479709AC} 8 | Exe 9 | FlySimTest 10 | FlySimTest 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\Microsoft.Azure.Amqp.2.1.1\lib\net45\Microsoft.Azure.Amqp.dll 37 | 38 | 39 | ..\packages\Microsoft.Azure.EventHubs.1.0.3\lib\net451\Microsoft.Azure.EventHubs.dll 40 | 41 | 42 | ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /FlySimTest/FlySimTest/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.EventHubs; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace FlySimTest 10 | { 11 | class Program 12 | { 13 | static int _count = 20; 14 | static List _airplanes = new List(); 15 | static EventHubClient _client; 16 | 17 | static void Main(string[] args) 18 | { 19 | Task.Run(async () => { await Test(args); }).GetAwaiter().GetResult(); 20 | } 21 | 22 | static async Task Test(string[] args) 23 | { 24 | if (args.Length > 0) 25 | { 26 | try 27 | { 28 | _count = Convert.ToInt32(args[0]); 29 | } 30 | catch (Exception) 31 | { 32 | Console.WriteLine("Usage: FlySimLoadTest [count]"); 33 | } 34 | } 35 | 36 | for (int i = 0; i < _count; i++) 37 | { 38 | var airplane = new Airplane(); 39 | airplane.deviceId = Guid.NewGuid().ToString().Substring(24, 12); 40 | var hash = (uint)airplane.deviceId.GetHashCode(); 41 | airplane.heading = hash % 360; 42 | airplane.altitude = 30000.0 + ((hash % 5) * 1000); // All planes within 5,000 feet for testing 43 | airplane.latitude = 36.7 + ((double)((hash / 100) % 100) / 100.0); 44 | airplane.longitude = -116.8 + ((double)(hash % 100) / 50.0); 45 | airplane.airspeed = 384.0; 46 | airplane.pitch = 0.0; 47 | airplane.roll = 0.0; 48 | airplane.timestamp = DateTime.Now; 49 | airplane.temperature = 72.0; 50 | airplane.humidity = 50.0; 51 | _airplanes.Add(airplane); 52 | } 53 | 54 | _client = EventHubClient.CreateFromConnectionString("SHARED_EVENT_HUB_ENDPOINT;EntityPath=flysim-shared-input-hub"); 55 | 56 | while (true) 57 | { 58 | foreach (var airplane in _airplanes) 59 | { 60 | var result = TransmitFlightDataAsync(airplane); // Do not await 61 | Console.WriteLine(String.Format("Name={0}, Latitude={1}, Longitude={2}", 62 | airplane.deviceId, airplane.latitude, airplane.longitude)); 63 | } 64 | 65 | Console.WriteLine(); 66 | await Task.Delay(2000); 67 | 68 | foreach (var airplane in _airplanes) 69 | { 70 | UpdateFlightData(airplane); 71 | } 72 | } 73 | } 74 | 75 | static async Task TransmitFlightDataAsync(Airplane airplane) 76 | { 77 | var message = JsonConvert.SerializeObject(airplane); 78 | await _client.SendAsync(new EventData(Encoding.UTF8.GetBytes(message))); 79 | } 80 | 81 | static void UpdateFlightData(Airplane airplane) 82 | { 83 | var now = DateTime.Now; 84 | var milliseconds = (now - airplane.timestamp).TotalMilliseconds; 85 | var radians = airplane.heading * Math.PI / 180.0; 86 | var distance = (milliseconds / 1000) * (airplane.airspeed * 0.000277778); // 1 MPH == 0.000277778 miles per second 87 | var dx = distance * Math.Sin(radians); 88 | var dy = distance * Math.Cos(radians); 89 | airplane.latitude += (dy / 69.0); // Assume 69 miles per 1 degree of latitude 90 | airplane.longitude += (dx / 69.0); // Assume 69 miles per 1 degree of longitude 91 | airplane.timestamp = now; 92 | } 93 | } 94 | 95 | class Airplane 96 | { 97 | public string deviceId; 98 | public DateTime timestamp; 99 | public double airspeed; 100 | public double heading; 101 | public double altitude; 102 | public double latitude; 103 | public double longitude; 104 | public double pitch; 105 | public double roll; 106 | public double temperature; 107 | public double humidity; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /FlySimTest/FlySimTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FlySimTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FlySimTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8f34a5fc-bb47-41ff-b9a5-f2db479709ac")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FlySimTest/FlySimTest/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /HOL 1/Images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/architecture.png -------------------------------------------------------------------------------- /HOL 1/Images/atc-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/atc-app.png -------------------------------------------------------------------------------- /HOL 1/Images/cable-and-chip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/cable-and-chip.png -------------------------------------------------------------------------------- /HOL 1/Images/chip-in-flight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/chip-in-flight.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-cloud-provision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-cloud-provision.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-connection-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-connection-done.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-device-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-device-settings.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-device-string1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-device-string1.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-device-upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-device-upload.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-examples-board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-examples-board.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-examples-cmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-examples-cmd.png -------------------------------------------------------------------------------- /HOL 1/Images/iot-workbench-examples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/iot-workbench-examples.png -------------------------------------------------------------------------------- /HOL 1/Images/open-iot-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/open-iot-hub.png -------------------------------------------------------------------------------- /HOL 1/Images/open-resource-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/open-resource-group.png -------------------------------------------------------------------------------- /HOL 1/Images/open-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/open-workspace.png -------------------------------------------------------------------------------- /HOL 1/Images/portal-device-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/portal-device-explorer.png -------------------------------------------------------------------------------- /HOL 1/Images/portal-enter-device-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/portal-enter-device-login.png -------------------------------------------------------------------------------- /HOL 1/Images/portal-hub-usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/portal-hub-usage.png -------------------------------------------------------------------------------- /HOL 1/Images/view-ssid-and-ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/view-ssid-and-ip.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-azure-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-azure-login.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-board-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-board-manager.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-check-board-installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-check-board-installed.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-click-baud-rate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-click-baud-rate.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-click-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-click-connect.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-enter-display-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-enter-display-name.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-getting-started.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-getting-started.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-install-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-install-json.png -------------------------------------------------------------------------------- /HOL 1/Images/vs-viewing-com-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vs-viewing-com-data.png -------------------------------------------------------------------------------- /HOL 1/Images/vscode-open-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 1/Images/vscode-open-example.png -------------------------------------------------------------------------------- /HOL 2/Images/add-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/add-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/app-ascending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/app-ascending.png -------------------------------------------------------------------------------- /HOL 2/Images/app-in-flight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/app-in-flight.png -------------------------------------------------------------------------------- /HOL 2/Images/app-turning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/app-turning.png -------------------------------------------------------------------------------- /HOL 2/Images/chip-in-flight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/chip-in-flight.png -------------------------------------------------------------------------------- /HOL 2/Images/create-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/create-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/create-namespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/create-namespace.png -------------------------------------------------------------------------------- /HOL 2/Images/event_hub_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/event_hub_instance.png -------------------------------------------------------------------------------- /HOL 2/Images/flysim-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/flysim-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/function_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/function_settings.png -------------------------------------------------------------------------------- /HOL 2/Images/iot-workbench-cloud-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/iot-workbench-cloud-deploy.png -------------------------------------------------------------------------------- /HOL 2/Images/new-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/new-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/open-event-hub-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/open-event-hub-2.png -------------------------------------------------------------------------------- /HOL 2/Images/open-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/open-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/open-function-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/open-function-app.png -------------------------------------------------------------------------------- /HOL 2/Images/open-iot-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/open-iot-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/open-resource-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/open-resource-group.png -------------------------------------------------------------------------------- /HOL 2/Images/portal-click-event-hub-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/portal-click-event-hub-policy.png -------------------------------------------------------------------------------- /HOL 2/Images/portal-click-iot-endpoints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/portal-click-iot-endpoints.png -------------------------------------------------------------------------------- /HOL 2/Images/portal-copy-event-hub-sas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/portal-copy-event-hub-sas.png -------------------------------------------------------------------------------- /HOL 2/Images/portal-function-running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/portal-function-running.png -------------------------------------------------------------------------------- /HOL 2/Images/portal-save-new-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/portal-save-new-event-hub.png -------------------------------------------------------------------------------- /HOL 2/Images/resolve_dependency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/resolve_dependency.png -------------------------------------------------------------------------------- /HOL 2/Images/restart-function-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/restart-function-app.png -------------------------------------------------------------------------------- /HOL 2/Images/vs-add-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 2/Images/vs-add-project.png -------------------------------------------------------------------------------- /HOL 3/Images/add-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-event-hub.png -------------------------------------------------------------------------------- /HOL 3/Images/add-input-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-input-1.png -------------------------------------------------------------------------------- /HOL 3/Images/add-input-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-input-2.png -------------------------------------------------------------------------------- /HOL 3/Images/add-output-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-output-1.png -------------------------------------------------------------------------------- /HOL 3/Images/add-output-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-output-2.png -------------------------------------------------------------------------------- /HOL 3/Images/add-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/add-query.png -------------------------------------------------------------------------------- /HOL 3/Images/app-environment-labels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/app-environment-labels.png -------------------------------------------------------------------------------- /HOL 3/Images/confirm-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/confirm-input.png -------------------------------------------------------------------------------- /HOL 3/Images/confirm-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/confirm-output.png -------------------------------------------------------------------------------- /HOL 3/Images/copy-connection-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/copy-connection-string.png -------------------------------------------------------------------------------- /HOL 3/Images/create-gist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-gist.png -------------------------------------------------------------------------------- /HOL 3/Images/create-input-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-input-hub.png -------------------------------------------------------------------------------- /HOL 3/Images/create-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-input.png -------------------------------------------------------------------------------- /HOL 3/Images/create-namespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-namespace.png -------------------------------------------------------------------------------- /HOL 3/Images/create-output-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-output-hub.png -------------------------------------------------------------------------------- /HOL 3/Images/create-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-output.png -------------------------------------------------------------------------------- /HOL 3/Images/create-stream-analytics-job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/create-stream-analytics-job.png -------------------------------------------------------------------------------- /HOL 3/Images/event-hubs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/event-hubs.png -------------------------------------------------------------------------------- /HOL 3/Images/new-event-hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/new-event-hub.png -------------------------------------------------------------------------------- /HOL 3/Images/new-stream-analytics-job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/new-stream-analytics-job.png -------------------------------------------------------------------------------- /HOL 3/Images/open-namespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/open-namespace.png -------------------------------------------------------------------------------- /HOL 3/Images/open-resource-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/open-resource-group.png -------------------------------------------------------------------------------- /HOL 3/Images/open-shared-access-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/open-shared-access-key.png -------------------------------------------------------------------------------- /HOL 3/Images/open-stream-analytics-job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/open-stream-analytics-job.png -------------------------------------------------------------------------------- /HOL 3/Images/query-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/query-results.png -------------------------------------------------------------------------------- /HOL 3/Images/start-stream-analytics-job-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/start-stream-analytics-job-1.png -------------------------------------------------------------------------------- /HOL 3/Images/start-stream-analytics-job-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/start-stream-analytics-job-2.png -------------------------------------------------------------------------------- /HOL 3/Images/test-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/test-query.png -------------------------------------------------------------------------------- /HOL 3/Images/upload-test-data-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/upload-test-data-1.png -------------------------------------------------------------------------------- /HOL 3/Images/upload-test-data-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 3/Images/upload-test-data-2.png -------------------------------------------------------------------------------- /HOL 3/resources/flysim-2-in-proximity.json: -------------------------------------------------------------------------------- 1 | {"deviceId":"Charles","timestamp":"2017-09-17T17:50:54","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.24,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 2 | {"deviceId":"Charles","timestamp":"2017-09-17T17:50:56","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.25,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 3 | {"deviceId":"Charles","timestamp":"2017-09-17T17:50:58","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.26,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 4 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:00","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.27,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 5 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:02","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.28,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 6 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:04","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.29,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 7 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:06","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.30,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 8 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:08","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.31,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 9 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:10","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.32,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 10 | {"deviceId":"Charles","timestamp":"2017-09-17T17:51:12","airspeed":384.0,"heading":0.0,"altitude":30000.0,"latitude":37.33,"longitude":-115.81,"pitch":1.0,"roll":-2.27,"temperature":22.9,"humidity":62.9} 11 | 12 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:50:55","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.75,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 13 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:50:57","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.76,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 14 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:50:59","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.77,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 15 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:01","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.78,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 16 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:03","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.79,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 17 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:05","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.80,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 18 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:07","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.81,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 19 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:09","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.82,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 20 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:11","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.83,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} 21 | {"deviceId":"Amelia","timestamp":"2017-09-17T17:51:13","airspeed":384.0,"heading":270.0,"altitude":32500.0,"latitude":37.28,"longitude":-115.84,"pitch":0.0,"roll":2.27,"temperature":22.9,"humidity":62.9} -------------------------------------------------------------------------------- /HOL 4/Images/app-in-flight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/app-in-flight.png -------------------------------------------------------------------------------- /HOL 4/Images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/architecture.png -------------------------------------------------------------------------------- /HOL 4/Images/atc-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/atc-app.png -------------------------------------------------------------------------------- /HOL 4/Images/chip-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/chip-warning.png -------------------------------------------------------------------------------- /HOL 4/Images/copy-api-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/copy-api-key.png -------------------------------------------------------------------------------- /HOL 4/Images/copy-from-gist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/copy-from-gist.png -------------------------------------------------------------------------------- /HOL 4/Images/function_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/function_settings.png -------------------------------------------------------------------------------- /HOL 4/Images/modified-function-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/modified-function-1.png -------------------------------------------------------------------------------- /HOL 4/Images/modified-function-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/modified-function-2.png -------------------------------------------------------------------------------- /HOL 4/Images/new-application-setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/new-application-setting.png -------------------------------------------------------------------------------- /HOL 4/Images/new-translator-text-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/new-translator-text-1.png -------------------------------------------------------------------------------- /HOL 4/Images/new-translator-text-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/new-translator-text-2.png -------------------------------------------------------------------------------- /HOL 4/Images/new-translator-text-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/new-translator-text-3.png -------------------------------------------------------------------------------- /HOL 4/Images/new-translator-text-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/new-translator-text-4.png -------------------------------------------------------------------------------- /HOL 4/Images/open-api-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/open-api-key.png -------------------------------------------------------------------------------- /HOL 4/Images/open-application-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/open-application-settings.png -------------------------------------------------------------------------------- /HOL 4/Images/open-shared-access-policies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/open-shared-access-policies.png -------------------------------------------------------------------------------- /HOL 4/Images/portal-iot-hub-endpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/portal-iot-hub-endpoint.png -------------------------------------------------------------------------------- /HOL 4/Images/restart-function-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/restart-function-app.png -------------------------------------------------------------------------------- /HOL 4/Images/select-language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/select-language.png -------------------------------------------------------------------------------- /HOL 4/Images/two-approaching.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/two-approaching.png -------------------------------------------------------------------------------- /HOL 4/Images/two-at-risk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/two-at-risk.png -------------------------------------------------------------------------------- /HOL 4/Images/warning-messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/CloudIoTHack/2087bc1df4503c581af0870b74a7740b4dd3995d/HOL 4/Images/warning-messages.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloud City IoT Hack # 2 | 3 | --- 4 | 5 | ## Overview ## 6 | 7 | This repo contains content for the Cloud City IoT Hack, an event that provides developers with a hands-on introduction to some of the very best features Microsoft Azure has to offer, including [IoT Hubs](https://azure.microsoft.com/services/iot-hub/), [Event Hubs](https://azure.microsoft.com/services/event-hubs/), [Azure Functions](https://azure.microsoft.com/services/functions/), [Stream Analytics](https://azure.microsoft.com/services/stream-analytics/), and [Cognitive Services](https://azure.microsoft.com/services/cognitive-services/). Four hands-on labs are located in folders named HOL 1, HOL 2, HOL 3, and HOL 4. Here's a synopsis of those labs: 8 | 9 | - [HOL 1](HOL%201/HOL%201%20-%20MXChip.md) - Attendees create an Azure IoT Hub and program an [MXCHIP]([MXChip](https://microsoft.github.io/azure-iot-developer-kit/)) to send accelerometer data to it. 10 | - [HOL 2](HOL%202/HOL%202%20-%20Functions%20and%20Event%20Hubs.md) - Attendees create an Azure Event Hub and deploy an Azure Function that transforms accelerometer data input to the IoT Hub into "flight data" denoting the disposition on an airplane and transmits it to the Event Hub. Then they connect a UWP client app to the Event Hub and use their MXChip to fly a simulated airplane. 11 | - [HOL 3](HOL%203/HOL%203%20-%20Stream%20Analytics.md) - The instructor creates a pair of Event Hubs and deploys a Stream Analytics job that analyzes all the air traffic in the room for aircraft that are within two miles of each another. He or she also deploys a UWP app that shows all the air traffic. **THIS HOL IS INSTRUCTOR-LED**. 12 | - [HOL 4](HOL%204/HOL%204%20-%20Putting%20It%20All%20Together.md) - Attendees modify the Azure Function they deployed in HOL 2 to transmit flight data to the input hub used by Stream Analytics. They also connect the client app to the Stream Analytics output and modify the app to transmit warning messages back to the MXChip when their aircraft are within two miles of another. 13 | 14 | The repo also has five source-code folders: 15 | 16 | - FlySim - A Visual Studio 2017 solution containing the client app that attendees use to fly simulated airplanes. 17 | - FlySimEmbedded - The code attendees upload to the MXChip to program it to send accelerometer data to an Azure IoT Hub. 18 | - FlySimFunctions - The source code of Azure Functions to process and send accelerometer data from the created Azure IoT Hub into Azure Event Hub. 19 | - AirTrafficSim - A Visual Studio 2017 solution containing the air-traffic control (ATC) app that shows all the airplanes in flight and highlights those that are within two miles of each other. 20 | - FlySimTest - A Visual Studio 2017 solution containing a command-line app for injecting simulated aircraft into AirTrafficSim. It's great for testing, and also for adding airplanes to the ATC sector if there aren't enough attendees at the event to make things interesting. To prepare it for use, replace SHARED_EVENT_HUB_ENDPOINT on line 54 with the endpoint connection string for the Event Hub that provides input to Stream Analytics. By default, it injects 20 airplanes. You can inject more (or less) by specifying the desired number as a command-line parameter. 21 | 22 | 23 | For an overview of the end-to-end solution featured in the event, see the introduction to [HOL 1](HOL%201/HOL%201%20-%20MXChip.md). 24 | 25 | ## Contributing ## 26 | 27 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 28 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 29 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 30 | 31 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 32 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 33 | provided by the bot. You will only need to do this once across all repos using our CLA. 34 | 35 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 36 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 37 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 38 | --------------------------------------------------------------------------------