diff --git a/Source/Additional Samples/Clima_Simulation/Clima_Simulation.csproj b/Source/Additional Samples/Clima_Simulation/Clima_Simulation.csproj
new file mode 100644
index 0000000..8bb8329
--- /dev/null
+++ b/Source/Additional Samples/Clima_Simulation/Clima_Simulation.csproj
@@ -0,0 +1,24 @@
+
+
+ netstandard2.1
+ true
+ Library
+ App
+ 10.0
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Simulation/MeadowApp.cs b/Source/Additional Samples/Clima_Simulation/MeadowApp.cs
new file mode 100644
index 0000000..e78ebd6
--- /dev/null
+++ b/Source/Additional Samples/Clima_Simulation/MeadowApp.cs
@@ -0,0 +1,48 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Logging;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Clima_Simulation;
+// Change F7FeatherV2 to F7FeatherV1 if using Feather V1 Meadow boards
+// Change to F7CoreComputeV2 for Project Lab V3.x
+public class MeadowApp : App
+{
+ public override async Task Initialize()
+ {
+ Resolver.Log.Info($"Initializing...");
+
+ var cloudLogger = new CloudLogger();
+ Resolver.Log.AddProvider(cloudLogger);
+ Resolver.Services.Add(cloudLogger);
+
+ var count = 1;
+ var r = new Random();
+
+ while (true)
+ {
+ // send a cloud log
+ Resolver.Log.Info($"log loop {count++}");
+
+ // send a cloud event
+ var cl = Resolver.Services.Get();
+ cl.LogEvent(100, "clima conditions", new Dictionary()
+ {
+ { "Temperature", r.Next(20, 25) },
+ { "Rain", r.Next(0, 5) },
+ { "Light", r.Next(1000, 2000) },
+ { "SolarVoltage", r.Next(3, 5) },
+ { "Humidity", r.Next(80, 110) },
+ { "WindSpeed", r.Next(10, 15) },
+ { "WindDirection", r.Next(0, 360) },
+ { "Pressure", r.Next(1, 5) },
+ { "Co2Level", r.Next(750, 1000) },
+ { "BatteryVoltage", r.Next(3,5) },
+ });
+
+ await Task.Delay(60 * 1000);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Simulation/app.config.yaml b/Source/Additional Samples/Clima_Simulation/app.config.yaml
new file mode 100644
index 0000000..298abcf
--- /dev/null
+++ b/Source/Additional Samples/Clima_Simulation/app.config.yaml
@@ -0,0 +1,36 @@
+# Uncomment additional options as needed.
+# To learn more about these config options, including custom application configuration settings, check out the Application Settings Configuration documentation.
+# http://developer.wildernesslabs.co/Meadow/Meadow.OS/Configuration/Application_Settings_Configuration/
+
+# App lifecycle configuration.
+Lifecycle:
+
+ # Control whether Meadow will restart when an unhandled app exception occurs. Combine with Lifecycle > AppFailureRestartDelaySeconds to control restart timing.
+ RestartOnAppFailure: false
+
+ # When app set to restart automatically on app failure,
+# AppFailureRestartDelaySeconds: 15
+
+# Logging configuration.
+Logging:
+
+ # Adjust the level of logging detail.
+ LogLevel:
+
+ # Trace, Debug, Information, Warning, or Error
+ Default: Trace
+
+# Meadow.Cloud configuration.
+MeadowCloud:
+
+ # Enable Logging, Events, Command + Control
+ Enabled: true
+
+ # Enable Over-the-air Updates
+# EnableUpdates: false
+
+ # Enable Health Metrics
+# EnableHealthMetrics: false
+
+ # How often to send metrics to Meadow.Cloud
+# HealthMetricsIntervalMinutes: 60
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_Simulation/meadow.config.yaml b/Source/Additional Samples/Clima_Simulation/meadow.config.yaml
new file mode 100644
index 0000000..4697716
--- /dev/null
+++ b/Source/Additional Samples/Clima_Simulation/meadow.config.yaml
@@ -0,0 +1,54 @@
+# 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: MeadowDevice
+
+ # 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
+
+ # Maximum number of retry attempts for connections etc. before an error code is returned.
+ MaximumRetryCount: 7
+
+# Network configuration.
+Network:
+
+ # Network Interface (Default value is WiFi with DHCP)
+ Interfaces:
+ - Name: WiFi
+ UseDHCP: true
+
+ # Default Interface
+ DefaultInterface: Wifi
+
+ # Automatically attempt to get the time at startup?
+ GetNetworkTimeAtStartup: true
+
+ # 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/Additional Samples/Clima_Simulation/wifi.config.yaml b/Source/Additional Samples/Clima_Simulation/wifi.config.yaml
new file mode 100644
index 0000000..53a227c
--- /dev/null
+++ b/Source/Additional Samples/Clima_Simulation/wifi.config.yaml
@@ -0,0 +1,12 @@
+# Uncomment to set the default Wi-Fi credentials. (This file will be processed into secure storage on the ESP32 and then deleted from the device.)
+# To learn more about these config options, including custom application configuration settings, check out the Application Settings Configuration documentation.
+# http://developer.wildernesslabs.co/Meadow/Meadow.OS/Configuration/WiFi_Configuration/
+
+# WiFi network credentials
+Credentials:
+
+ # WiFi SSID
+ Ssid: YourSSID
+
+ # WiFi Password
+ Password: SSIDPassword
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_reTerminal/App.axaml b/Source/Additional Samples/Clima_reTerminal/App.axaml
new file mode 100644
index 0000000..e6f9f66
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/App.axaml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_reTerminal/App.axaml.cs b/Source/Additional Samples/Clima_reTerminal/App.axaml.cs
new file mode 100644
index 0000000..33e8463
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/App.axaml.cs
@@ -0,0 +1,36 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using Clima_reTerminal.ViewModels;
+using Clima_reTerminal.Views;
+
+namespace Clima_reTerminal
+{
+ public partial class App : Application
+ {
+ public App()
+ {
+ RegisterServices();
+ }
+
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ base.Initialize();
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow = new MainWindow
+ {
+ DataContext = new MainWindowViewModel(),
+ //WindowState = Avalonia.Controls.WindowState.FullScreen
+ };
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/avalonia-logo.ico b/Source/Additional Samples/Clima_reTerminal/Assets/avalonia-logo.ico
new file mode 100644
index 0000000..56a68b9
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/avalonia-logo.ico differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-battery.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-battery.png
new file mode 100644
index 0000000..7b196d1
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-battery.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-compass.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-compass.png
new file mode 100644
index 0000000..530cb68
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-compass.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-humidity.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-humidity.png
new file mode 100644
index 0000000..e7abf46
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-humidity.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-light.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-light.png
new file mode 100644
index 0000000..7a0959f
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-light.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-pressure.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-pressure.png
new file mode 100644
index 0000000..aee2188
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-pressure.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-rain.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-rain.png
new file mode 100644
index 0000000..18e1059
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-rain.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-solar.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-solar.png
new file mode 100644
index 0000000..47cf8e0
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-solar.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-speed.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-speed.png
new file mode 100644
index 0000000..822aa87
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-speed.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-temp.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-temp.png
new file mode 100644
index 0000000..4990fff
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-temp.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-voltage.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-voltage.png
new file mode 100644
index 0000000..5df0002
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-voltage.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Assets/icon-wind.png b/Source/Additional Samples/Clima_reTerminal/Assets/icon-wind.png
new file mode 100644
index 0000000..9cf7ddc
Binary files /dev/null and b/Source/Additional Samples/Clima_reTerminal/Assets/icon-wind.png differ
diff --git a/Source/Additional Samples/Clima_reTerminal/Client/RestClient.cs b/Source/Additional Samples/Clima_reTerminal/Client/RestClient.cs
new file mode 100644
index 0000000..4d7266b
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/Client/RestClient.cs
@@ -0,0 +1,105 @@
+using Clima_reTerminal.Models;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace Clima_reTerminal.Client
+{
+ public static class RestClient
+ {
+ static RestClient() { }
+
+ public static async Task> GetSensorReadings()
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ try
+ {
+ client.DefaultRequestHeaders.Add("Authorization", $"apikey {Secrets.API_KEY}");
+ client.Timeout = new TimeSpan(0, 5, 0);
+
+ var response = await client.GetAsync($"" +
+ $"{Secrets.MEADOW_CLOUD_URL}/api/orgs/{Secrets.ORGANIZATION_ID}/search/source:event " +
+ $"deviceId:{Secrets.DEVICE_ID} eventId:100 size:20 sortby:timestamp sortorder:desc");
+
+ if (response.IsSuccessStatusCode)
+ {
+ string jsonString = await response.Content.ReadAsStringAsync();
+ Console.WriteLine("Response Content: " + jsonString);
+
+ var root = JsonSerializer.Deserialize(jsonString);
+
+ return root?.data?.queryResponses;
+ }
+ else
+ {
+ Console.WriteLine("Error: " + response.StatusCode);
+ return new List();
+ }
+ }
+ catch (TaskCanceledException)
+ {
+ Console.WriteLine("Request timed out.");
+ return new List();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Request went sideways: {e.Message}");
+ return new List();
+ }
+ }
+ }
+
+ public static async Task SendCommand(CultivarCommands command, bool relayState)
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ try
+ {
+ client.DefaultRequestHeaders.Add("Authorization", $"apikey {Secrets.API_KEY}");
+ client.Timeout = new TimeSpan(0, 5, 0);
+
+ string jsonString = $"" +
+ $"{{" +
+ $"\"deviceIds\": [" +
+ $"\"{Secrets.DEVICE_ID}\"]," +
+ $"\"commandName\": \"{command}\"," +
+ $"\"args\": {{ " +
+ $"\"relaystate\": {relayState}" +
+ $"}}," +
+ $"\"qos\": 0" +
+ $"}}";
+
+ var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
+
+ HttpResponseMessage response = await client.PostAsync($"{Secrets.MEADOW_CLOUD_URL}/api/devices/commands", content);
+
+ if (response.IsSuccessStatusCode)
+ {
+ string responseContent = await response.Content.ReadAsStringAsync();
+ Console.WriteLine("Response Content: " + responseContent);
+ }
+ else
+ {
+ Console.WriteLine("Error: " + response.StatusCode);
+ }
+
+ return true;
+ }
+ catch (TaskCanceledException)
+ {
+ Console.WriteLine("Request timed out.");
+ return false;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Request went sideways: {e.Message}");
+ return false;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.csproj b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.csproj
new file mode 100644
index 0000000..b2eb059
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.csproj
@@ -0,0 +1,37 @@
+
+
+ WinExe
+ net7.0
+ enable
+ true
+ app.manifest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.sln b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.sln
new file mode 100644
index 0000000..0887efa
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminal.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34031.279
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clima_reTerminal", "Clima_reTerminal.csproj", "{EFE6C4EC-9620-4AEC-A25F-459FFE87B37B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EFE6C4EC-9620-4AEC-A25F-459FFE87B37B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EFE6C4EC-9620-4AEC-A25F-459FFE87B37B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EFE6C4EC-9620-4AEC-A25F-459FFE87B37B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EFE6C4EC-9620-4AEC-A25F-459FFE87B37B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {79579EBC-F281-403F-8BA5-9A805204DC1C}
+ EndGlobalSection
+EndGlobal
diff --git a/Source/Additional Samples/Clima_reTerminal/Clima_reTerminalApplication.cs b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminalApplication.cs
new file mode 100644
index 0000000..628e102
--- /dev/null
+++ b/Source/Additional Samples/Clima_reTerminal/Clima_reTerminalApplication.cs
@@ -0,0 +1,56 @@
+using Avalonia;
+using Avalonia.Threading;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Clima_reTerminal
+{
+ public class Clima_reTerminalApplication : Application
+ where T : class
+ {
+ public CancellationToken CancellationToken => throw new NotImplementedException();
+
+ public Dictionary Settings => new Dictionary();
+
+ protected Clima_reTerminalApplication()
+ {
+ }
+
+ public void InvokeOnMainThread(Action