diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml
index b86e231..6343f5f 100644
--- a/.github/workflows/main-ci.yml
+++ b/.github/workflows/main-ci.yml
@@ -3,6 +3,7 @@ name: Main Build
on:
workflow_dispatch:
pull_request:
+ branches: [ main ]
push:
branches: [ main ]
@@ -17,7 +18,6 @@ jobs:
uses: actions/checkout@v3
with:
path: Clima
- ref: main
- name: Setup .NET
uses: actions/setup-dotnet@v2
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..4587e7a
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,10 @@
+{
+ "configurations": [
+ {
+ "name": "COM9",
+ "type": "meadow",
+ "request": "launch",
+ "preLaunchTask": "meadow: Build"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Image_Assets/Clima.jpg b/Image_Assets/Clima.jpg
deleted file mode 100644
index 63ad745..0000000
Binary files a/Image_Assets/Clima.jpg and /dev/null differ
diff --git a/Image_Assets/Clima_Fritzing_Diagram.png b/Image_Assets/Clima_Fritzing_Diagram.png
deleted file mode 100644
index 5d9ae03..0000000
Binary files a/Image_Assets/Clima_Fritzing_Diagram.png and /dev/null differ
diff --git a/Image_Assets/Clima_android.png b/Image_Assets/Clima_android.png
deleted file mode 100644
index 5c97ed5..0000000
Binary files a/Image_Assets/Clima_android.png and /dev/null differ
diff --git a/Image_Assets/clima-banner.jpg b/Image_Assets/clima-banner.jpg
index 9dd6dd8..c794530 100644
Binary files a/Image_Assets/clima-banner.jpg and b/Image_Assets/clima-banner.jpg differ
diff --git a/README.md b/README.md
index 37d5570..e737485 100644
--- a/README.md
+++ b/README.md
@@ -3,46 +3,17 @@
Clima is a solar-powered, custom embedded-IoT solution that tracks climate from a suite of sensors, saves data locally for access via Bluetooth, uses a RESTful Web API, and synchronizes data to the cloud.
## Contents
-* [Clima Versions](#clima-versions)
+* [Clima Pro](#clima)
* [Assembly Instructions](#assembly-instructions)
* [Getting Started](#getting-started)
* [Hardware Specifications](#hardware-specifications)
-* [Mobile Companion App](#mobile-companion-app)
-* [Get an API Key for OpenWeather](#get-an-api-key-for-openweather)
-* [Clima.HackKit](#climahackkit)
* [Support](#support)
-## Clima Versions
-
-We offer clima in two options, a full dedicated kit that it's fully solar powered build and ideal to measure weather outdoors, or a much simplified version that you can build with our Hack Kits.
-
-Both versions are 100% open source, including all of the enclosure design files, and PCB design of the pro version.
-
-
- With this kit, it includes the complete package of sensors, PCB enclosure and mount to place this outdoors. You'll be able to measure wind speed/direction, rain volume, atmospheric conditions like temperature, pressure, humidity, CO2 levels and GPS Coordinates.
-
-
- With the Meadow Hack Kit, you can build this project to measure indoor room temperature with an analog temperature sensor, use a 240x240 TFT Spi display and three push buttons to build a simple UI using MicroGraphics to do things like change temperature units, and more.
-
-
-
+## Clima
+
+With this kit, it includes the complete package of sensors, PCB enclosure and mount to place this outdoors. You'll be able to measure wind speed/direction, rain volume, atmospheric conditions like temperature, pressure, humidity, CO2 levels and GPS Coordinates.
+
+
## Assembly Instructions
@@ -60,37 +31,28 @@ To simplify the way to use this Meadow-powered reference IoT product, we've crea
- `dotnet add package Meadow.Clima`, or
- [Meadow.Clima Nuget Package](https://www.nuget.org/packages/Meadow.Clima/)
-2. Instantiate the `IClimaHardware` object:
+2. Change the App type on your MeadowApp class to `ClimaAppBase` and initialize Clima's `MainController` passing the `Hardware` and a `INetworkAdapter` such as your WiFi adapter onboard the Meadow Core Compute Module:
+
```csharp
-public class MeadowApp : App
+public class ClimaApp : ClimaAppBase
{
- IClimaHardware clima;
-
public override Task Initialize()
{
- clima = Clima.Create();
- ...
-```
+ Resolver.Log.Info($"Initialize...");
-3. To Access the `Clima` onboard peripherals (AtmosphericSensor, for example):
-```csharp
- if (clima.AtmosphericSensor is { } bme688)
- {
- bme688.Updated += Bme688Updated;
- bme688.StartUpdating();
- }
-```
+ var mainController = new MainController();
+
+ var wifi = Hardware.ComputeModule.NetworkAdapters.Primary();
-4. Like on step 3, you can also access the rest of peripherals:
- - `EnvironmentalSensor` - Access the SCD40 sensor
- - `WindVane` - Access the Wind Vane to check wind direction
- - `RainGauge` - Access the Rain Gauge to check rain volume
- - `Anemometer` - Access the Anemometer to get wind speed
- - `SolarVoltageInput` - Access the voltage input from the Solar Add-on
- - `Gnss` - Access the NEO-M8 GNSS/GPS module
- - `ColorLed` - Access an RGB LED
+ mainController.Initialize(
+ hardware: Hardware,
+ networkAdapter: wifi);
+ .
+ .
+ .
+```
-5. Run the [Clima_Demo](Source/Clima_Demo/) project that uses all the peripherals onboard and outputs readings every few seconds.
+3. Run the [Clima_Demo](Source/Clima_Demo/) project that does periodic readings of all its sensors and sends them to [Meadow.Cloud](https://www.meadowcloud.co) if you have a Wilderness Labs account and have provisioned your device.
## Hardware Specifications
@@ -98,22 +60,6 @@ public class MeadowApp : App
You can find the schematics and other design files in the [Hardware_Design folder](Hardware_Design/).
-## Mobile Companion App
-
-This project also comes with a Xamarin.Forms Clima companion app (on Android and iOS) that shows you how to communicate with your Meadow device using [Bluetooth](http://developer.wildernesslabs.co/Meadow/Meadow.OS/Bluetooth/) and [Maple](http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/Libraries_and_Frameworks/Maple.Server/) for both kit versions.
-
-![Clima companion app](Image_Assets/Clima_android.png)
-
-## Get an API Key for OpenWeather
-
-Go to [Register for an OpenWeather API Key](https://blog.wildernesslabs.co/add-openweather-to-your-meadow-projects/)
-
-## Clima.HackKit
-
-![Clima hack kit](Image_Assets/Clima.jpg)
-
-Instructions on how to assemble the Clima Hack Kit Version can be found [here](/Docs/Clima.HackKit/readme.md)
-
## Support
Having trouble building/running these projects?
diff --git a/Source/Additional Samples/Clima_Companion_App/App.xaml b/Source/Additional Samples/Clima_Companion_App/App.xaml
deleted file mode 100644
index 7af90e1..0000000
--- a/Source/Additional Samples/Clima_Companion_App/App.xaml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/App.xaml.cs b/Source/Additional Samples/Clima_Companion_App/App.xaml.cs
deleted file mode 100644
index 87bed9d..0000000
--- a/Source/Additional Samples/Clima_Companion_App/App.xaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace MobileClima
-{
- public partial class App : Application
- {
- public App()
- {
- InitializeComponent();
-
- MainPage = new AppShell();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/AppShell.xaml b/Source/Additional Samples/Clima_Companion_App/AppShell.xaml
deleted file mode 100644
index a6810a5..0000000
--- a/Source/Additional Samples/Clima_Companion_App/AppShell.xaml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/AppShell.xaml.cs b/Source/Additional Samples/Clima_Companion_App/AppShell.xaml.cs
deleted file mode 100644
index e4c6ebb..0000000
--- a/Source/Additional Samples/Clima_Companion_App/AppShell.xaml.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace MobileClima;
-
-public partial class AppShell : Shell
-{
- public AppShell()
- {
- InitializeComponent();
- }
-}
diff --git a/Source/Additional Samples/Clima_Companion_App/Clima_Companion_App.csproj b/Source/Additional Samples/Clima_Companion_App/Clima_Companion_App.csproj
deleted file mode 100644
index c1c36df..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Clima_Companion_App.csproj
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
- net7.0-android
-
-
- Exe
- MobileClima
- true
- true
- enable
-
-
- Clima
-
-
- com.companyname.MobileClima
- 2750A062-72A3-4E67-A82F-AAC0A348C7B4
-
-
- 1.0
- 1
-
- 21.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Converter/InverseBoolConverter.cs b/Source/Additional Samples/Clima_Companion_App/Converter/InverseBoolConverter.cs
deleted file mode 100644
index 35cadaf..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Converter/InverseBoolConverter.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Globalization;
-
-namespace MobileClima.Converter
-{
- public class InverseBoolConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return !(bool)value;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return !(bool)value;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/MauiProgram.cs b/Source/Additional Samples/Clima_Companion_App/MauiProgram.cs
deleted file mode 100644
index 29a456e..0000000
--- a/Source/Additional Samples/Clima_Companion_App/MauiProgram.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace MobileClima;
-
-public static class MauiProgram
-{
- public static MauiApp CreateMauiApp()
- {
- var builder = MauiApp.CreateBuilder();
- builder
- .UseMauiApp()
- .ConfigureFonts(fonts =>
- {
- fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
- fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
- });
-
- return builder.Build();
- }
-}
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/AndroidManifest.xml b/Source/Additional Samples/Clima_Companion_App/Platforms/Android/AndroidManifest.xml
deleted file mode 100644
index 3bca0fc..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainActivity.cs b/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainActivity.cs
deleted file mode 100644
index 250d1e2..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainActivity.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Android.App;
-using Android.Content.PM;
-
-namespace MobileClima
-{
- [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true,
- ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation |
- ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize |
- ConfigChanges.Density)]
- public class MainActivity : MauiAppCompatActivity
- {
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainApplication.cs b/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainApplication.cs
deleted file mode 100644
index ffda6e7..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/MainApplication.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Android.App;
-using Android.Runtime;
-
-namespace MobileClima;
-
-[Application]
-public class MainApplication : MauiApplication
-{
- public MainApplication(IntPtr handle, JniHandleOwnership ownership)
- : base(handle, ownership)
- {
- }
-
- protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
-}
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/values/colors.xml b/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/values/colors.xml
deleted file mode 100644
index 4b99715..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #512BD4
- #14607F
- #2B0B98
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/xml/network_security_config.xml b/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/xml/network_security_config.xml
deleted file mode 100644
index 19ecbc6..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Android/Resources/xml/network_security_config.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml b/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml
deleted file mode 100644
index 7a756a2..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml.cs b/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml.cs
deleted file mode 100644
index 55b2030..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/App.xaml.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Microsoft.UI.Xaml;
-
-// To learn more about WinUI, the WinUI project structure,
-// and more about our project templates, see: http://aka.ms/winui-project-info.
-
-namespace MobileClima.WinUI;
-
-///
-/// Provides application-specific behavior to supplement the default Application class.
-///
-public partial class App : MauiWinUIApplication
-{
- ///
- /// Initializes the singleton application object. This is the first line of authored code
- /// executed, and as such is the logical equivalent of main() or WinMain().
- ///
- public App()
- {
- this.InitializeComponent();
- }
-
- protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
-}
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/Package.appxmanifest b/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/Package.appxmanifest
deleted file mode 100644
index 624679d..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/Package.appxmanifest
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
- $placeholder$
- User Name
- $placeholder$.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/app.manifest b/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/app.manifest
deleted file mode 100644
index 569ff7f..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/Windows/app.manifest
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
- true/PM
- PerMonitorV2, PerMonitor
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/AppDelegate.cs b/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/AppDelegate.cs
deleted file mode 100644
index 7c55477..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/AppDelegate.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Foundation;
-
-namespace MobileClima;
-
-[Register("AppDelegate")]
-public class AppDelegate : MauiUIApplicationDelegate
-{
- protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
-}
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Info.plist b/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Info.plist
deleted file mode 100644
index 0004a4f..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Info.plist
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
- LSRequiresIPhoneOS
-
- UIDeviceFamily
-
- 1
- 2
-
- UIRequiredDeviceCapabilities
-
- arm64
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- XSAppIconAssets
- Assets.xcassets/appicon.appiconset
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Program.cs b/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Program.cs
deleted file mode 100644
index 2f6232f..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Platforms/iOS/Program.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using ObjCRuntime;
-using UIKit;
-
-namespace MobileClima;
-
-public class Program
-{
- // This is the main entry point of the application.
- static void Main(string[] args)
- {
- // if you want to use a different Application Delegate class from "AppDelegate"
- // you can specify it here.
- UIApplication.Main(args, null, typeof(AppDelegate));
- }
-}
diff --git a/Source/Additional Samples/Clima_Companion_App/Properties/launchSettings.json b/Source/Additional Samples/Clima_Companion_App/Properties/launchSettings.json
deleted file mode 100644
index edf8aad..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Properties/launchSettings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "profiles": {
- "Windows Machine": {
- "commandName": "MsixPackage",
- "nativeDebugging": false
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appicon.svg b/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appicon.svg
deleted file mode 100644
index 397c060..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appicon.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appiconfg.svg b/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appiconfg.svg
deleted file mode 100644
index 60f896c..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/AppIcon/appiconfg.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Regular.ttf b/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Regular.ttf
deleted file mode 100644
index 6cbaf4b..0000000
Binary files a/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Regular.ttf and /dev/null differ
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Semibold.ttf b/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Semibold.ttf
deleted file mode 100644
index 554d68a..0000000
Binary files a/Source/Additional Samples/Clima_Companion_App/Resources/Fonts/OpenSans-Semibold.ttf and /dev/null differ
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_pair.svg b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_pair.svg
deleted file mode 100644
index 4b4bc25..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_pair.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_paired.svg b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_paired.svg
deleted file mode 100644
index 8253be2..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_ble_paired.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_hack_kit.png b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_hack_kit.png
deleted file mode 100644
index 718605d..0000000
Binary files a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_hack_kit.png and /dev/null differ
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_pro.png b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_pro.png
deleted file mode 100644
index 8990db0..0000000
Binary files a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_clima_pro.png and /dev/null differ
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.png b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.png
deleted file mode 100644
index 40341cc..0000000
Binary files a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.png and /dev/null differ
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.svg b/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.svg
deleted file mode 100644
index 9431fbf..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Images/img_search.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Raw/AboutAssets.txt b/Source/Additional Samples/Clima_Companion_App/Resources/Raw/AboutAssets.txt
deleted file mode 100644
index 15d6244..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Raw/AboutAssets.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Any raw assets you want to be deployed with your application can be placed in
-this directory (and child directories). Deployment of the asset to your application
-is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
-
-
-
-These files will be deployed with you package and will be accessible using Essentials:
-
- async Task LoadMauiAsset()
- {
- using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
- using var reader = new StreamReader(stream);
-
- var contents = reader.ReadToEnd();
- }
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Splash/splash.svg b/Source/Additional Samples/Clima_Companion_App/Resources/Splash/splash.svg
deleted file mode 100644
index 8db16c4..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Splash/splash.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Colors.xaml b/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Colors.xaml
deleted file mode 100644
index d995b9e..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Colors.xaml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- #512BD4
- #DFD8F7
- #2B0B98
- White
- Black
- #E1E1E1
- #C8C8C8
- #ACACAC
- #919191
- #6E6E6E
- #404040
- #212121
- #141414
- #23ABE3
- #555
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #F7B548
- #FFD590
- #FFE5B9
- #28C2D1
- #7BDDEF
- #C3F2F4
- #3E8EED
- #72ACF1
- #A7CBF6
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Styles.xaml b/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Styles.xaml
deleted file mode 100644
index d8d3c29..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Resources/Styles/Styles.xaml
+++ /dev/null
@@ -1,391 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/Additional Samples/Clima_Companion_App/Utils/NetworkManager.cs b/Source/Additional Samples/Clima_Companion_App/Utils/NetworkManager.cs
deleted file mode 100644
index 4adf5d7..0000000
--- a/Source/Additional Samples/Clima_Companion_App/Utils/NetworkManager.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-namespace MobileClima.Utils
-{
- public static class NetworkManager
- {
- static NetworkManager() { }
-
- ///
- /// Fetches the climate readings from the Web API Endpoint
- ///
- ///
- public static async Task GetAsync(string ipAddress)
- {
- using (HttpClient client = new HttpClient()
- {
- BaseAddress = new Uri($"http://{ipAddress}:2792/"),
- Timeout = TimeSpan.FromMinutes(5)
- })
- {
- try
- {
- var response = await client.GetAsync("ClimateData", HttpCompletionOption.ResponseContentRead);
-
- if (response.IsSuccessStatusCode)
- {
- string json = await response.Content.ReadAsStringAsync();
-
- Console.WriteLine(json);
- }
- else
- {
- throw new InvalidOperationException("Could not connect to device");
- }
-
- //var values = System.Text.Json.JsonSerializer.Deserialize(json, typeof(List));
-
- return response;
- }
- catch (TaskCanceledException)
- {
- Console.WriteLine("Request time out.");
- return null;
- }
- catch (Exception e)
- {
- Console.WriteLine($"Request went sideways: {e.Message}");
- return null;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml b/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml
deleted file mode 100644
index efebad2..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml
+++ /dev/null
@@ -1,140 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml.cs b/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml.cs
deleted file mode 100644
index 9b0d412..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/BluetoothPage.xaml.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using MobileClima.ViewModel;
-
-namespace MobileClima.View
-{
- public partial class BluetoothPage : ContentPage
- {
- public BluetoothPage(bool isClimaPro)
- {
- InitializeComponent();
- BindingContext = new BluetoothViewModel(isClimaPro);
- }
-
- protected override void OnAppearing()
- {
- base.OnAppearing();
- (BindingContext as BluetoothViewModel).CmdSearchForDevices.Execute(null);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml b/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml
deleted file mode 100644
index 711283f..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
- #555
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml.cs b/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml.cs
deleted file mode 100644
index 55e327c..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/MainPage.xaml.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-namespace MobileClima.View
-{
- public partial class MainPage : ContentPage
- {
- public MainPage()
- {
- InitializeComponent();
- }
-
- void BtnProBluetoothClicked(object sender, System.EventArgs e)
- {
- Navigation.PushAsync(new BluetoothPage(true)
- {
- Title = "Clima.Pro"
- });
- }
-
- void BtnProMapleClicked(object sender, System.EventArgs e)
- {
- Navigation.PushAsync(new MaplePage(true)
- {
- Title = "Clima.Pro"
- });
- }
-
- void BtnHackKitBluetoothClicked(object sender, System.EventArgs e)
- {
- Navigation.PushAsync(new BluetoothPage(false)
- {
- Title = "Clima.HackKit"
- });
- }
-
- void BtnHackKitMapleClicked(object sender, System.EventArgs e)
- {
- Navigation.PushAsync(new MaplePage(false)
- {
- Title = "Clima.HackKit"
- });
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml b/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml
deleted file mode 100644
index 79982ba..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml
+++ /dev/null
@@ -1,183 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml.cs b/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml.cs
deleted file mode 100644
index 7dfff99..0000000
--- a/Source/Additional Samples/Clima_Companion_App/View/MaplePage.xaml.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using MobileClima.ViewModel;
-
-namespace MobileClima.View
-{
- public partial class MaplePage : ContentPage
- {
- public MaplePage(bool isClimaPro)
- {
- InitializeComponent();
- BindingContext = new MapleViewModel(isClimaPro);
- }
-
- protected override async void OnAppearing()
- {
- base.OnAppearing();
- await (BindingContext as MapleViewModel).LoadData();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/ViewModel/BaseViewModel.cs b/Source/Additional Samples/Clima_Companion_App/ViewModel/BaseViewModel.cs
deleted file mode 100644
index a98af3d..0000000
--- a/Source/Additional Samples/Clima_Companion_App/ViewModel/BaseViewModel.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace MobileClima.ViewModel
-{
- public class BaseViewModel : INotifyPropertyChanged
- {
- bool isBusy;
- public bool IsBusy
- {
- get => isBusy;
- set { isBusy = value; OnPropertyChanged(nameof(IsBusy)); }
- }
-
- bool isClimaPro;
- public bool IsClimaPro
- {
- get => isClimaPro;
- set { isClimaPro = value; OnPropertyChanged(nameof(IsClimaPro)); }
- }
-
- #region INotifyPropertyChanged Implementation
- public event PropertyChangedEventHandler PropertyChanged;
- public void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/ViewModel/BluetoothViewModel.cs b/Source/Additional Samples/Clima_Companion_App/ViewModel/BluetoothViewModel.cs
deleted file mode 100644
index 14f587e..0000000
--- a/Source/Additional Samples/Clima_Companion_App/ViewModel/BluetoothViewModel.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using Clima.Contracts.Bluetooth;
-using Plugin.BLE;
-using Plugin.BLE.Abstractions.Contracts;
-using Plugin.BLE.Abstractions.EventArgs;
-using Plugin.BLE.Abstractions.Exceptions;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Windows.Input;
-
-namespace MobileClima.ViewModel
-{
- public class BluetoothViewModel : BaseViewModel
- {
- int listenTimeout = 5000;
-
- ushort DEVICE_ID = 253;
-
- IAdapter adapter;
- IService service;
-
- ICharacteristic tempCharacteristic;
- ICharacteristic pressureCharacteristic;
- ICharacteristic humidityCharacteristic;
- ICharacteristic rainFallCharacteristic;
- ICharacteristic windSpeedCharacteristic;
- ICharacteristic windDirectionCharacteristic;
-
- public ObservableCollection DeviceList { get; set; }
-
- IDevice deviceSelected;
- public IDevice DeviceSelected
- {
- get => deviceSelected;
- set { deviceSelected = value; OnPropertyChanged(nameof(DeviceSelected)); }
- }
-
- bool isScanning;
- public bool IsScanning
- {
- get => isScanning;
- set { isScanning = value; OnPropertyChanged(nameof(IsScanning)); }
- }
-
- bool isConnected;
- public bool IsConnected
- {
- get => isConnected;
- set { isConnected = value; OnPropertyChanged(nameof(IsConnected)); }
- }
-
- bool isDeviceListEmpty;
- public bool IsDeviceListEmpty
- {
- get => isDeviceListEmpty;
- set { isDeviceListEmpty = value; OnPropertyChanged(nameof(IsDeviceListEmpty)); }
- }
-
- string date;
- public string Date
- {
- get => date;
- set { date = value; OnPropertyChanged(nameof(Date)); }
- }
-
- string temperatureValue;
- public string TemperatureValue
- {
- get => temperatureValue;
- set { temperatureValue = value; OnPropertyChanged(nameof(TemperatureValue)); }
- }
-
- string pressureValue;
- public string PressureValue
- {
- get => pressureValue;
- set { pressureValue = value; OnPropertyChanged(nameof(PressureValue)); }
- }
-
- string humidityValue;
- public string HumidityValue
- {
- get => humidityValue;
- set { humidityValue = value; OnPropertyChanged(nameof(HumidityValue)); }
- }
-
- string rainFallValue;
- public string RainFallValue
- {
- get => rainFallValue;
- set { rainFallValue = value; OnPropertyChanged(nameof(RainFallValue)); }
- }
-
- string windSpeedValue;
- public string WindSpeedValue
- {
- get => windSpeedValue;
- set { windSpeedValue = value; OnPropertyChanged(nameof(WindSpeedValue)); }
- }
-
- string windDirectionValue;
- public string WindDirectionValue
- {
- get => windDirectionValue;
- set { windDirectionValue = value; OnPropertyChanged(nameof(WindDirectionValue)); }
- }
-
- public ICommand CmdToggleConnection { get; set; }
-
- public ICommand CmdSearchForDevices { get; set; }
-
- public ICommand CmdGetClimaStatus { get; set; }
-
- public BluetoothViewModel(bool isClimaPro)
- {
- IsClimaPro = isClimaPro;
-
- DeviceList = new ObservableCollection();
-
- adapter = CrossBluetoothLE.Current.Adapter;
- adapter.ScanTimeout = listenTimeout;
- adapter.ScanMode = ScanMode.LowLatency;
- adapter.DeviceConnected += AdapterDeviceConnected;
- adapter.DeviceDiscovered += AdapterDeviceDiscovered;
- adapter.DeviceDisconnected += AdapterDeviceDisconnected;
-
- CmdToggleConnection = new Command(async () => await ToggleConnection());
-
- CmdSearchForDevices = new Command(async () => await DiscoverDevices());
-
- CmdGetClimaStatus = new Command(async () => await GetClimaStatus());
- }
-
- void AdapterDeviceDisconnected(object sender, DeviceEventArgs e)
- {
- IsConnected = false;
- }
-
- async void AdapterDeviceConnected(object sender, DeviceEventArgs e)
- {
- IsConnected = true;
-
- IDevice device = e.Device;
-
- var services = await device.GetServicesAsync();
-
- foreach (var serviceItem in services)
- {
- if (UuidToUshort(serviceItem.Id.ToString()) == DEVICE_ID)
- {
- service = serviceItem;
- }
- }
-
- tempCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.TEMPERATURE));
-
- if (IsClimaPro)
- {
- pressureCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.PRESSURE));
- humidityCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.HUMIDITY));
- rainFallCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.RAIN_FALL));
- windSpeedCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.WIND_SPEED));
- windDirectionCharacteristic = await service.GetCharacteristicAsync(Guid.Parse(CharacteristicsConstants.WIND_DIRECTION));
- }
- }
-
- async void AdapterDeviceDiscovered(object sender, DeviceEventArgs e)
- {
- if (DeviceList.FirstOrDefault(x => x.Name == e.Device.Name) == null &&
- !string.IsNullOrEmpty(e.Device.Name))
- {
- DeviceList.Add(e.Device);
- }
-
- if (e.Device.Name == "Clima_SQLite_Demo" ||
- e.Device.Name == "Clima_HackKit_Demo")
- {
- await adapter.StopScanningForDevicesAsync();
- IsDeviceListEmpty = false;
- DeviceSelected = e.Device;
- }
- }
-
- async Task ScanTimeoutTask()
- {
- await Task.Delay(listenTimeout);
- await adapter.StopScanningForDevicesAsync();
- IsScanning = false;
- }
-
- async Task DiscoverDevices()
- {
- try
- {
- IsScanning = true;
-
- var tasks = new Task[]
- {
- ScanTimeoutTask(),
- adapter.StartScanningForDevicesAsync()
- };
-
- await Task.WhenAny(tasks);
- }
- catch (DeviceConnectionException ex)
- {
- Debug.WriteLine(ex.Message);
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex.Message);
- }
- }
-
- async Task ToggleConnection()
- {
- try
- {
- if (IsConnected)
- {
- await adapter.DisconnectDeviceAsync(DeviceSelected);
- IsConnected = false;
- }
- else
- {
- await adapter.ConnectToDeviceAsync(DeviceSelected);
- IsConnected = true;
- }
- }
- catch (DeviceConnectionException ex)
- {
- Debug.WriteLine(ex.Message);
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex.Message);
- }
- }
-
- async Task GetClimaStatus()
- {
- if (IsBusy)
- return;
- IsBusy = true;
-
- try
- {
- Date = DateTime.Now.ToString();
- TemperatureValue = System.Text.Encoding.Default.GetString(await tempCharacteristic.ReadAsync()).Split(';')[0];
-
- if (IsClimaPro)
- {
- PressureValue = System.Text.Encoding.Default.GetString(await pressureCharacteristic.ReadAsync()).Split(';')[0];
- HumidityValue = System.Text.Encoding.Default.GetString(await humidityCharacteristic.ReadAsync()).Split(';')[0];
- RainFallValue = System.Text.Encoding.Default.GetString(await rainFallCharacteristic.ReadAsync()).Split(';')[0];
- WindSpeedValue = System.Text.Encoding.Default.GetString(await windSpeedCharacteristic.ReadAsync()).Split(';')[0];
- WindDirectionValue = System.Text.Encoding.Default.GetString(await windDirectionCharacteristic.ReadAsync()).Split(';')[0];
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- finally
- {
- IsBusy = false;
- }
- }
-
- protected int UuidToUshort(string uuid)
- {
- return int.Parse(uuid.Substring(4, 4), System.Globalization.NumberStyles.HexNumber); ;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Companion_App/ViewModel/MapleViewModel.cs b/Source/Additional Samples/Clima_Companion_App/ViewModel/MapleViewModel.cs
deleted file mode 100644
index e3f1d4f..0000000
--- a/Source/Additional Samples/Clima_Companion_App/ViewModel/MapleViewModel.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-using CommonContracts.Models;
-using Meadow.Foundation.Web.Maple;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.Windows.Input;
-
-namespace MobileClima.ViewModel
-{
- public class MapleViewModel : BaseViewModel
- {
- public MapleClient client { get; private set; }
-
- public ObservableCollection TemperatureLog { get; set; }
-
- public ObservableCollection WeatherLog { get; set; }
-
- int _serverPort;
- public int ServerPort
- {
- get => _serverPort;
- set { _serverPort = value; OnPropertyChanged(nameof(ServerPort)); }
- }
-
- bool _isScanning;
- public bool IsScanning
- {
- get => _isScanning;
- set { _isScanning = value; OnPropertyChanged(nameof(IsScanning)); }
- }
-
- bool isRefreshing;
- public bool IsRefreshing
- {
- get => isRefreshing;
- set { isRefreshing = value; OnPropertyChanged(nameof(IsRefreshing)); }
- }
-
- bool _isServerListEmpty;
- public bool IsServerListEmpty
- {
- get => _isServerListEmpty;
- set { _isServerListEmpty = value; OnPropertyChanged(nameof(IsServerListEmpty)); }
- }
-
- string ipAddress;
- public string IpAddress
- {
- get => ipAddress;
- set { ipAddress = value; OnPropertyChanged(nameof(IpAddress)); }
- }
-
- ServerModel _selectedServer;
- public ServerModel SelectedServer
- {
- get => _selectedServer;
- set
- {
- if (value == null) return;
- _selectedServer = value;
- IpAddress = _selectedServer.IpAddress;
- OnPropertyChanged(nameof(SelectedServer));
- }
- }
-
- public ObservableCollection HostList { get; set; }
-
- public ICommand SearchServersCommand { get; private set; }
-
- public ICommand UpdateReadingsCommand { get; private set; }
-
- public MapleViewModel(bool isClimaPro)
- {
- IsClimaPro = isClimaPro;
-
- if (isClimaPro)
- {
- WeatherLog = new ObservableCollection();
- }
- else
- {
- TemperatureLog = new ObservableCollection();
- }
-
- HostList = new ObservableCollection();
-
- ServerPort = 5417;
-
- client = new MapleClient();
- client.Servers.CollectionChanged += ServersCollectionChanged;
-
- UpdateReadingsCommand = new Command(async () =>
- {
- if(IsRefreshing)
- return;
- IsRefreshing = true;
-
- if (isClimaPro)
- {
- await GetClimateLogs();
- }
- else
- {
- await GetTemperatureLogs();
- }
-
- IsRefreshing = false;
- });
-
- SearchServersCommand = new Command(async () => await GetServers());
- }
-
- void ServersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- switch (e.Action)
- {
- case NotifyCollectionChangedAction.Add:
- foreach (ServerModel server in e.NewItems)
- {
- HostList.Add(new ServerModel() { Name = $"{server.Name} ({server.IpAddress})", IpAddress = server.IpAddress });
- Console.WriteLine($"'{server.Name}' @ ip:[{server.IpAddress}]");
- }
- break;
- }
- }
-
- async Task GetServers()
- {
- if (IsScanning)
- return;
- IsScanning = true;
-
- try
- {
- IsServerListEmpty = false;
-
- await client.StartScanningForAdvertisingServers();
-
- //HostList.Add(new ServerModel() { Name = "Meadow (192.168.1.81)", IpAddress = "192.168.1.81" });
-
- if (HostList.Count == 0)
- {
- IsServerListEmpty = true;
- }
- else
- {
- IsServerListEmpty = false;
- SelectedServer = HostList[0];
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- finally
- {
- IsScanning = false;
- }
- }
-
- async Task GetTemperatureLogs()
- {
- try
- {
- var response = await client.GetAsync(
- hostAddress: SelectedServer != null ? SelectedServer.IpAddress : IpAddress,
- port: ServerPort,
- endPoint: "gettemperaturelogs");
-
- if (response == null)
- return;
-
- var values = System.Text.Json.JsonSerializer.Deserialize>(response);
-
- TemperatureLog.Clear();
- foreach (var value in values)
- {
- TemperatureLog.Add(value);
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
-
- async Task GetClimateLogs()
- {
- try
- {
- var response = await client.GetAsync(
- hostAddress: SelectedServer != null ? SelectedServer.IpAddress : IpAddress,
- port: ServerPort,
- endPoint: "getclimalogs");
-
- if (response == null)
- return;
-
- var values = System.Text.Json.JsonSerializer.Deserialize>(response);
-
- WeatherLog.Clear();
- foreach (var value in values)
- {
- WeatherLog.Add(value);
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
-
- public async Task LoadData()
- {
- await GetServers();
-
- if (SelectedServer != null)
- {
- UpdateReadingsCommand.Execute(null);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Clima_HackKit_Demo.csproj b/Source/Additional Samples/Clima_HackKit_Demo/Clima_HackKit_Demo.csproj
deleted file mode 100644
index ac6b8f8..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Clima_HackKit_Demo.csproj
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- netstandard2.1
- true
- Library
- App
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/BluetoothServer.cs b/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/BluetoothServer.cs
deleted file mode 100644
index ac30352..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/BluetoothServer.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using Clima.Contracts.Bluetooth;
-using Meadow.Gateways.Bluetooth;
-using Clima_HackKit_Demo.Controller;
-using System;
-using Meadow;
-using Meadow.Foundation;
-
-namespace Clima_HackKit_Demo.Connectivity
-{
- public class BluetoothServer
- {
- private static readonly Lazy instance =
- new Lazy(() => new BluetoothServer());
- public static BluetoothServer Instance => instance.Value;
-
- Definition bleTreeDefinition;
- CharacteristicString temperatureCharacteristic;
-
- private BluetoothServer() { }
-
- public void Initialize()
- {
- bleTreeDefinition = GetDefinition();
- TemperatureController.Instance.TemperatureUpdated += TemperatureUpdated;
- MeadowApp.Device.BluetoothAdapter.StartBluetoothServer(bleTreeDefinition);
-
- LedController.Instance.SetColor(Color.Green);
- }
-
- private void TemperatureUpdated(object sender, Meadow.Units.Temperature e)
- {
- temperatureCharacteristic.SetValue($"{ e.Celsius:N2}°C;");
- }
-
- Definition GetDefinition()
- {
- temperatureCharacteristic = new CharacteristicString(
- name: "Temperature",
- uuid: CharacteristicsConstants.TEMPERATURE,
- maxLength: 20,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read);
-
- var service = new Service(
- name: "ServiceA",
- uuid: 253,
- temperatureCharacteristic
- );
-
- return new Definition("Clima_HackKit_Demo", service);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/MapleRequestHandler.cs b/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/MapleRequestHandler.cs
deleted file mode 100644
index d3e8d5e..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Connectivity/MapleRequestHandler.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using CommonContracts.Models;
-using Meadow.Foundation;
-using Meadow.Foundation.Web.Maple;
-using Meadow.Foundation.Web.Maple.Routing;
-using Clima_HackKit_Demo.Controller;
-using Clima_HackKit_Demo.Database;
-using System.Collections.Generic;
-using Meadow;
-
-namespace Clima_HackKit_Demo.Connectivity
-{
- public class MapleRequestHandler : RequestHandlerBase
- {
- public MapleRequestHandler() { }
-
- [HttpGet("/gettemperaturelogs")]
- public IActionResult GetTemperatureLogs()
- {
- LedController.Instance.SetColor(Color.Magenta);
-
- var logs = DatabaseManager.Instance.GetTemperatureReadings();
-
- var data = new List();
- foreach (var log in logs)
- {
- data.Add(new TemperatureModel()
- {
- Temperature = log.TemperatureCelcius?.ToString("00"),
- DateTime = log.DateTime.ToString("yyyy-MM-dd hh:mm:ss tt"),
- });
- }
-
- LedController.Instance.SetColor(Color.Green);
- return new JsonResult(data);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Controller/DisplayController.cs b/Source/Additional Samples/Clima_HackKit_Demo/Controller/DisplayController.cs
deleted file mode 100644
index 7f3bdf6..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Controller/DisplayController.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-using Meadow.Foundation;
-using Meadow.Foundation.Displays;
-using Meadow.Foundation.Displays.UI;
-using Meadow.Foundation.Graphics;
-using Meadow.Foundation.Graphics.Buffers;
-using Meadow.Units;
-using SimpleJpegDecoder;
-using System;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using Meadow;
-using Meadow.Peripherals.Displays;
-
-namespace Clima_HackKit_Demo.Controller
-{
- public class DisplayController
- {
- private static readonly Lazy instance =
- new Lazy(() => new DisplayController());
- public static DisplayController Instance => instance.Value;
-
- CancellationTokenSource token;
-
- protected Temperature conditions;
-
- protected TextDisplayMenu menu;
- protected St7789 display;
- protected BufferRgb888 logo, wifiConnecting, wifiConnected;
- protected MicroGraphics graphics;
-
- static Color backgroundColor = Color.FromHex("#23ABE3");
-
- protected bool isCelcius = true;
- protected bool isRendering = false;
-
- private DisplayController()
- {
- Initialize();
- }
-
- public void Initialize()
- {
- display = new St7789
- (
- spiBus: MeadowApp.Device.CreateSpiBus(),
- chipSelectPin: null,
- dcPin: MeadowApp.Device.Pins.D01,
- resetPin: MeadowApp.Device.Pins.D00,
- width: 240, height: 240,
- colorMode: ColorMode.Format16bppRgb565
- );
-
- // create our graphics surface that we'll draw onto and then blit to the display
- graphics = new MicroGraphics(display)
- {
- CurrentFont = new Font12x20(),
- Stroke = 3,
- Rotation = RotationType._180Degrees
- };
- graphics.DisplayConfig.FontScale = 2;
-
- var menuItems = new MenuItem[]
- {
- new MenuItem("°C", command: "setCelcius"),
- new MenuItem("°F", command: "setFahrenheit"),
- };
-
- menu = new TextDisplayMenu(graphics, menuItems, false);
- menu.Selected += MenuSelected;
-
- // finally, clear the display so it's ready for action
- graphics.Clear(true);
-
- //and load the logo jpg into a buffer
- logo = LoadJpeg("img_meadow.jpg");
- wifiConnected = LoadJpeg("img_wifi_connected.jpg");
- wifiConnecting = LoadJpeg("img_wifi_connecting.jpg");
- }
-
- BufferRgb888 LoadJpeg(string fileName)
- {
- var jpgData = LoadResource(fileName);
- var decoder = new JpegDecoder();
- decoder.DecodeJpeg(jpgData);
- return new BufferRgb888(decoder.Width, decoder.Height, decoder.GetImageData());
- }
-
- void MenuSelected(object sender, MenuSelectedEventArgs e)
- {
- Console.WriteLine("MenuSelected: " + e.Command);
-
- isCelcius = (e.Command == "setCelcius");
-
- //hide the menu after a selection
- menu.Disable();
- //and update the display
- Render();
- }
-
- void DrawBackground()
- {
- //clear the buffer to a single color
- graphics.Clear(backgroundColor);
-
- //draw the jpeg logo
- graphics.DrawBuffer(
- x: graphics.Width / 2 - logo.Width / 2,
- y: 34,
- buffer: logo);
-
- //draw the circle
- graphics.DrawCircle(
- centerX: display.Width / 2,
- centerY: display.Height / 2,
- radius: (display.Width / 2) - 10,
- color: Color.Black,
- filled: false);
- }
-
- public void UpdateDisplay(Temperature conditions)
- {
- this.conditions = conditions;
-
- if (menu.IsEnabled == false)
- {
- Render();
- }
- }
-
- public void ShowSplashScreen()
- {
- DrawBackground();
-
- graphics.Show();
- }
-
- public void MenuUp()
- {
- menu.Previous();
- }
-
- public void MenuDown()
- {
- menu.Next();
- }
-
- public void MenuSelect()
- {
- if (menu.IsEnabled == false)
- {
- menu.Enable();
- }
- else
- {
- menu.Select();
- }
- }
-
- protected byte[] LoadResource(string filename)
- {
- var assembly = Assembly.GetExecutingAssembly();
- var resourceName = $"Clima_HackKit_Demo.{filename}";
-
- using Stream stream = assembly.GetManifestResourceStream(resourceName);
- using var ms = new MemoryStream();
- stream.CopyTo(ms);
- return ms.ToArray();
- }
-
- protected void Render()
- {
- //if the menu is enabled, it's responsible for drawing the screen
- if (menu.IsEnabled) { return; }
-
- // if we're already rendering, bail out.
- if (isRendering)
- {
- Console.WriteLine("Already in a rendering loop, bailing out.");
- return;
- }
-
- isRendering = true;
-
- DrawBackground();
-
- string tempText;
- if (isCelcius)
- {
- tempText = $"{conditions.Celsius:##.#}°C";
- }
- else
- {
- tempText = $"{conditions.Fahrenheit:##.#}°F";
- }
-
- graphics.DrawText(
- x: display.Width / 2,
- y: 140,
- text: tempText,
- color: Color.Black,
- scaleFactor: ScaleFactor.X2,
- alignmentH: HorizontalAlignment.Center);
-
- graphics.Show();
-
- isRendering = false;
- }
-
- public async Task StartWifiConnectingAnimation()
- {
- token = new CancellationTokenSource();
-
- while (!token.IsCancellationRequested)
- {
- graphics.DrawBuffer(
- x: graphics.Width / 2 - wifiConnecting.Width / 2,
- y: 134,
- buffer: wifiConnecting);
- graphics.Show();
-
- await Task.Delay(500);
-
- graphics.DrawBuffer(
- x: graphics.Width / 2 - wifiConnected.Width / 2,
- y: 134,
- buffer: wifiConnected);
- graphics.Show();
-
- await Task.Delay(500);
- }
- }
-
- public void StopWifiConnectingAnimation()
- {
- token.Cancel();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Controller/LedController.cs b/Source/Additional Samples/Clima_HackKit_Demo/Controller/LedController.cs
deleted file mode 100644
index b0a55a6..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Controller/LedController.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Meadow.Foundation;
-using Meadow.Foundation.Leds;
-using System;
-using Meadow;
-
-namespace Clima_HackKit_Demo.Controller
-{
- public class LedController
- {
- private static readonly Lazy instance =
- new Lazy(() => new LedController());
- public static LedController Instance => instance.Value;
-
- RgbPwmLed led;
-
- private LedController()
- {
- Initialize();
- }
-
- private void Initialize()
- {
- led = new RgbPwmLed(
- MeadowApp.Device.Pins.OnboardLedRed,
- MeadowApp.Device.Pins.OnboardLedGreen,
- MeadowApp.Device.Pins.OnboardLedBlue
- );
- }
-
- public void SetColor(Color color)
- {
- led.SetColor(color);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Controller/TemperatureController.cs b/Source/Additional Samples/Clima_HackKit_Demo/Controller/TemperatureController.cs
deleted file mode 100644
index 1b9c7e8..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Controller/TemperatureController.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Meadow.Foundation.Sensors.Temperature;
-using Meadow.Units;
-using Clima_HackKit_Demo.Database;
-using System;
-
-namespace Clima_HackKit_Demo.Controller
-{
- public class TemperatureController
- {
- private static readonly Lazy instance =
- new Lazy(() => new TemperatureController());
- public static TemperatureController Instance => instance.Value;
-
- public event EventHandler TemperatureUpdated = delegate { };
-
- AnalogTemperature analogTemperature;
-
- private TemperatureController() { }
-
- public void Initialize()
- {
- analogTemperature = new AnalogTemperature(
- MeadowApp.Device.Pins.A00, AnalogTemperature.KnownSensorType.LM35);
- analogTemperature.StartUpdating(TimeSpan.FromSeconds(30));
- analogTemperature.Updated += AnalogTemperatureUpdated;
- }
-
- void AnalogTemperatureUpdated(object sender, Meadow.IChangeResult e)
- {
- Console.Write($"Saving ({e.New.Celsius},{DateTime.Now})...");
-
- var reading = new TemperatureTable()
- {
- TemperatureValue = e.New,
- DateTime = DateTime.Now
- };
- DatabaseManager.Instance.SaveReading(reading);
-
- TemperatureUpdated.Invoke(this, e.New);
-
- DisplayController.Instance.UpdateDisplay(e.New);
-
- Console.WriteLine("done!");
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Database/DatabaseManager.cs b/Source/Additional Samples/Clima_HackKit_Demo/Database/DatabaseManager.cs
deleted file mode 100644
index f062fdd..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Database/DatabaseManager.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Meadow;
-using Meadow.Foundation;
-using Clima_HackKit_Demo.Controller;
-using SQLite;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Clima_HackKit_Demo.Database
-{
- public class DatabaseManager
- {
- private static readonly Lazy instance =
- new Lazy(() => new DatabaseManager());
- public static DatabaseManager Instance => instance.Value;
-
- bool isConfigured = false;
-
- SQLiteConnection Database { get; set; }
-
- private DatabaseManager()
- {
- Initialize();
- }
-
- protected void Initialize()
- {
- var databasePath = Path.Combine(MeadowOS.FileSystem.DataDirectory, "ClimateReadings.db");
- Database = new SQLiteConnection(databasePath);
-
- Database.DropTable(); //convenience while we work on the model object
- Database.CreateTable();
- isConfigured = true;
- }
-
- public bool SaveReading(TemperatureTable temperature)
- {
- LedController.Instance.SetColor(WildernessLabsColors.ChileanFireDark);
-
- if (isConfigured == false)
- {
- Console.WriteLine("SaveUpdateReading: DB not ready");
- return false;
- }
-
- if (temperature == null)
- {
- Console.WriteLine("SaveUpdateReading: Conditions is null");
- return false;
- }
-
- Database.Insert(temperature);
-
- LedController.Instance.SetColor(Color.Green);
- return true;
- }
-
- public List GetTemperatureReadings()
- {
- return Database.Table().ToList();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Database/TemperatureTable.cs b/Source/Additional Samples/Clima_HackKit_Demo/Database/TemperatureTable.cs
deleted file mode 100644
index 50deec8..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Database/TemperatureTable.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Meadow.Units;
-using SQLite;
-using System;
-
-namespace Clima_HackKit_Demo.Database
-{
- [Table("TemperatureReadings")]
- public class TemperatureTable
- {
- [PrimaryKey, AutoIncrement]
- public int? ID { get; set; }
-
- public DateTime DateTime { get; set; }
-
- public double? TemperatureCelcius
- {
- get => TemperatureValue?.Celsius;
- set => TemperatureValue = new Temperature(value.Value,
- Temperature.UnitType.Celsius);
- }
-
- [Ignore]
- public Temperature? TemperatureValue { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/MeadowApp.cs b/Source/Additional Samples/Clima_HackKit_Demo/MeadowApp.cs
deleted file mode 100644
index 60d9959..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/MeadowApp.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Clima_HackKit_Demo.Connectivity;
-using Clima_HackKit_Demo.Controller;
-using Meadow;
-using Meadow.Devices;
-using Meadow.Foundation;
-using Meadow.Foundation.Sensors.Buttons;
-using Meadow.Foundation.Web.Maple;
-using Meadow.Hardware;
-using System;
-using System.Threading.Tasks;
-
-namespace Clima_HackKit_Demo
-{
- // Change F7FeatherV2 to F7FeatherV1 for V1.x boards
- public class MeadowApp : App
- {
- bool isWiFi = false;
-
- PushButton buttonUp, buttonMenu;
- PollingPushButton buttonDown;
-
- public override Task Initialize()
- {
- LedController.Instance.SetColor(Color.Red);
-
- buttonUp = new PushButton(Device.Pins.D03);
- buttonDown = new PollingPushButton(Device.Pins.D02);
- buttonMenu = new PushButton(Device.Pins.D04);
-
- buttonUp.Clicked += (s, e) => DisplayController.Instance.MenuUp();
- buttonDown.Clicked += (s, e) => DisplayController.Instance.MenuDown();
- buttonMenu.Clicked += (s, e) => DisplayController.Instance.MenuSelect();
-
- DisplayController.Instance.ShowSplashScreen();
-
- TemperatureController.Instance.Initialize();
-
- if (isWiFi)
- {
- InitializeMaple().Wait();
- }
- else
- {
- InitializeBluetooth();
- }
-
- return base.Initialize();
- }
-
- void InitializeBluetooth()
- {
- BluetoothServer.Instance.Initialize();
- }
-
- async Task InitializeMaple()
- {
- _ = DisplayController.Instance.StartWifiConnectingAnimation();
-
- var wifi = Device.NetworkAdapters.Primary();
- wifi.NetworkConnected += NetworkConnected;
- await wifi.Connect(Secrets.WIFI_NAME, Secrets.WIFI_PASSWORD, TimeSpan.FromSeconds(45));
- }
-
- private void NetworkConnected(INetworkAdapter sender, NetworkConnectionEventArgs args)
- {
- DisplayController.Instance.StopWifiConnectingAnimation();
-
- var mapleServer = new MapleServer(sender.IpAddress, 5417, true, logger: Resolver.Log);
- mapleServer.Start();
-
- LedController.Instance.SetColor(Color.Green);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/Secrets.cs b/Source/Additional Samples/Clima_HackKit_Demo/Secrets.cs
deleted file mode 100644
index ad2416c..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/Secrets.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Clima_HackKit_Demo
-{
- public class Secrets
- {
- ///
- /// Name of the WiFi network to use.
- ///
- public const string WIFI_NAME = "SSID";
-
- ///
- /// Password for the WiFi network names in WIFI_NAME.
- ///
- public const string WIFI_PASSWORD = "PASSWORD";
- }
-}
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/img_meadow.jpg b/Source/Additional Samples/Clima_HackKit_Demo/img_meadow.jpg
deleted file mode 100644
index 841af22..0000000
Binary files a/Source/Additional Samples/Clima_HackKit_Demo/img_meadow.jpg and /dev/null differ
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connected.jpg b/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connected.jpg
deleted file mode 100644
index 62c6eb1..0000000
Binary files a/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connected.jpg and /dev/null differ
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connecting.jpg b/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connecting.jpg
deleted file mode 100644
index 8c0c2cf..0000000
Binary files a/Source/Additional Samples/Clima_HackKit_Demo/img_wifi_connecting.jpg and /dev/null differ
diff --git a/Source/Additional Samples/Clima_HackKit_Demo/meadow.config.yaml b/Source/Additional Samples/Clima_HackKit_Demo/meadow.config.yaml
deleted file mode 100644
index 7978338..0000000
--- a/Source/Additional Samples/Clima_HackKit_Demo/meadow.config.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-# Acceptable values for true: true, 1, yes
-# Acceptable values for false: false, 0, no
-
-#===============================================================================
-# main device config
-
-MonoControl:
-Options: --jit
-
-Device:
-# Name of the device on the network.
-Name: MeadowClimaHackKit
-
-#===============================================================================
-# Network configuration.
-Network:
-
-# Automatically attempt to get the time at startup?
-GetNetworkTimeAtStartup: 1
-
-# Time synchronization period in seconds.
-NtpRefreshPeriod: 600
-
-# Name of the NTP servers.
-NtpServers:
-- time.google.com
-- time1.google.com
-- time2.google.com
-- time3.google.com
-
-# IP addresses of the DNS servers.
-DnsServers:
-- 142.103.1.1
-- 65.39.139.53
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Clima_SQLite_Demo.csproj b/Source/Additional Samples/Clima_SQLite_Demo/Clima_SQLite_Demo.csproj
deleted file mode 100644
index 399d10f..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Clima_SQLite_Demo.csproj
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
- netstandard2.1
- true
- Library
- App
- enable
-
-
- 9.0
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/BluetoothServer.cs b/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/BluetoothServer.cs
deleted file mode 100644
index 39696b4..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/BluetoothServer.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-using System;
-using Clima.Contracts.Bluetooth;
-using Meadow.Gateways.Bluetooth;
-
-namespace Clima_SQLite_Demo.Connectivity
-{
- public class BluetoothServer
- {
- private static readonly Lazy instance =
- new Lazy(() => new BluetoothServer());
- public static BluetoothServer Instance => instance.Value;
-
- Definition bleTreeDefinition;
- CharacteristicString tempCharacteristic;
- CharacteristicString pressureCharacteristic;
- CharacteristicString humidityCharacteristic;
- CharacteristicString rainFallCharacteristic;
- CharacteristicString windSpeedCharacteristic;
- CharacteristicString windDirectionCharacteristic;
-
- private BluetoothServer() { }
-
- public void Initialize()
- {
- bleTreeDefinition = GetDefinition();
- ClimateMonitorAgent.Instance.ClimateConditionsUpdated += ClimateConditionsUpdated;
- MeadowApp.Device.BluetoothAdapter.StartBluetoothServer(bleTreeDefinition);
- }
-
- private void ClimateConditionsUpdated(object sender, Models.ClimateConditions climateConditions)
- {
- Console.WriteLine("New climate data, setting BLE characteristics.");
- if(climateConditions.New?.Temperature is { } temperature)
- {
- tempCharacteristic.SetValue($"{ temperature.Fahrenheit:N2}°F;");
- }
- if (climateConditions.New?.Pressure is { } pressure)
- {
- pressureCharacteristic.SetValue($"{ pressure.Pascal:N2}hPa;");
- }
- if (climateConditions.New?.Humidity is { } humidity)
- {
- humidityCharacteristic.SetValue($"{ humidity:N2}%;");
- }
- if (climateConditions.New?.RainFall is { } rainFall)
- {
- rainFallCharacteristic.SetValue($"{ rainFall:N2}mm;");
- }
- if (climateConditions.New?.WindSpeed is { } windSpeed)
- {
- windSpeedCharacteristic.SetValue($"{ windSpeed.KilometersPerHour:N2}Kmph;");
- }
- if (climateConditions.New?.WindDirection is { } windDirection)
- {
- windDirectionCharacteristic.SetValue($"{ windDirection};");
- }
- }
-
- protected Definition GetDefinition()
- {
- tempCharacteristic = new CharacteristicString(
- "Temperature",
- uuid: CharacteristicsConstants.TEMPERATURE,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- pressureCharacteristic = new CharacteristicString(
- "Pressure",
- uuid: CharacteristicsConstants.PRESSURE,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- humidityCharacteristic = new CharacteristicString(
- "Humidity",
- uuid: CharacteristicsConstants.HUMIDITY,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- rainFallCharacteristic = new CharacteristicString(
- "RainFall",
- uuid: CharacteristicsConstants.RAIN_FALL,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- windSpeedCharacteristic = new CharacteristicString(
- "WindSpeed",
- uuid: CharacteristicsConstants.WIND_SPEED,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- windDirectionCharacteristic = new CharacteristicString(
- "WindDirection",
- uuid: CharacteristicsConstants.WIND_DIRECTION,
- permissions: CharacteristicPermission.Read,
- properties: CharacteristicProperty.Read,
- maxLength: 32
- );
-
- ICharacteristic[] characteristics =
- {
- tempCharacteristic,
- pressureCharacteristic,
- humidityCharacteristic,
- rainFallCharacteristic,
- windSpeedCharacteristic,
- windDirectionCharacteristic
- };
-
- var service = new Service(
- name: "ServiceA",
- uuid: 253,
- characteristics
- );
-
- return new Definition("MeadowClimaPro", service);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/MapleRequestHandler.cs b/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/MapleRequestHandler.cs
deleted file mode 100644
index 79ba0a4..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Connectivity/MapleRequestHandler.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using CommonContracts.Models;
-using Meadow.Foundation.Web.Maple;
-using Meadow.Foundation.Web.Maple.Routing;
-using Clima_SQLite_Demo.Database;
-using System.Collections.Generic;
-
-namespace Clima_SQLite_Demo.Connectivity
-{
- public class MapleRequestHandler : RequestHandlerBase
- {
- public MapleRequestHandler() { }
-
- [HttpGet("/getclimalogs")]
- public IActionResult GetClimateLogs()
- {
- var logs = DatabaseManager.Instance.GetAllClimateReadings();
-
- var data = new List();
- foreach (var log in logs)
- {
- data.Insert(0, new ClimateModel()
- {
- Date = log.DateTime.ToString(),
- Temperature = log.Temperature.ToString(),
- Pressure = log.Pressure.ToString(),
- Humidity = log.Humidity.ToString(),
- WindDirection = log.WindDirection.ToString(),
- WindSpeed = log.WindSpeed.ToString()
- });
- }
-
- return new JsonResult(data);
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Controller/ClimateMonitorAgent.cs b/Source/Additional Samples/Clima_SQLite_Demo/Controller/ClimateMonitorAgent.cs
index 48ce848..ebc77bc 100644
--- a/Source/Additional Samples/Clima_SQLite_Demo/Controller/ClimateMonitorAgent.cs
+++ b/Source/Additional Samples/Clima_SQLite_Demo/Controller/ClimateMonitorAgent.cs
@@ -24,7 +24,7 @@ private ClimateMonitorAgent() { }
public async Task Initialize()
{
- clima = Meadow.Devices.Clima.Create();
+ clima = Meadow.Devices.ClimaHardwareProvider.Create();
await StartUpdating(TimeSpan.FromSeconds(30));
}
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Database/ClimateReading.cs b/Source/Additional Samples/Clima_SQLite_Demo/Database/ClimateReading.cs
deleted file mode 100644
index e40fcd9..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Database/ClimateReading.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using Meadow.Units;
-using SQLite;
-using MU = Meadow.Units;
-
-namespace Clima_SQLite_Demo.Database
-{
- [Table("ClimateReadings")]
- public class ClimateReading
- {
- [PrimaryKey, AutoIncrement]
- public int? ID { get; set; }
-
- public double? TemperatureValue
- {
- get => Temperature?.Celsius;
- set => Temperature = new Temperature(value.Value, MU.Temperature.UnitType.Celsius);
- }
-
- public double? PressureValue
- {
- get => Pressure?.Bar;
- set => Pressure = new Pressure(value.Value, MU.Pressure.UnitType.Bar);
- }
-
- public double? HumidityValue
- {
- get => Humidity?.Percent;
- set => Humidity = new RelativeHumidity(value.Value, MU.RelativeHumidity.UnitType.Percent);
- }
-
- public double? RainFallValue
- {
- get => RainFall?.Millimeters;
- set => RainFall = new Length(value.Value, MU.Length.UnitType.Millimeters);
- }
-
- public Azimuth16PointCardinalNames? WindDirectionValue
- {
- get => WindDirection;
- set => WindDirection = value;
- }
-
- public double? WindSpeedValue
- {
- get => WindSpeed?.KilometersPerHour;
- set => WindSpeed = new Speed(value.Value, MU.Speed.UnitType.KilometersPerHour);
- }
-
- [Indexed]
- public DateTime DateTime { get; set; }
-
- ///
- /// Whether or not this particular reading has been uploaded to the cloud.
- ///
- public bool Synchronized { get; set; }
-
- [Ignore]
- public Temperature? Temperature { get; set; }
- [Ignore]
- public Pressure? Pressure { get; set; }
- [Ignore]
- public RelativeHumidity? Humidity { get; set; }
- [Ignore]
- public Length? RainFall { get; set; }
- [Ignore]
- public Azimuth16PointCardinalNames? WindDirection { get; set; }
- [Ignore]
- public Speed? WindSpeed { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Database/DatabaseManager.cs b/Source/Additional Samples/Clima_SQLite_Demo/Database/DatabaseManager.cs
deleted file mode 100644
index 61e63c8..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Database/DatabaseManager.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using Meadow;
-using SQLite;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Clima_SQLite_Demo.Database
-{
- public class DatabaseManager
- {
- private static readonly Lazy instance =
- new Lazy(() => new DatabaseManager());
- public static DatabaseManager Instance => instance.Value;
-
- bool isConfigured = false;
-
- SQLiteConnection Database { get; set; }
-
- private DatabaseManager()
- {
- Initialize();
- }
-
- protected void Initialize()
- {
- var databasePath = Path.Combine(MeadowOS.FileSystem.DataDirectory, "ClimateReadings.db");
- Database = new SQLiteConnection(databasePath);
-
- Database.DropTable(); //convenience while we work on the model object
- Database.CreateTable();
- isConfigured = true;
- }
-
- public bool SaveReading(ClimateReading climate)
- {
- if (isConfigured == false)
- {
- Console.WriteLine("SaveUpdateReading: DB not ready");
- return false;
- }
-
- if (climate == null)
- {
- Console.WriteLine("SaveUpdateReading: Conditions is null");
- return false;
- }
-
- Console.WriteLine("Saving climate reading to DB");
-
- Database.Insert(climate);
-
- Console.WriteLine($"Successfully saved to database");
-
- return true;
- }
-
- public ClimateReading GetClimateReading(int id)
- {
- return Database.Get(id);
- }
-
- public List GetAllClimateReadings()
- {
- return Database.Table().ToList();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/MeadowApp.cs b/Source/Additional Samples/Clima_SQLite_Demo/MeadowApp.cs
deleted file mode 100644
index 2d4d0da..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/MeadowApp.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Clima_SQLite_Demo.Connectivity;
-using Meadow;
-using Meadow.Devices;
-using Meadow.Foundation.Web.Maple;
-using Meadow.Hardware;
-using System;
-using System.Threading.Tasks;
-
-namespace Clima_SQLite_Demo
-{
- public class MeadowApp : App
- {
- bool isWiFi = true;
-
- public override async Task Initialize()
- {
- await ClimateMonitorAgent.Instance.Initialize();
-
- if (isWiFi)
- {
- try
- {
- var wifi = Device.NetworkAdapters.Primary();
- wifi.NetworkConnected += NetworkConnected;
- await wifi.Connect(Secrets.WIFI_NAME, Secrets.WIFI_PASSWORD, TimeSpan.FromSeconds(45));
- }
- catch (Exception ex)
- {
- Resolver.Log.Error(ex.Message);
- }
- }
- else
- {
- BluetoothServer.Instance.Initialize();
- }
- }
-
- private void NetworkConnected(INetworkAdapter sender, NetworkConnectionEventArgs args)
- {
- var mapleServer = new MapleServer(sender.IpAddress, 5417, true, logger: Resolver.Log);
- mapleServer.Start();
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Models/ClimateConditions.cs b/Source/Additional Samples/Clima_SQLite_Demo/Models/ClimateConditions.cs
deleted file mode 100644
index 80fa2a7..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Models/ClimateConditions.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Clima_SQLite_Demo.Database;
-
-namespace Clima_SQLite_Demo.Models
-{
- public class ClimateConditions
- {
- public ClimateReading? New { get; set; }
- public ClimateReading? Old { get; set; }
-
- public ClimateConditions() { }
- public ClimateConditions(ClimateReading newClimate, ClimateReading oldClimate)
- {
- New = newClimate;
- Old = oldClimate;
- }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/Secrets.cs b/Source/Additional Samples/Clima_SQLite_Demo/Secrets.cs
deleted file mode 100644
index 7381248..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/Secrets.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Clima_SQLite_Demo
-{
- public class Secrets
- {
- ///
- /// Name of the WiFi network to use.
- ///
- public const string WIFI_NAME = "SSID";
-
- ///
- /// Password for the WiFi network names in WIFI_NAME.
- ///
- public const string WIFI_PASSWORD = "PASSWORD";
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_SQLite_Demo/meadow.config.yaml b/Source/Additional Samples/Clima_SQLite_Demo/meadow.config.yaml
deleted file mode 100644
index 780ce65..0000000
--- a/Source/Additional Samples/Clima_SQLite_Demo/meadow.config.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-# Acceptable values for true: true, 1, yes
-# Acceptable values for false: false, 0, no
-
-#===============================================================================
-# main device config
-
-MonoControl:
-Options: --jit
-
-Device:
-# Name of the device on the network.
-Name: MeadowClimaProKit
-
-#===============================================================================
-# Network configuration.
-Network:
-
-# Automatically attempt to get the time at startup?
-GetNetworkTimeAtStartup: 1
-
-# Time synchronization period in seconds.
-NtpRefreshPeriod: 600
-
-# Name of the NTP servers.
-NtpServers:
-- time.google.com
-- time1.google.com
-- time2.google.com
-- time3.google.com
-
-# IP addresses of the DNS servers.
-DnsServers:
-- 142.103.1.1
-- 65.39.139.53
\ No newline at end of file
diff --git a/Source/Additional Samples/CommonContracts/Bluetooth/CharacteristicsConstants.cs b/Source/Additional Samples/CommonContracts/Bluetooth/CharacteristicsConstants.cs
deleted file mode 100644
index d637d47..0000000
--- a/Source/Additional Samples/CommonContracts/Bluetooth/CharacteristicsConstants.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Clima.Contracts.Bluetooth
-{
- public static class CharacteristicsConstants
- {
- public const string TEMPERATURE = "e78f7b5e-842b-4b99-94e3-7401bf72b870";
- public const string PRESSURE = "2d45f026-d8ea-4d47-813a-13e8f788d328";
- public const string HUMIDITY = "143a3841-e244-4520-a456-214e048a030f";
- public const string RAIN_FALL = "017e99d6-8a61-11eb-8dcd-0242ac1300aa";
- public const string WIND_SPEED = "5a0bb016-69ab-4a49-a2f2-de5b292458f3";
- public const string WIND_DIRECTION = "b54aa605-c1ae-47cd-b4e1-0c5ff6af735c";
- }
-}
diff --git a/Source/Additional Samples/CommonContracts/CommonContracts.projitems b/Source/Additional Samples/CommonContracts/CommonContracts.projitems
deleted file mode 100644
index 6f94602..0000000
--- a/Source/Additional Samples/CommonContracts/CommonContracts.projitems
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
- true
- {567267B3-ED96-4FEA-B555-2EE203372EA4}
-
-
- Clima.Contracts
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/CommonContracts/CommonContracts.shproj b/Source/Additional Samples/CommonContracts/CommonContracts.shproj
deleted file mode 100644
index 0cf9d37..0000000
--- a/Source/Additional Samples/CommonContracts/CommonContracts.shproj
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- {567267B3-ED96-4FEA-B555-2EE203372EA4}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Additional Samples/CommonContracts/Models/ClimateModel.cs b/Source/Additional Samples/CommonContracts/Models/ClimateModel.cs
deleted file mode 100644
index b041d04..0000000
--- a/Source/Additional Samples/CommonContracts/Models/ClimateModel.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace CommonContracts.Models
-{
- public class ClimateModel
- {
- public string Date { get; set; }
- public string Temperature { get; set; }
- public string Pressure { get; set; }
- public string Humidity { get; set; }
- public string Rain { get; set; }
- public string WindSpeed { get; set; }
- public string WindDirection { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/CommonContracts/Models/TemperatureModel.cs b/Source/Additional Samples/CommonContracts/Models/TemperatureModel.cs
deleted file mode 100644
index cf6ac1b..0000000
--- a/Source/Additional Samples/CommonContracts/Models/TemperatureModel.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace CommonContracts.Models
-{
- public class TemperatureModel
- {
- public string Temperature { get; set; }
- public string DateTime { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Source/Additional Samples/CommonContracts/Models/WeatherModel.cs b/Source/Additional Samples/CommonContracts/Models/WeatherModel.cs
deleted file mode 100644
index 01845a6..0000000
--- a/Source/Additional Samples/CommonContracts/Models/WeatherModel.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Text.Json.Serialization;
-
-namespace CommonContracts.Models
-{
- public class ClimateModel
- {
- [JsonPropertyName("date")]
- public string Date { get; set; }
-
- [JsonPropertyName("temperature")]
- public string Temperature { get; set; }
-
- [JsonPropertyName("pressure")]
- public string Pressure { get; set; }
-
- [JsonPropertyName("humdity")]
- public string Humidity { get; set; }
-
- [JsonPropertyName("rain")]
- public string Rain { get; set; }
-
- [JsonPropertyName("windspeed")]
- public string WindSpeed { get; set; }
-
- [JsonPropertyName("winddirection")]
- public string WindDirection { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Source/Clima_Demo/Clima_Demo.csproj b/Source/Clima_Demo/Clima_Demo.csproj
index fe32342..67fc3f5 100644
--- a/Source/Clima_Demo/Clima_Demo.csproj
+++ b/Source/Clima_Demo/Clima_Demo.csproj
@@ -11,6 +11,9 @@
+
+ Always
+ Always
diff --git a/Source/Clima_Demo/MeadowApp.cs b/Source/Clima_Demo/MeadowApp.cs
index 599a554..adbe0dc 100644
--- a/Source/Clima_Demo/MeadowApp.cs
+++ b/Source/Clima_Demo/MeadowApp.cs
@@ -1,30 +1,79 @@
using Meadow;
using Meadow.Devices;
+using Meadow.Devices.Esp32.MessagePayloads;
using Meadow.Hardware;
-using System.Collections.Generic;
using System.Threading.Tasks;
namespace Clima_Demo;
-public class MeadowApp : App
+public class ClimaApp : ClimaAppBase
{
- private MainController mainController;
+ private MainController? mainController;
- public MeadowApp()
+ public override Task Initialize()
{
+ Resolver.Log.Info($"Initialize...");
+
mainController = new MainController();
+
+ var reliabilityService = Resolver.Services.Get();
+ reliabilityService!.MeadowSystemError += OnMeadowSystemError;
+
+ if (reliabilityService.LastBootWasFromCrash)
+ {
+ mainController.LogAppStartupAfterCrash(reliabilityService.GetCrashData());
+ reliabilityService.ClearCrashData();
+ }
+
+ var wifi = Hardware.ComputeModule.NetworkAdapters.Primary();
+ mainController.Initialize(Hardware, wifi);
+
+ return Task.CompletedTask;
}
- public override void OnBootFromCrash(IEnumerable crashReports)
+ private void OnMeadowSystemError(MeadowSystemErrorInfo error, bool recommendReset, out bool forceReset)
{
- mainController.LogAppStartupAfterCrash(crashReports);
+ if (error is Esp32SystemErrorInfo espError)
+ {
+ Resolver.Log.Warn($"The ESP32 has had an error ({espError.StatusCode}).");
+ }
+ else
+ {
+ Resolver.Log.Info($"We've had a system error: {error}");
+ }
+
+ if (recommendReset)
+ {
+ Resolver.Log.Warn($"Meadow is recommending a device reset");
+ }
+
+ forceReset = recommendReset;
+
+ // override the reset recommendation
+ //forceReset = false;
}
- public override Task Initialize()
+ private void OnMeadowSystemError(object sender, MeadowSystemErrorInfo e)
{
- var wifi = Device.NetworkAdapters.Primary();
- mainController.Initialize(Clima.Create(), wifi);
+ Resolver.Log.Error($"App has detected a system error: {e.Message}");
- return Task.CompletedTask;
+ if (e is Esp32SystemErrorInfo esp)
+ {
+ Resolver.Log.Error($"ESP function: {esp.Function}");
+ Resolver.Log.Error($"ESP status code: {esp.StatusCode}");
+ }
+
+ if (e.Exception != null)
+ {
+ Resolver.Log.Error($"Exception: {e.Exception.Message}");
+ Resolver.Log.Error($"ErrorNumber: {e.ErrorNumber}");
+ Resolver.Log.Error($"HResult: {e.Exception.HResult}");
+
+ if (e.Exception.InnerException != null)
+ {
+ Resolver.Log.Error($"InnerException: {e.Exception.InnerException.Message}");
+ Resolver.Log.Error($"HResult: {e.Exception.InnerException.HResult}");
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Source/Clima_Demo/app.build.yaml b/Source/Clima_Demo/app.build.yaml
new file mode 100644
index 0000000..f9f0c47
--- /dev/null
+++ b/Source/Clima_Demo/app.build.yaml
@@ -0,0 +1,2 @@
+Deploy:
+ NoLink: [ Clima ]
\ No newline at end of file
diff --git a/Source/Clima_Demo/app.config.yaml b/Source/Clima_Demo/app.config.yaml
index 08ab07f..55fbb50 100644
--- a/Source/Clima_Demo/app.config.yaml
+++ b/Source/Clima_Demo/app.config.yaml
@@ -4,13 +4,17 @@
Lifecycle:
# Control whether Meadow will restart when an unhandled app exception occurs. Combine with Lifecycle > AppFailureRestartDelaySeconds to control restart timing.
- RestartOnAppFailure: true
+ RestartOnAppFailure: false
# # When app set to restart automatically on app failure,
# AppFailureRestartDelaySeconds: 15
-# # Adjust the level of logging detail.
+# Logging configuration.
Logging:
+
+ # Adjust the level of logging detail.
LogLevel:
+
+ # Trace, Debug, Information, Warning, or Error
Default: Trace
MeadowCloud:
diff --git a/Source/Clima_Demo/meadow.config.yaml b/Source/Clima_Demo/meadow.config.yaml
index ae6dfe8..e1b04ee 100644
--- a/Source/Clima_Demo/meadow.config.yaml
+++ b/Source/Clima_Demo/meadow.config.yaml
@@ -1,18 +1,49 @@
-Device:
+# Acceptable values for true: true, 1, yes
+# Acceptable values for false: false, 0, no
+
+# Main Device Config
+Device:
+
+ # Name of the device on the network.
Name: Clima
+ # Uncomment if SD card hardware present on this hardware
+ # (e.g., Core-Compute module with SD add-on)? Optional; default value is `false`.
+# SdStorageSupported: true
+
+# Control how the ESP coprocessor will start and operate.
Coprocessor:
+
+ # Should the ESP32 automatically attempt to connect to an access point at startup?
+ # If set to true, wifi.yaml credentials must be stored in the device.
AutomaticallyStartNetwork: true
+
+ # Should the ESP32 automatically reconnect to the configured access point?
AutomaticallyReconnect: true
- MaximumRetryCount: 7
+ # Maximum number of retry attempts for connections etc. before an error code is returned.
+ MaximumRetryCount: 99
+
+# Network configuration.
Network:
+
+ # Default Interface
DefaultInterface: WiFi
+
+ # Automatically attempt to get the time at startup?
GetNetworkTimeAtStartup: true
- NtpRefreshPeriodSeconds: 600
+
+ # Time synchronization period in seconds.
+ NtpRefreshPeriod: 600
+
+ # Name of the NTP servers.
NtpServers:
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- 3.pool.ntp.org
+ # IP addresses of the DNS servers.
+ DnsServers:
+ - 1.1.1.1
+ - 8.8.8.8
\ No newline at end of file
diff --git a/Source/Clima_Demo/readme.md b/Source/Clima_Demo/readme.md
new file mode 100644
index 0000000..f9c48f5
--- /dev/null
+++ b/Source/Clima_Demo/readme.md
@@ -0,0 +1,27 @@
+```mermaid
+flowchart TD
+%% Nodes
+ A("Boot")
+ B{"Connect to Cloud"}
+ C("Deliver Data")
+ D("Shutdown network")
+ E("Device Sleep")
+ F("Device Wake")
+ G("Collect Telemetry")
+ H{{"`tick++ % pubcount`"}}
+
+ ne_0("== 0")
+ eq_0("!= 0")
+
+%% Edge connections between nodes
+ A --> B
+ B --> yes --> C
+ B --> no --> E
+ C --> D
+ D --> E
+ E -.-> F
+ F --> G
+ G --> H
+ H --> eq_0 --> E
+ H --> ne_0 --> B
+```
\ No newline at end of file
diff --git a/Source/Clima_Demo/wifi.config.yaml b/Source/Clima_Demo/wifi.config.yaml
index 748dc39..1687721 100644
--- a/Source/Clima_Demo/wifi.config.yaml
+++ b/Source/Clima_Demo/wifi.config.yaml
@@ -4,5 +4,5 @@
# # To enable automatically connecting to a default network, make sure to enable the Coprocessor > AutomaticallyStartNetwork value in meadow.config.yaml.
Credentials:
- Ssid: interwebs
- Password: 1234567890
+ Ssid: SSID
+ Password: PASSWORD
diff --git a/Source/Meadow.Clima.sln b/Source/Meadow.Clima.sln
index af5a02a..cec31e7 100644
--- a/Source/Meadow.Clima.sln
+++ b/Source/Meadow.Clima.sln
@@ -6,16 +6,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Clima", "Meadow.Clim
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clima_Demo", "Clima_Demo\Clima_Demo.csproj", "{E914AFEB-4392-443C-A45B-67B71DD81171}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Additional Samples", "Additional Samples", "{4AB0FC09-05D2-4F55-9C2D-13C133456E2F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clima_Companion_App", "Additional Samples\Clima_Companion_App\Clima_Companion_App.csproj", "{D8527A17-C9C4-4388-8712-FA870E5DC331}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clima_HackKit_Demo", "Additional Samples\Clima_HackKit_Demo\Clima_HackKit_Demo.csproj", "{0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clima_SQLite_Demo", "Additional Samples\Clima_SQLite_Demo\Clima_SQLite_Demo.csproj", "{494082D7-2C48-45A6-8FF7-DD553D27BC4A}"
-EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CommonContracts", "Additional Samples\CommonContracts\CommonContracts.shproj", "{567267B3-ED96-4FEA-B555-2EE203372EA4}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -62,77 +52,13 @@ Global
{E914AFEB-4392-443C-A45B-67B71DD81171}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E914AFEB-4392-443C-A45B-67B71DD81171}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{E914AFEB-4392-443C-A45B-67B71DD81171}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhone.Build.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhone.Deploy.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|Any CPU.Build.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhone.ActiveCfg = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhone.Build.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhone.Deploy.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {D8527A17-C9C4-4388-8712-FA870E5DC331}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhone.Build.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhone.Deploy.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|Any CPU.Build.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhone.ActiveCfg = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhone.Build.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhone.Deploy.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhone.Build.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhone.Deploy.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|Any CPU.Build.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhone.ActiveCfg = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhone.Build.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhone.Deploy.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {D8527A17-C9C4-4388-8712-FA870E5DC331} = {4AB0FC09-05D2-4F55-9C2D-13C133456E2F}
- {0B2E742C-9C97-4CE1-8B2A-1390CB3F1B03} = {4AB0FC09-05D2-4F55-9C2D-13C133456E2F}
- {494082D7-2C48-45A6-8FF7-DD553D27BC4A} = {4AB0FC09-05D2-4F55-9C2D-13C133456E2F}
- {567267B3-ED96-4FEA-B555-2EE203372EA4} = {4AB0FC09-05D2-4F55-9C2D-13C133456E2F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CA61E123-F783-4CB3-8EB2-099EE930ADD4}
EndGlobalSection
- GlobalSection(SharedMSBuildProjectFiles) = preSolution
- Additional Samples\CommonContracts\CommonContracts.projitems*{0b2e742c-9c97-4ce1-8b2a-1390cb3f1b03}*SharedItemsImports = 5
- Additional Samples\CommonContracts\CommonContracts.projitems*{494082d7-2c48-45a6-8ff7-dd553d27bc4a}*SharedItemsImports = 5
- Additional Samples\CommonContracts\CommonContracts.projitems*{567267b3-ed96-4fea-b555-2ee203372ea4}*SharedItemsImports = 13
- Additional Samples\CommonContracts\CommonContracts.projitems*{d8527a17-c9c4-4388-8712-fa870e5dc331}*SharedItemsImports = 5
- EndGlobalSection
EndGlobal
diff --git a/Source/Meadow.Clima/ClimaAppBase.cs b/Source/Meadow.Clima/ClimaAppBase.cs
new file mode 100644
index 0000000..33a629b
--- /dev/null
+++ b/Source/Meadow.Clima/ClimaAppBase.cs
@@ -0,0 +1,7 @@
+using Meadow.Devices.Clima.Hardware;
+
+namespace Meadow.Devices;
+
+public abstract class ClimaAppBase : App
+{
+}
diff --git a/Source/Meadow.Clima/Clima.cs b/Source/Meadow.Clima/ClimaHardwareProvider.cs
similarity index 80%
rename from Source/Meadow.Clima/Clima.cs
rename to Source/Meadow.Clima/ClimaHardwareProvider.cs
index eb35032..c788671 100644
--- a/Source/Meadow.Clima/Clima.cs
+++ b/Source/Meadow.Clima/ClimaHardwareProvider.cs
@@ -1,4 +1,5 @@
-using Meadow.Foundation.ICs.IOExpanders;
+using Meadow.Devices.Clima.Hardware;
+using Meadow.Foundation.ICs.IOExpanders;
using Meadow.Hardware;
using Meadow.Logging;
using System;
@@ -8,16 +9,24 @@ namespace Meadow.Devices;
///
/// Represents the Clima hardware
///
-public class Clima
+public class ClimaHardwareProvider : IMeadowAppEmbeddedHardwareProvider
{
- private Clima() { }
+ public ClimaHardwareProvider()
+ {
+ }
+
+ public static IClimaHardware Create()
+ {
+ return new ClimaHardwareProvider()
+ .Create(Resolver.Services.Get()!);
+ }
///
/// Create an instance of the Clima class
///
///
///
- public static IClimaHardware Create()
+ public IClimaHardware Create(IMeadowDevice device)
{
IClimaHardware hardware;
Logger? logger = Resolver.Log;
@@ -25,9 +34,7 @@ public static IClimaHardware Create()
logger?.Debug("Initializing Clima...");
- var device = Resolver.Device;
-
- if (Resolver.Device == null)
+ if (device == null)
{
var msg = "Clima instance must be created no earlier than App.Initialize()";
logger?.Error(msg);
@@ -63,7 +70,9 @@ public static IClimaHardware Create()
logger?.Info("Failed to instantiate version MCP23008");
}
- if (version > 4)
+ logger?.Info($"MCP Version: {version}");
+
+ if (version >= 4)
{
logger?.Info("Instantiating Clima v4 specific hardware");
hardware = new ClimaHardwareV4(ccm, i2cBus, mcpVersion!);
diff --git a/Source/Meadow.Clima/Constants/CloudEventIds.cs b/Source/Meadow.Clima/Constants/CloudEventIds.cs
index 503bd56..a95893b 100644
--- a/Source/Meadow.Clima/Constants/CloudEventIds.cs
+++ b/Source/Meadow.Clima/Constants/CloudEventIds.cs
@@ -1,8 +1,8 @@
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Constants;
public enum CloudEventIds
{
DeviceStarted = 100,
Telemetry = 110,
BootFromCrash = 200
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/CloudController.cs b/Source/Meadow.Clima/Controllers/CloudController.cs
index 2c25e32..b99ca13 100644
--- a/Source/Meadow.Clima/Controllers/CloudController.cs
+++ b/Source/Meadow.Clima/Controllers/CloudController.cs
@@ -1,12 +1,25 @@
-using Meadow;
-using Meadow.Cloud;
+using Meadow.Cloud;
+using Meadow.Devices.Clima.Constants;
+using Meadow.Devices.Clima.Models;
using System;
using System.Linq;
+using System.Threading.Tasks;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Controllers;
public class CloudController
{
+ public async Task WaitForDataToSend()
+ {
+ // TODO: add a timeout here
+ while (Resolver.MeadowCloudService.QueueCount > 0)
+ {
+ // Resolver.Log.Info($"Waiting for {Resolver.MeadowCloudService.QueueCount} items to be delivered...");
+ await Task.Delay(1000);
+ }
+ Resolver.Log.Info($"All cloud data has been sent");
+ }
+
public void LogAppStartupAfterCrash()
{
SendEvent(CloudEventIds.DeviceStarted, $"Device restarted after crash");
@@ -17,6 +30,30 @@ public void LogAppStartup(string hardwareRevision)
SendEvent(CloudEventIds.DeviceStarted, $"Device started (hardware {hardwareRevision})");
}
+ public void LogDeviceInfo(string deviceName, double latitiude, double longitude)
+ {
+ // {
+ // "description": "Clima Boot Telemetry",
+ // "eventId": 109,
+ // "timestamp": "2024-05-20T22:25:15.862Z",
+ // "measurements": {
+ // "lat": 34.2277472,
+ // "long": -118.2273136
+ // }
+ // }
+ var cloudEvent = new CloudEvent
+ {
+ Description = "Clima Position Telemetry",
+ Timestamp = DateTime.UtcNow,
+ EventId = 109,
+ };
+
+ cloudEvent.Measurements.Add("device_name", deviceName);
+ cloudEvent.Measurements.Add("lat", latitiude);
+ cloudEvent.Measurements.Add("long", longitude);
+
+ SendEvent(cloudEvent);
+ }
public void LogWarning(string message)
{
SendLog(message, "warning");
@@ -105,4 +142,4 @@ private void SendEvent(CloudEvent cloudEvent)
Resolver.Log.Warn($"Failed to send cloud event: {ex.Message}");
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/LocationController.cs b/Source/Meadow.Clima/Controllers/LocationController.cs
index 63c7e35..c0ce90f 100644
--- a/Source/Meadow.Clima/Controllers/LocationController.cs
+++ b/Source/Meadow.Clima/Controllers/LocationController.cs
@@ -1,60 +1,38 @@
-using Meadow;
-using Meadow.Devices;
+using Meadow.Devices.Clima.Hardware;
using Meadow.Peripherals.Sensors.Location.Gnss;
+using System;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Controllers;
public class LocationController
{
+ private IGnssSensor gnss;
+
public bool LogData { get; set; } = false;
+ public event EventHandler PositionReceived;
+
public LocationController(IClimaHardware clima)
{
if (clima.Gnss is { } gnss)
{
- //gnss.GsaReceived += GnssGsaReceived;
- //gnss.GsvReceived += GnssGsvReceived;
- //gnss.VtgReceived += GnssVtgReceived;
- gnss.RmcReceived += GnssRmcReceived;
- gnss.GllReceived += GnssGllReceived;
- gnss.StartUpdating();
- }
-
- }
- private void GnssGsaReceived(object _, ActiveSatellites e)
- {
- if (e.SatellitesUsedForFix is { } sats)
- {
- Resolver.Log.Info($"Number of active satellites: {sats.Length}");
- }
- }
-
- private void GnssGsvReceived(object _, SatellitesInView e)
- {
- Resolver.Log.Info($"Satellites in view: {e.Satellites.Length}");
- }
-
- private void GnssVtgReceived(object _, CourseOverGround e)
- {
- if (e is { } cv)
- {
- Resolver.Log.Info($"{cv}");
- };
- }
-
- private void GnssRmcReceived(object _, GnssPositionInfo e)
- {
- if (e.Valid)
- {
- Resolver.Log.InfoIf(LogData, $"GNSS Position: lat: [{e.Position.Latitude}], long: [{e.Position.Longitude}]");
+ this.gnss = gnss;
+ this.gnss.GnssDataReceived += OnGnssDataReceived;
+ this.gnss.StartUpdating();
}
}
- private void GnssGllReceived(object _, GnssPositionInfo e)
+ private void OnGnssDataReceived(object sender, IGnssResult e)
{
- if (e.Valid)
+ if (e is GnssPositionInfo pi)
{
- Resolver.Log.InfoIf(LogData, $"GNSS Position: lat: [{e.Position.Latitude}], long: [{e.Position.Longitude}]");
+ if (pi.IsValid && pi.Position != null)
+ {
+ // we only need one position fix - weather stations don't move
+ Resolver.Log.InfoIf(LogData, $"GNSS Position: lat: [{pi.Position.Latitude}], long: [{pi.Position.Longitude}]");
+ PositionReceived?.Invoke(this, pi);
+ gnss.StopUpdating();
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/NetworkController.cs b/Source/Meadow.Clima/Controllers/NetworkController.cs
index 89616d2..44420af 100644
--- a/Source/Meadow.Clima/Controllers/NetworkController.cs
+++ b/Source/Meadow.Clima/Controllers/NetworkController.cs
@@ -1,8 +1,9 @@
using Meadow.Hardware;
using System;
using System.Threading;
+using System.Threading.Tasks;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Controllers;
public class NetworkController
{
@@ -19,6 +20,16 @@ public class NetworkController
public NetworkController(INetworkAdapter networkAdapter)
{
+ if (networkAdapter is IWiFiNetworkAdapter wifi)
+ {
+ if (wifi.IsConnected)
+ {
+ _ = ReportWiFiScan(wifi);
+ }
+
+ // TODO: make this configurable
+ wifi.SetAntenna(AntennaType.External);
+ }
this.networkAdapter = networkAdapter;
networkAdapter.NetworkConnected += OnNetworkConnected;
@@ -27,6 +38,39 @@ public NetworkController(INetworkAdapter networkAdapter)
downEventTimer = new Timer(DownEventTimerProc, null, -1, -1);
}
+ public async Task ConnectToCloud()
+ {
+ if (networkAdapter is IWiFiNetworkAdapter wifi)
+ {
+ if (!wifi.IsConnected)
+ {
+ Resolver.Log.Info("Connecting to network...");
+ await wifi.Connect("interwebs", "1234567890");
+ }
+ }
+
+ Resolver.Log.Info($"Connecting to network {(networkAdapter.IsConnected ? "succeeded" : "FAILED")}");
+
+ return networkAdapter.IsConnected;
+ }
+
+ public async Task ShutdownNetwork()
+ {
+ if (networkAdapter is IWiFiNetworkAdapter wifi)
+ {
+ Resolver.Log.Info("Disconnecting network...");
+ try
+ {
+ await wifi.Disconnect(true);
+ Resolver.Log.Info("Network disconnected");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Info($"Network disconnect failed: {ex.Message}");
+ }
+ }
+ }
+
private void DownEventTimerProc(object _)
{
if (networkAdapter.IsConnected)
@@ -46,9 +90,39 @@ private void OnNetworkDisconnected(INetworkAdapter sender, NetworkDisconnectionE
ConnectionStateChanged?.Invoke(this, false);
}
+ private async Task ReportWiFiScan(IWiFiNetworkAdapter wifi)
+ {
+ var networks = await wifi.Scan();
+
+ Resolver.Log.Info("WiFi Scan Results");
+ if (networks.Count == 0)
+ {
+ Resolver.Log.Info("No networks found");
+ }
+ else
+ {
+ foreach (var network in networks)
+ {
+ if (string.IsNullOrEmpty(network.Ssid))
+ {
+ Resolver.Log.Info($"[no ssid]: {network.SignalDbStrength}dB");
+ }
+ else
+ {
+ Resolver.Log.Info($"{network.Ssid}: {network.SignalDbStrength}dB");
+ }
+ }
+ }
+ }
+
private void OnNetworkConnected(INetworkAdapter sender, NetworkConnectionEventArgs args)
{
+ if (sender is IWiFiNetworkAdapter wifi)
+ {
+ _ = ReportWiFiScan(wifi);
+ }
+
lastDown = null;
ConnectionStateChanged?.Invoke(this, true);
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/NotificationController.cs b/Source/Meadow.Clima/Controllers/NotificationController.cs
index a958daa..810048d 100644
--- a/Source/Meadow.Clima/Controllers/NotificationController.cs
+++ b/Source/Meadow.Clima/Controllers/NotificationController.cs
@@ -1,7 +1,7 @@
using Meadow.Peripherals.Leds;
using System;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Controllers;
public class NotificationController
{
@@ -14,6 +14,17 @@ public enum Warnings
BatteryLow = 1 << 2,
}
+ public enum SystemStatus
+ {
+ LowPower,
+ Starting,
+ SearchingForNetwork,
+ NetworkConnected,
+ ConnectingToCloud,
+ Connected,
+
+ }
+
private readonly IRgbPwmLed? rgbLed;
private Warnings activeWarnings = Warnings.None;
@@ -22,14 +33,36 @@ public NotificationController(IRgbPwmLed? rgbLed)
this.rgbLed = rgbLed;
}
- public void SystemStarting()
+ public void SetSystemStatus(SystemStatus status)
{
- rgbLed?.SetColor(RgbLedColors.Red);
- }
+ switch (status)
+ {
+ case SystemStatus.LowPower:
+ if (rgbLed != null)
+ {
+ rgbLed.StopAnimation();
+ rgbLed.IsOn = false;
+ }
+ break;
+ case SystemStatus.Starting:
+ rgbLed?.SetColor(RgbLedColors.Red);
+ break;
+ case SystemStatus.SearchingForNetwork:
+ rgbLed?.StartBlink(RgbLedColors.Red);
+ break;
+ case SystemStatus.NetworkConnected:
+ rgbLed?.StopAnimation();
+ rgbLed?.SetColor(RgbLedColors.Magenta);
+ break;
+ case SystemStatus.ConnectingToCloud:
+ rgbLed?.StartBlink(RgbLedColors.Cyan);
+ break;
+ case SystemStatus.Connected:
+ rgbLed?.StopAnimation();
+ rgbLed?.SetColor(RgbLedColors.Green);
+ break;
- public void SystemUp()
- {
- ReportWarnings();
+ }
}
public void SetWarning(Warnings warning)
@@ -55,4 +88,4 @@ private void ReportWarnings()
rgbLed?.SetColor(RgbLedColors.Green);
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/PowerController.cs b/Source/Meadow.Clima/Controllers/PowerController.cs
index 04e7550..af690dc 100644
--- a/Source/Meadow.Clima/Controllers/PowerController.cs
+++ b/Source/Meadow.Clima/Controllers/PowerController.cs
@@ -1,10 +1,10 @@
-using Meadow;
-using Meadow.Devices;
+using Meadow.Devices.Clima.Hardware;
+using Meadow.Devices.Clima.Models;
using Meadow.Units;
using System;
using System.Threading.Tasks;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Controllers;
public class PowerController
{
@@ -54,6 +54,15 @@ public async Task GetPowerData()
};
}
+ public void TimedSleep(TimeSpan duration)
+ {
+ Resolver.Log.Info("Going to sleep...");
+
+ Resolver.Device.PlatformOS.Sleep(duration);
+
+ Resolver.Log.Info("PowerController completed sleep");
+ }
+
private void SolarVoltageUpdated(object sender, IChangeResult e)
{
Resolver.Log.InfoIf(LogPowerData, $"Solar Voltage: {e.New.Volts:0.#} volts");
@@ -111,4 +120,4 @@ private void BatteryVoltageUpdated(object sender, IChangeResult e)
}
}
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Controllers/SensorController.cs b/Source/Meadow.Clima/Controllers/SensorController.cs
index ecb1454..344f43f 100644
--- a/Source/Meadow.Clima/Controllers/SensorController.cs
+++ b/Source/Meadow.Clima/Controllers/SensorController.cs
@@ -1,56 +1,71 @@
-using Meadow;
-using Meadow.Devices;
+using Meadow.Devices.Clima.Hardware;
+using Meadow.Devices.Clima.Models;
using Meadow.Units;
using System;
using System.Threading.Tasks;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Controllers;
public class SensorController
{
private IClimaHardware hardware;
+ private CircularBuffer windVaneBuffer = new CircularBuffer(12);
+ private Length? startupRainValue;
+ private SensorData latestData;
- public bool LogSensorData { get; set; } = false;
+ private bool LogSensorData { get; set; } = false;
public TimeSpan UpdateInterval { get; } = TimeSpan.FromSeconds(5);
public SensorController(IClimaHardware clima)
{
+ latestData = new SensorData();
hardware = clima;
if (clima.TemperatureSensor is { } temperatureSensor)
{
temperatureSensor.Updated += TemperatureUpdated;
+ // atmospheric temp is slow to change
+ temperatureSensor.StartUpdating(TimeSpan.FromSeconds(15));
temperatureSensor.StartUpdating(UpdateInterval);
}
if (clima.BarometricPressureSensor is { } pressureSensor)
{
pressureSensor.Updated += PressureUpdated;
- pressureSensor.StartUpdating(UpdateInterval);
+ // barometric pressure is slow to change
+ pressureSensor.StartUpdating(TimeSpan.FromMinutes(1));
}
if (clima.HumiditySensor is { } humiditySensor)
{
humiditySensor.Updated += HumidityUpdated;
- humiditySensor.StartUpdating(UpdateInterval);
+ // humidity is slow to change
+ humiditySensor.StartUpdating(TimeSpan.FromMinutes(1));
}
if (clima.CO2ConcentrationSensor is { } co2Sensor)
{
co2Sensor.Updated += Co2Updated;
- co2Sensor.StartUpdating(UpdateInterval);
+ // CO2 levels are slow to change
+ co2Sensor.StartUpdating(TimeSpan.FromMinutes(5));
}
if (clima.WindVane is { } windVane)
{
windVane.Updated += WindvaneUpdated;
- windVane.StartUpdating(UpdateInterval);
+ windVane.StartUpdating(TimeSpan.FromSeconds(1));
}
if (clima.RainGauge is { } rainGuage)
{
- rainGuage.Updated += RainGuageUpdated;
- rainGuage.StartUpdating(UpdateInterval);
+ rainGuage.Updated += RainGaugeUpdated;
+
+ // TODO: if we're restarting, we need to rehydrate today's totals already collected
+ // startupRainValue = rainGuage.Read().Result;
+ // Resolver.Log.Info($"Startup rain value: {startupRainValue}");
+
+ // rain does not change frequently
+ rainGuage.StartUpdating(TimeSpan.FromMinutes(5));
}
if (clima.Anemometer is { } anemometer)
@@ -58,54 +73,104 @@ public SensorController(IClimaHardware clima)
anemometer.Updated += AnemometerUpdated;
anemometer.StartUpdating(UpdateInterval);
}
+
+ if (clima.LightSensor is { } lightSensor)
+ {
+ lightSensor.Updated += LightSensorUpdated;
+ lightSensor.StartUpdating(UpdateInterval);
+ }
+ }
+
+ public Task GetSensorData()
+ {
+ lock (latestData)
+ {
+ var data = latestData.Copy();
+
+ latestData.Clear();
+
+ return Task.FromResult(data);
+ }
}
- public async Task GetSensorData()
+ private void LightSensorUpdated(object sender, IChangeResult e)
{
- return new SensorData
- {
- Temperature = hardware.TemperatureSensor?.Temperature ?? null,
- Pressure = hardware.BarometricPressureSensor?.Pressure ?? null,
- Humidity = hardware.HumiditySensor?.Humidity ?? null,
- Co2Level = hardware.CO2ConcentrationSensor?.CO2Concentration ?? null,
- WindSpeed = hardware.Anemometer?.WindSpeed ?? null,
- WindDirection = hardware.WindVane?.WindAzimuth ?? null,
- Rain = hardware.RainGauge?.RainDepth ?? null,
- };
+ lock (latestData)
+ {
+ latestData.Light = e.New;
+ }
+
+ Resolver.Log.InfoIf(LogSensorData, $"Light: {e.New.Lux:0.#} lux");
}
private void TemperatureUpdated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.Temperature = e.New;
+ }
+
Resolver.Log.InfoIf(LogSensorData, $"Temperature: {e.New.Celsius:0.#}C");
}
private void PressureUpdated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.Pressure = e.New;
+ }
+
Resolver.Log.InfoIf(LogSensorData, $"Pressure: {e.New.Millibar:0.#}mbar");
}
private void HumidityUpdated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.Humidity = e.New;
+ }
+
Resolver.Log.InfoIf(LogSensorData, $"Humidity: {e.New.Percent:0.#}%");
}
private void Co2Updated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.Co2Level = e.New;
+ }
Resolver.Log.InfoIf(LogSensorData, $"CO2: {e.New.PartsPerMillion:0.#}ppm");
}
private void AnemometerUpdated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.WindSpeed = e.New;
+ }
+
Resolver.Log.InfoIf(LogSensorData, $"Anemometer: {e.New.MetersPerSecond:0.#} m/s");
}
- private void RainGuageUpdated(object sender, IChangeResult e)
+ private void RainGaugeUpdated(object sender, IChangeResult e)
{
+ lock (latestData)
+ {
+ latestData.Rain = e.New;
+ }
+
Resolver.Log.InfoIf(LogSensorData, $"Rain Gauge: {e.New.Millimeters:0.#} mm");
}
private void WindvaneUpdated(object sender, IChangeResult e)
{
- Resolver.Log.InfoIf(LogSensorData, $"Wind Vane: {e.New.Compass16PointCardinalName} ({e.New.Radians:0.#} radians)");
+ windVaneBuffer.Append(e.New);
+
+ lock (latestData)
+ {
+ latestData.WindDirection = windVaneBuffer.Mean();
+ }
+
+ Resolver.Log.InfoIf(LogSensorData, $"Wind Vane: {e.New.DecimalDegrees} (mean: {windVaneBuffer.Mean().DecimalDegrees})");
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Hardware/ClimaHardwareBase.cs b/Source/Meadow.Clima/Hardware/ClimaHardwareBase.cs
index 6105568..9b0ec80 100644
--- a/Source/Meadow.Clima/Hardware/ClimaHardwareBase.cs
+++ b/Source/Meadow.Clima/Hardware/ClimaHardwareBase.cs
@@ -6,10 +6,11 @@
using Meadow.Peripherals.Sensors;
using Meadow.Peripherals.Sensors.Atmospheric;
using Meadow.Peripherals.Sensors.Environmental;
+using Meadow.Peripherals.Sensors.Light;
using Meadow.Peripherals.Sensors.Weather;
using System;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Hardware;
///
/// Contains common elements of Clima hardware
@@ -63,6 +64,9 @@ public abstract class ClimaHardwareBase : IClimaHardware
///
public IAnemometer? Anemometer => GetAnemometer();
+ ///
+ public ILightSensor? LightSensor => GetLightSensor();
+
///
public IAnalogInputPort? SolarVoltageInput { get; protected set; }
@@ -83,6 +87,14 @@ public abstract class ClimaHardwareBase : IClimaHardware
///
public I2cConnector? Qwiic => (I2cConnector?)Connectors[0];
+ ///
+ public IMeadowDevice ComputeModule { get; }
+
+ internal ClimaHardwareBase(IMeadowDevice device)
+ {
+ ComputeModule = device;
+ }
+
internal virtual I2cConnector? CreateQwiicConnector()
{
return null;
@@ -155,6 +167,8 @@ public IConnector?[] Connectors
return _gasResistanceSensor;
}
+ protected virtual ILightSensor? GetLightSensor() => null;
+
///
/// Get the Wind Vane on the Clima board
///
diff --git a/Source/Meadow.Clima/Hardware/ClimaHardwareV2.cs b/Source/Meadow.Clima/Hardware/ClimaHardwareV2.cs
index 15f90af..5ba7437 100644
--- a/Source/Meadow.Clima/Hardware/ClimaHardwareV2.cs
+++ b/Source/Meadow.Clima/Hardware/ClimaHardwareV2.cs
@@ -6,7 +6,7 @@
using Meadow.Peripherals.Sensors.Weather;
using System;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Hardware;
///
/// Represents the Clima v2.x hardware
@@ -27,6 +27,7 @@ public class ClimaHardwareV2 : ClimaHardwareBase
/// The meadow device
/// The I2C bus
public ClimaHardwareV2(IF7FeatherMeadowDevice device, II2cBus i2cBus)
+ : base(device)
{
_device = device;
diff --git a/Source/Meadow.Clima/Hardware/ClimaHardwareV3.cs b/Source/Meadow.Clima/Hardware/ClimaHardwareV3.cs
index 7745ce2..a9c5b07 100644
--- a/Source/Meadow.Clima/Hardware/ClimaHardwareV3.cs
+++ b/Source/Meadow.Clima/Hardware/ClimaHardwareV3.cs
@@ -9,7 +9,7 @@
using Meadow.Peripherals.Sensors.Weather;
using System;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Hardware;
///
/// Represents the Clima v3.x hardware
@@ -64,6 +64,7 @@ public class ClimaHardwareV3 : ClimaHardwareBase
/// The I2C bus
/// The Mcp23008 used to read version information
public ClimaHardwareV3(IF7CoreComputeMeadowDevice device, II2cBus i2cBus, Mcp23008 mcpVersion)
+ : base(device)
{
McpVersion = mcpVersion;
diff --git a/Source/Meadow.Clima/Hardware/ClimaHardwareV4.cs b/Source/Meadow.Clima/Hardware/ClimaHardwareV4.cs
index a68165f..7018bbc 100644
--- a/Source/Meadow.Clima/Hardware/ClimaHardwareV4.cs
+++ b/Source/Meadow.Clima/Hardware/ClimaHardwareV4.cs
@@ -1,13 +1,20 @@
-using Meadow.Foundation.ICs.IOExpanders;
+using Meadow.Foundation;
+using Meadow.Foundation.ICs.IOExpanders;
+using Meadow.Foundation.Sensors.Light;
using Meadow.Hardware;
+using Meadow.Peripherals.Sensors.Light;
+using Meadow.Units;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Hardware;
///
/// Represents the Clima v4.x hardware
///
public class ClimaHardwareV4 : ClimaHardwareV3
{
+ private ILightSensor? _lightSensor;
+ private bool _firstLightQuery = true;
+
///
public override string RevisionString => "v4.x";
@@ -18,7 +25,7 @@ public class ClimaHardwareV4 : ClimaHardwareV3
/// The I2C bus
/// The Mcp23008 used to read version information
public ClimaHardwareV4(IF7CoreComputeMeadowDevice device, II2cBus i2cBus, Mcp23008 mcpVersion)
- : base(device, i2cBus, mcpVersion)
+ : base(device, i2cBus, mcpVersion)
{
}
@@ -27,12 +34,37 @@ public ClimaHardwareV4(IF7CoreComputeMeadowDevice device, II2cBus i2cBus, Mcp230
Logger?.Trace("Creating Qwiic I2C connector");
return new I2cConnector(
- nameof(Qwiic),
+ nameof(Qwiic),
new PinMapping
{
- new PinMapping.PinAlias(I2cConnector.PinNames.SCL, _device.Pins.I2C1_SCL),
- new PinMapping.PinAlias(I2cConnector.PinNames.SDA, _device.Pins.I2C1_SDA),
+ new PinMapping.PinAlias(I2cConnector.PinNames.SCL, _device.Pins.I2C1_SCL),
+ new PinMapping.PinAlias(I2cConnector.PinNames.SDA, _device.Pins.I2C1_SDA),
},
new I2cBusMapping(_device, 1));
}
+
+ protected override ILightSensor? GetLightSensor()
+ {
+ if (_lightSensor == null && _firstLightQuery)
+ {
+ try
+ {
+ Logger?.Trace("Creating Light sensor");
+ _lightSensor = new Veml7700(_device.CreateI2cBus());
+ if (_lightSensor is PollingSensorBase pollingSensor)
+ {
+ pollingSensor.CommunicationError += (s, e) => { _lightSensor.StopUpdating(); };
+ }
+ }
+ catch
+ {
+ Logger?.Warn("Light sensor not found on I2C bus");
+ _lightSensor = null;
+ }
+
+ _firstLightQuery = false;
+ }
+
+ return _lightSensor;
+ }
}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Hardware/IClimaHardware.cs b/Source/Meadow.Clima/Hardware/IClimaHardware.cs
index 2d9d42c..7f2c22c 100644
--- a/Source/Meadow.Clima/Hardware/IClimaHardware.cs
+++ b/Source/Meadow.Clima/Hardware/IClimaHardware.cs
@@ -4,20 +4,25 @@
using Meadow.Peripherals.Sensors;
using Meadow.Peripherals.Sensors.Atmospheric;
using Meadow.Peripherals.Sensors.Environmental;
+using Meadow.Peripherals.Sensors.Light;
using Meadow.Peripherals.Sensors.Weather;
-namespace Meadow.Devices;
+namespace Meadow.Devices.Clima.Hardware;
///
/// Contract for the Clima hardware definitions
///
-public interface IClimaHardware
+public interface IClimaHardware : IMeadowAppEmbeddedHardware
{
///
/// The I2C Bus
///
public II2cBus I2cBus { get; }
+ public ILightSensor? LightSensor { get; }
+
+ public IMeadowDevice ComputeModule { get; }
+
///
/// Gets the ITemperatureSensor on the Clima board
///
diff --git a/Source/Meadow.Clima/MainController.cs b/Source/Meadow.Clima/MainController.cs
index a8dc7ab..96f9432 100644
--- a/Source/Meadow.Clima/MainController.cs
+++ b/Source/Meadow.Clima/MainController.cs
@@ -1,9 +1,11 @@
-using Clima_Demo;
+using Meadow.Devices.Clima.Controllers;
+using Meadow.Devices.Clima.Hardware;
using Meadow.Hardware;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using static Meadow.Devices.Clima.Controllers.NotificationController;
namespace Meadow.Devices;
@@ -16,7 +18,11 @@ public class MainController
private LocationController locationController;
private NetworkController? networkController;
private CloudController cloudController;
- private Timer TelemetryTimer;
+ private int tick;
+ private const int SensorReadPeriodSeconds = 10;
+ private const int PublicationPeriodMinutes = 1;
+ private bool lowPowerMode = false;
+ private Timer sleepSimulationTimer;
public TimeSpan TelemetryPublicationPeriod { get; } = TimeSpan.FromMinutes(1);
@@ -29,11 +35,10 @@ public Task Initialize(IClimaHardware hardware, INetworkAdapter? networkAdapter)
notificationController = new NotificationController(hardware.RgbLed);
Resolver.Services.Add(notificationController);
- notificationController.SystemStarting();
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.Starting);
cloudController = new CloudController();
- Resolver.Services.Get()?.LogAppStartup(hardware.RevisionString);
Resolver.Log.Info($"Running on Clima Hardware {hardware.RevisionString}");
sensorController = new SensorController(hardware);
@@ -44,6 +49,8 @@ public Task Initialize(IClimaHardware hardware, INetworkAdapter? networkAdapter)
locationController = new LocationController(hardware);
+ locationController.PositionReceived += OnPositionReceived;
+
if (networkAdapter == null)
{
Resolver.Log.Error("No network adapter found!");
@@ -56,25 +63,129 @@ public Task Initialize(IClimaHardware hardware, INetworkAdapter? networkAdapter)
if (!networkController.IsConnected)
{
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.SearchingForNetwork);
Resolver.Log.Info("Network is down");
- notificationController.SetWarning(NotificationController.Warnings.NetworkDisconnected);
+ }
+ else
+ {
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.NetworkConnected);
+ if (Resolver.MeadowCloudService.ConnectionState == CloudConnectionState.Connecting)
+ {
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.ConnectingToCloud);
+ }
}
}
- notificationController.SystemUp();
+ Resolver.MeadowCloudService.ConnectionStateChanged += OnMeadowCloudServiceConnectionStateChanged;
cloudController.LogAppStartup(hardware.RevisionString);
- TelemetryTimer = new Timer(TelemetryTimerProc, null, 0, -1);
+ Resolver.Device.PlatformOS.AfterWake += PlatformOS_AfterWake;
+
+ if (!lowPowerMode)
+ {
+ sleepSimulationTimer = new Timer((_) => PlatformOS_AfterWake(null, WakeSource.Unknown), null, -1, -1);
+ }
+
+ _ = SystemPreSleepStateProc();
return Task.CompletedTask;
}
- private async void TelemetryTimerProc(object _)
+ private void OnPositionReceived(object sender, Peripherals.Sensors.Location.Gnss.GnssPositionInfo e)
+ {
+ if (e.Position != null)
+ {
+ // crop to 2 decimal places (~1km accuracy) for privacy
+ var lat = Math.Round(e.Position.Latitude, 2);
+ var lon = Math.Round(e.Position.Longitude, 2);
+
+ cloudController.LogDeviceInfo(Resolver.Device.Information.DeviceName, lat, lon);
+ }
+ }
+
+ private void PlatformOS_AfterWake(object sender, WakeSource e)
{
+ Resolver.Log.Info("PlatformOS_AfterWake");
+ SystemPostWakeStateProc();
+ }
+
+ private async Task SystemPreSleepStateProc()
+ {
+ await CollectTelemetry();
+
+ // connect to cloud
+ if (networkController != null)
+ {
+ notificationController.SetSystemStatus(SystemStatus.SearchingForNetwork);
+ var connected = await networkController.ConnectToCloud();
+ if (connected)
+ {
+ if (cloudController != null)
+ {
+ await cloudController.WaitForDataToSend();
+ }
+
+ if (lowPowerMode)
+ {
+ await networkController.ShutdownNetwork();
+ }
+ }
+ }
+
+ notificationController.SetSystemStatus(SystemStatus.LowPower);
+ if (lowPowerMode)
+ {
+ powerController.TimedSleep(TimeSpan.FromSeconds(SensorReadPeriodSeconds));
+ }
+ else
+ {
+ Resolver.Log.Info("Simulating sleep");
+ sleepSimulationTimer.Change(TimeSpan.FromSeconds(SensorReadPeriodSeconds), TimeSpan.FromMilliseconds(-1));
+ }
+ }
+
+ private void SystemPostWakeStateProc()
+ {
+ // collect data
+
+ if (++tick % PublicationPeriodMinutes * 60 / SensorReadPeriodSeconds == 0)
+ {
+ _ = SystemPreSleepStateProc();
+ }
+ else
+ {
+ if (lowPowerMode)
+ {
+ powerController.TimedSleep(TimeSpan.FromSeconds(SensorReadPeriodSeconds));
+ }
+ else
+ {
+ sleepSimulationTimer.Change(TimeSpan.FromSeconds(SensorReadPeriodSeconds), TimeSpan.FromMilliseconds(-1));
+ }
+ }
+ }
+
+ private void OnMeadowCloudServiceConnectionStateChanged(object sender, CloudConnectionState e)
+ {
+ switch (e)
+ {
+ case CloudConnectionState.Connected:
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.Connected);
+ break;
+ default:
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.ConnectingToCloud);
+ break;
+ }
+ }
+
+ private async Task CollectTelemetry()
+ {
+ // collect telemetry every tick
Resolver.Log.Info($"Collecting telemetry");
try
{
+ // publish telemetry to the cloud every N ticks
cloudController.LogTelemetry(
await sensorController.GetSensorData(),
await powerController.GetPowerData());
@@ -83,8 +194,6 @@ await sensorController.GetSensorData(),
{
Resolver.Log.Warn($"Failed to log telemetry: {ex.Message}");
}
-
- TelemetryTimer.Change(TelemetryPublicationPeriod, TimeSpan.FromMilliseconds(-1));
}
private void OnNetworkStillDown(object sender, System.TimeSpan e)
@@ -92,6 +201,11 @@ private void OnNetworkStillDown(object sender, System.TimeSpan e)
Resolver.Log.Info($"Network has been down for {e.TotalSeconds:N0} seconds");
// TODO: after some period, should we force-restart the device?
+ if (e.TotalMinutes > 5)
+ {
+ Resolver.Log.Info($"Network Connection timeout. Resetting the device.");
+ Resolver.Device.PlatformOS.Reset();
+ }
}
private void OnNetworkConnectionStateChanged(object sender, bool e)
@@ -100,6 +214,7 @@ private void OnNetworkConnectionStateChanged(object sender, bool e)
{
Resolver.Log.Info($"Network connected");
notificationController.ClearWarning(NotificationController.Warnings.NetworkDisconnected);
+ notificationController.SetSystemStatus(NotificationController.SystemStatus.NetworkConnected);
}
else
{
@@ -115,7 +230,7 @@ private void OnBatteryVoltageWarning(object sender, bool e)
var message = $"Battery voltage dropped below {powerController.LowBatteryWarningLevel.Volts:N1}";
Resolver.Log.Warn(message);
- notificationController.SetWarning(NotificationController.Warnings.BatteryLow);
+ //notificationController.SetWarning(NotificationController.Warnings.BatteryLow);
cloudController.LogWarning(message);
}
else
@@ -135,7 +250,7 @@ private void OnSolarVoltageWarning(object sender, bool e)
var message = $"Solar voltage dropped below {powerController.LowSolarWarningLevel.Volts:N1}";
Resolver.Log.Warn(message);
- notificationController.SetWarning(NotificationController.Warnings.SolarLoadLow);
+ //notificationController.SetWarning(NotificationController.Warnings.SolarLoadLow);
cloudController.LogWarning(message);
}
else
diff --git a/Source/Meadow.Clima/Meadow.Clima.csproj b/Source/Meadow.Clima/Meadow.Clima.csproj
index 6ade144..2a496ec 100644
--- a/Source/Meadow.Clima/Meadow.Clima.csproj
+++ b/Source/Meadow.Clima/Meadow.Clima.csproj
@@ -22,13 +22,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Source/Meadow.Clima/Models/PowerData.cs b/Source/Meadow.Clima/Models/PowerData.cs
index 2eca7b0..9c769a2 100644
--- a/Source/Meadow.Clima/Models/PowerData.cs
+++ b/Source/Meadow.Clima/Models/PowerData.cs
@@ -1,13 +1,27 @@
using Meadow.Units;
using System.Collections.Generic;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Models;
+///
+/// Represents power data including solar voltage and battery voltage.
+///
public record PowerData
{
+ ///
+ /// Gets or sets the solar voltage.
+ ///
public Voltage? SolarVoltage { get; set; }
+
+ ///
+ /// Gets or sets the battery voltage.
+ ///
public Voltage? BatteryVoltage { get; set; }
+ ///
+ /// Converts the power data to a telemetry dictionary.
+ ///
+ /// The telemetry dictionary.
public Dictionary AsTelemetryDictionary()
{
var d = new Dictionary();
@@ -22,4 +36,4 @@ public Dictionary AsTelemetryDictionary()
return d;
}
-}
+}
\ No newline at end of file
diff --git a/Source/Meadow.Clima/Models/SensorData.cs b/Source/Meadow.Clima/Models/SensorData.cs
index 03c36dd..e67eec1 100644
--- a/Source/Meadow.Clima/Models/SensorData.cs
+++ b/Source/Meadow.Clima/Models/SensorData.cs
@@ -1,18 +1,89 @@
using Meadow.Units;
using System.Collections.Generic;
-namespace Clima_Demo;
+namespace Meadow.Devices.Clima.Models;
-public record SensorData
+///
+/// Represents the clima sensor data
+///
+public class SensorData
{
+ ///
+ /// Gets or sets the temperature.
+ ///
public Temperature? Temperature { get; set; }
+
+ ///
+ /// Gets or sets the pressure.
+ ///
public Pressure? Pressure { get; set; }
+
+ ///
+ /// Gets or sets the relative humidity.
+ ///
public RelativeHumidity? Humidity { get; set; }
+
+ ///
+ /// Gets or sets the CO2 level.
+ ///
public Concentration? Co2Level { get; set; }
+
+ ///
+ /// Gets or sets the wind speed.
+ ///
public Speed? WindSpeed { get; set; }
+
+ ///
+ /// Gets or sets the wind direction.
+ ///
public Azimuth? WindDirection { get; set; }
+
+ ///
+ /// Gets or sets the rain length.
+ ///
public Length? Rain { get; set; }
+ ///
+ /// Gets or sets the illuminance.
+ ///
+ public Illuminance? Light { get; set; }
+
+ ///
+ /// Clears all the sensor data.
+ ///
+ public void Clear()
+ {
+ Co2Level = null;
+ Temperature = null;
+ Pressure = null;
+ WindSpeed = null;
+ WindDirection = null;
+ Rain = null;
+ Light = null;
+ }
+
+ ///
+ /// Creates a copy of the SensorData object.
+ ///
+ public SensorData Copy()
+ {
+ return new SensorData
+ {
+ Co2Level = Co2Level,
+ Temperature = Temperature,
+ Pressure = Pressure,
+ WindSpeed = WindSpeed,
+ WindDirection = WindDirection,
+ Rain = Rain,
+ Light = Light,
+ };
+ }
+
+
+ ///
+ /// Converts the SensorData object to a dictionary suitable for telemetry.
+ ///
+ /// A dictionary containing the telemetry data.
public Dictionary AsTelemetryDictionary()
{
var d = new Dictionary();
@@ -44,7 +115,11 @@ public Dictionary AsTelemetryDictionary()
{
d.Add(nameof(Rain), Rain.Value.Centimeters);
}
+ if (Light != null)
+ {
+ d.Add(nameof(Light), Light.Value.Lux);
+ }
return d;
}
-}
+}
\ No newline at end of file