diff --git a/Source/Azure/AzureIoTHub/Controllers/DisplayController.cs b/Source/Azure/AzureIoTHub/Controllers/DisplayController.cs index da0726c..2d2b8be 100644 --- a/Source/Azure/AzureIoTHub/Controllers/DisplayController.cs +++ b/Source/Azure/AzureIoTHub/Controllers/DisplayController.cs @@ -2,120 +2,240 @@ using Meadow.Foundation.Graphics; using Meadow.Foundation.Graphics.MicroLayout; using Meadow.Units; -using System; using System.Threading; -using System.Threading.Tasks; namespace MeadowAzureIoTHub.Controllers { public class DisplayController { - static Color backgroundColor = Color.FromHex("#23ABE3"); - static Color foregroundColor = Color.Black; + Color backgroundColor = Color.FromHex("#23ABE3"); - CancellationTokenSource token; + Font8x12 font8x12 = new Font8x12(); + Font12x20 font12X20 = new Font12x20(); - Image imgConnecting = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_wifi_connected.bmp"); - Image imgConnected = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_wifi_connecting.bmp"); - Image imgRefreshing = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_refreshing.bmp"); - Image imgRefreshed = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_refreshed.bmp"); + CancellationTokenSource token; - MicroGraphics graphics; + Image imgWifi = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_wifi.bmp"); + Image imgWifiFade = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_wifi_fade.bmp"); + Image imgSync = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_sync.bmp"); + Image imgSyncFade = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_sync_fade.bmp"); DisplayScreen displayScreen; AbsoluteLayout SplashLayout; - AbsoluteLayout DataLayout; - - public DisplayController(IGraphicsDisplay display) - { - graphics = new MicroGraphics(display) - { - CurrentFont = new Font8x12(), - Stroke = 3, - Rotation = RotationType._90Degrees - }; + AbsoluteLayout DataLayout; - displayScreen = new DisplayScreen(display); - { - backgroundColor = backgroundColor; - } + Picture Wifi; - graphics.Clear(true); - } + Picture Sync; + + Label Title; + + Label Temperature; + + Label Humidity; - protected void DrawBackground() + public DisplayController(IGraphicsDisplay display) { - var logo = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_meadow.bmp"); + displayScreen = new DisplayScreen(display, RotationType._90Degrees) + { + BackgroundColor = backgroundColor + }; - graphics.Clear(backgroundColor); + LoadSplashLayout(); - graphics.DrawImage( - x: graphics.Width / 2 - logo.Width / 2, - y: 63, - image: logo); + displayScreen.Controls.Add(SplashLayout); - graphics.DrawText(graphics.Width / 2, 160, "Azure IoT Hub", foregroundColor, ScaleFactor.X2, HorizontalAlignment.Center); - } + LoadDataLayout(); - public void ShowSplashScreen() + displayScreen.Controls.Add(DataLayout); + } + + private void LoadSplashLayout() { - DrawBackground(); - - graphics.Show(); - } + SplashLayout = new AbsoluteLayout(displayScreen, 0, 0, displayScreen.Width, displayScreen.Height) + { + IsVisible = false + }; - public async Task ShowConnectingAnimation() + var logo = Image.LoadFromResource("MeadowAzureIoTHub.Resources.img_meadow.bmp"); + var displayImage = new Picture( + 55, + 60, + logo.Width, + logo.Height, + logo) + { + BackColor = backgroundColor, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }; + SplashLayout.Controls.Add(displayImage); + + SplashLayout.Controls.Add(new Label( + 0, + 160, + displayScreen.Width, + font8x12.Height) + { + Text = $"Azure IoT Hub", + TextColor = Color.Black, + Font = font8x12, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center, + }); + } + + public void LoadDataLayout() { - token = new CancellationTokenSource(); - - bool alternateImg = false; - while (!token.IsCancellationRequested) + DataLayout = new AbsoluteLayout(displayScreen, 0, 0, displayScreen.Width, displayScreen.Height) { - alternateImg = !alternateImg; + IsVisible = false + }; + + Sync = new Picture( + 15, + 15, + imgSyncFade.Width, + imgSyncFade.Height, + imgSyncFade); + DataLayout.Controls.Add(Sync); + + Title = new Label( + 60, + 20, + 120, + 26) + { + Text = "AMQP", + TextColor = Color.Black, + Font = font8x12, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center + }; + DataLayout.Controls.Add(Title); + + Wifi = new Picture( + 195, + 15, + imgWifiFade.Width, + imgWifiFade.Height, + imgWifiFade); + DataLayout.Controls.Add(Wifi); + + DataLayout.Controls.Add(new Box( + 20, + 57, + 200, + 76) + { + ForeColor = Color.Black, + IsFilled = false + }); + + DataLayout.Controls.Add(new Label( + 24, + 65, + 192, + font8x12.Height * 2) + { + Text = "Temperature", + TextColor = Color.Black, + Font = font8x12, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center + }); + + Temperature = new Label( + 24, + 93, + 192, + font12X20.Height * 2) + { + Text = "--°C", + TextColor = Color.Black, + Font = font12X20, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center + }; + DataLayout.Controls.Add(Temperature); + + DataLayout.Controls.Add(new Box( + 20, + 144, + 200, + 76) + { + ForeColor = Color.Black, + IsFilled = false + }); + + DataLayout.Controls.Add(new Label( + 24, + 152, + 192, + font8x12.Height * 2) + { + Text = "Humidity", + TextColor = Color.Black, + Font = font8x12, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center + }); + + Humidity = new Label( + 24, + 180, + 192, + font12X20.Height * 2) + { + Text = "--%", + TextColor = Color.Black, + Font = font12X20, + ScaleFactor = ScaleFactor.X2, + HorizontalAlignment = HorizontalAlignment.Center + }; + DataLayout.Controls.Add(Humidity); + } - graphics.DrawImage(204, 6, alternateImg ? imgConnecting : imgConnected); - graphics.Show(); + public void ShowSplashScreen() + { + DataLayout.IsVisible = false; + SplashLayout.IsVisible = true; + } + + public void ShowDataScreen() + { + SplashLayout.IsVisible = false; + DataLayout.IsVisible = true; + } - await Task.Delay(500); - } + public void UpdateTitle(string title) + { + Title.Text = title; } - public void ShowConnected() + public void UpdateWiFiStatus(bool isConnected) { - token.Cancel(); - graphics.DrawImage(204, 6, imgConnected); - - graphics.DrawImage(6, 6, imgRefreshed); - - graphics.DrawRectangle(0, 32, 240, 208, backgroundColor, true); - - graphics.DrawRoundedRectangle(19, 47, 200, 80, 15, foregroundColor); - graphics.DrawText(120, 56, "Temperature", foregroundColor, ScaleFactor.X2, HorizontalAlignment.Center); - - graphics.DrawRoundedRectangle(19, 141, 200, 80, 15, foregroundColor); - graphics.DrawText(120, 149, "Humidity", foregroundColor, ScaleFactor.X2, HorizontalAlignment.Center); - - graphics.Show(); + Wifi.Image = isConnected + ? imgWifi + : imgWifiFade; } - public async Task StartSyncCompletedAnimation((Temperature? Temperature, RelativeHumidity? Humidity) reading) + public void UpdateSyncStatus(bool isSyncing) { - graphics.DrawImage(6, 6, imgRefreshing); - graphics.Show(); - await Task.Delay(TimeSpan.FromSeconds(1)); - - graphics.CurrentFont = new Font12x20(); - - graphics.DrawRectangle(24, 85, 190, 40, backgroundColor, true); - graphics.DrawText(120, 85, $"{reading.Temperature.Value.Celsius:N1}°C", foregroundColor, ScaleFactor.X2, HorizontalAlignment.Center); + Sync.Image = isSyncing + ? imgSync + : imgSyncFade; + } - graphics.DrawRectangle(24, 178, 190, 40, backgroundColor, true); - graphics.DrawText(120, 178, $"{reading.Humidity.Value.Percent:N2}%", foregroundColor, ScaleFactor.X2, HorizontalAlignment.Center); + public void UpdateReadings((Temperature? Temperature, RelativeHumidity? Humidity) reading) + { + Temperature.Text = $"{reading.Temperature.Value.Celsius:N1}°C"; - graphics.DrawImage(6, 6, imgRefreshed); - graphics.Show(); + Humidity.Text = $"{reading.Humidity.Value.Percent:N2}%"; } } } \ No newline at end of file diff --git a/Source/Azure/AzureIoTHub/Controllers/IoTHubAmqpController.cs b/Source/Azure/AzureIoTHub/Controllers/IoTHubAmqpController.cs index 1fedb52..0a4fdeb 100644 --- a/Source/Azure/AzureIoTHub/Controllers/IoTHubAmqpController.cs +++ b/Source/Azure/AzureIoTHub/Controllers/IoTHubAmqpController.cs @@ -2,12 +2,11 @@ using Amqp.Framing; using Meadow; using Meadow.Units; -using MeadowAzureIoTHub.Controllers; using System; using System.Text; using System.Threading.Tasks; -namespace MeadowAzureIoTHub.Azure +namespace MeadowAzureIoTHub.Controllers { public class IoTHubAmqpController : IIoTHubController { diff --git a/Source/Azure/AzureIoTHub/MainController.cs b/Source/Azure/AzureIoTHub/MainController.cs index f4b4892..af58fdf 100644 --- a/Source/Azure/AzureIoTHub/MainController.cs +++ b/Source/Azure/AzureIoTHub/MainController.cs @@ -12,6 +12,8 @@ namespace MeadowAzureIoTHub { internal class MainController { + bool useMQTT = true; + Htu21d atmosphericSensor; DisplayController displayController; @@ -36,12 +38,19 @@ public async Task Initialize() displayController = new DisplayController(display); displayController.ShowSplashScreen(); - Thread.Sleep(3000); - _ = displayController.ShowConnectingAnimation(); - - //iotHubController = new IoTHubAmqpController(); + Thread.Sleep(5000); + displayController.ShowDataScreen(); - iotHubController = new IoTHubMqttController(); + if (useMQTT) + { + displayController.UpdateTitle("MQTT"); + iotHubController = new IoTHubMqttController(); + } + else + { + displayController.UpdateTitle("AMQP"); + iotHubController = new IoTHubAmqpController(); + } await InitializeIoTHub(); @@ -53,6 +62,8 @@ private async Task InitializeIoTHub() { while (!iotHubController.isAuthenticated) { + displayController.UpdateWiFiStatus(network.IsConnected); + if (network.IsConnected) { bool authenticated = await iotHubController.Initialize(); @@ -60,7 +71,7 @@ private async Task InitializeIoTHub() if (authenticated) { Resolver.Log.Info("Authenticated"); - displayController.ShowConnected(); + } else { @@ -78,15 +89,16 @@ private async Task InitializeIoTHub() private async void AtmosphericSensorUpdated(object sender, IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity)> e) { - await SendDataToIoTHub(e.New); - await displayController.StartSyncCompletedAnimation(e.New); - } + displayController.UpdateWiFiStatus(network.IsConnected); - private async Task SendDataToIoTHub((Temperature? Temperature, RelativeHumidity? Humidity) data) - { if (network.IsConnected && iotHubController.isAuthenticated) { - await iotHubController.SendEnvironmentalReading(data); + displayController.UpdateSyncStatus(true); + + await iotHubController.SendEnvironmentalReading(e.New); + displayController.UpdateReadings(e.New); + + displayController.UpdateSyncStatus(false); } } diff --git a/Source/Azure/AzureIoTHub/MeadowAzureIoTHub.csproj b/Source/Azure/AzureIoTHub/MeadowAzureIoTHub.csproj index e7fbe5a..77d13e4 100644 --- a/Source/Azure/AzureIoTHub/MeadowAzureIoTHub.csproj +++ b/Source/Azure/AzureIoTHub/MeadowAzureIoTHub.csproj @@ -12,17 +12,17 @@ - - - - + + + + - - - - + + + + diff --git a/Source/Azure/AzureIoTHub/Resources/img_refreshing.bmp b/Source/Azure/AzureIoTHub/Resources/img_sync.bmp similarity index 100% rename from Source/Azure/AzureIoTHub/Resources/img_refreshing.bmp rename to Source/Azure/AzureIoTHub/Resources/img_sync.bmp diff --git a/Source/Azure/AzureIoTHub/Resources/img_refreshed.bmp b/Source/Azure/AzureIoTHub/Resources/img_sync_fade.bmp similarity index 100% rename from Source/Azure/AzureIoTHub/Resources/img_refreshed.bmp rename to Source/Azure/AzureIoTHub/Resources/img_sync_fade.bmp diff --git a/Source/Azure/AzureIoTHub/Resources/img_wifi_connected.bmp b/Source/Azure/AzureIoTHub/Resources/img_wifi.bmp similarity index 100% rename from Source/Azure/AzureIoTHub/Resources/img_wifi_connected.bmp rename to Source/Azure/AzureIoTHub/Resources/img_wifi.bmp diff --git a/Source/Azure/AzureIoTHub/Resources/img_wifi_connecting.bmp b/Source/Azure/AzureIoTHub/Resources/img_wifi_fade.bmp similarity index 100% rename from Source/Azure/AzureIoTHub/Resources/img_wifi_connecting.bmp rename to Source/Azure/AzureIoTHub/Resources/img_wifi_fade.bmp diff --git a/Source/Meadow.Project.Samples.sln b/Source/Meadow.Project.Samples.sln index b6df8dc..80e3e6b 100644 --- a/Source/Meadow.Project.Samples.sln +++ b/Source/Meadow.Project.Samples.sln @@ -187,6 +187,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Displays.Led.SevenSegment", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web.Maple.Server", "..\..\Maple\Source\Web.Maple.Server\Web.Maple.Server.csproj", "{09A635D8-7B69-4C70-A176-C4054DFA4CA2}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Graphics.MicroLayout", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Libraries_and_Frameworks\Graphics.MicroLayout\Driver\Graphics.MicroLayout.csproj", "{E81687D9-4C37-40A0-B898-A4B6380854EF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -3132,6 +3134,30 @@ Global {09A635D8-7B69-4C70-A176-C4054DFA4CA2}.Release|x86.ActiveCfg = Release|Any CPU {09A635D8-7B69-4C70-A176-C4054DFA4CA2}.Release|x86.Build.0 = Release|Any CPU {09A635D8-7B69-4C70-A176-C4054DFA4CA2}.Release|x86.Deploy.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|ARM.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|iPhone.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|x64.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Debug|x86.Build.0 = Debug|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|Any CPU.Build.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|ARM.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|ARM.Build.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|iPhone.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|iPhone.Build.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|x64.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|x64.Build.0 = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|x86.ActiveCfg = Release|Any CPU + {E81687D9-4C37-40A0-B898-A4B6380854EF}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3224,6 +3250,7 @@ Global {B62721DE-8080-4511-A1DE-7E5D5EEDF1FC} = {735B86C0-571B-4AEC-A8C5-B1A9C81D0EE0} {86152F91-7ED6-4433-AD2A-588CFFF71EE8} = {735B86C0-571B-4AEC-A8C5-B1A9C81D0EE0} {09A635D8-7B69-4C70-A176-C4054DFA4CA2} = {735B86C0-571B-4AEC-A8C5-B1A9C81D0EE0} + {E81687D9-4C37-40A0-B898-A4B6380854EF} = {735B86C0-571B-4AEC-A8C5-B1A9C81D0EE0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {10FA7F4A-2FF2-4696-8B12-DD0B9C978890}