Skip to content

Commit

Permalink
Merge pull request #83 from WildernessLabs/feature/device-info
Browse files Browse the repository at this point in the history
record device name and position when position data arrives
  • Loading branch information
ctacke authored Jun 28, 2024
2 parents 4da9e23 + 6152bb1 commit 2b72395
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Clima_Demo/Clima_Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
<ProjectReference Include="..\Meadow.Clima\Meadow.Clima.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="app.build.yaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="meadow.config.yaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
82 changes: 77 additions & 5 deletions Source/Clima_Demo/MeadowApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

namespace Clima_Demo;

public class MeadowApp : App<F7CoreComputeV2>
public class ClimaApp : ClimaAppBase
{
private MainController mainController;

public MeadowApp()
public ClimaApp()
{
mainController = new MainController();
}

public override Task Initialize()
{
Resolver.Log.Trace($"!! Initializing");

var reliabilityService = Resolver.Services.Get<IReliabilityService>();
reliabilityService!.MeadowSystemError += OnMeadowSystemError;
if (reliabilityService.LastBootWasFromCrash)
Expand All @@ -25,8 +27,8 @@ public override Task Initialize()
reliabilityService.ClearCrashData();
}

var wifi = Device.NetworkAdapters.Primary<IWiFiNetworkAdapter>();
mainController.Initialize(Clima.Create(), wifi);
var wifi = Hardware.ComputeModule.NetworkAdapters.Primary<IWiFiNetworkAdapter>();
mainController.Initialize(Hardware, wifi);

return Task.CompletedTask;
}
Expand Down Expand Up @@ -74,4 +76,74 @@ private void OnMeadowSystemError(object sender, MeadowSystemErrorInfo e)
}
}
}
}
}

//public class MeadowApp : App<F7CoreComputeV2>
//{
// private MainController mainController;

// public MeadowApp()
// {
// mainController = new MainController();
// }

// public override Task Initialize()
// {
// var reliabilityService = Resolver.Services.Get<IReliabilityService>();
// reliabilityService!.MeadowSystemError += OnMeadowSystemError;
// if (reliabilityService.LastBootWasFromCrash)
// {
// mainController.LogAppStartupAfterCrash(reliabilityService.GetCrashData());
// reliabilityService.ClearCrashData();
// }

// var wifi = Device.NetworkAdapters.Primary<IWiFiNetworkAdapter>();
// mainController.Initialize(new Clima().Create() as IClimaHardware, wifi);

// return Task.CompletedTask;
// }

// private void OnMeadowSystemError(MeadowSystemErrorInfo error, bool recommendReset, out bool forceReset)
// {
// 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;
// }

// private void OnMeadowSystemError(object sender, MeadowSystemErrorInfo e)
// {
// Resolver.Log.Error($"App has detected a system error: {e.Message}");
// 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}");
// }
// }
// }
//}
2 changes: 2 additions & 0 deletions Source/Clima_Demo/app.build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deploy:
NoLink: [ Clima ]
2 changes: 1 addition & 1 deletion Source/Clima_Demo/app.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

Expand Down
5 changes: 5 additions & 0 deletions Source/Meadow.Clima/ClimaAppBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Meadow.Devices;

public abstract class ClimaAppBase : App<F7CoreComputeV2, ClimaHardwareProvider, IClimaHardware>
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,32 @@ namespace Meadow.Devices;
/// <summary>
/// Represents the Clima hardware
/// </summary>
public class Clima
public class ClimaHardwareProvider : IMeadowAppEmbeddedHardwareProvider<IClimaHardware>
{
private Clima() { }
public ClimaHardwareProvider()
{
}

public static IClimaHardware Create()
{
return new ClimaHardwareProvider()
.Create(Resolver.Services.Get<IMeadowDevice>()!);
}

/// <summary>
/// Create an instance of the Clima class
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IClimaHardware Create()
public IClimaHardware Create(IMeadowDevice device)
{
IClimaHardware hardware;
Logger? logger = Resolver.Log;
II2cBus i2cBus;

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);
Expand Down
22 changes: 22 additions & 0 deletions Source/Meadow.Clima/Controllers/CloudController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ 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);
}
public void LogWarning(string message)
{
SendLog(message, "warning");
Expand Down
55 changes: 17 additions & 38 deletions Source/Meadow.Clima/Controllers/LocationController.cs
Original file line number Diff line number Diff line change
@@ -1,60 +1,39 @@
using Meadow;
using Meadow.Devices;
using Meadow.Peripherals.Sensors.Location.Gnss;
using System;

namespace Clima_Demo;

public class LocationController
{
private IGnssSensor gnss;

public bool LogData { get; set; } = false;

public event EventHandler<GnssPositionInfo> 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.Position is not null)
{
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.Position is not null)
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();
}
}
}
}
8 changes: 8 additions & 0 deletions Source/Meadow.Clima/Hardware/ClimaHardwareBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ public abstract class ClimaHardwareBase : IClimaHardware
/// <inheritdoc/>
public I2cConnector? Qwiic => (I2cConnector?)Connectors[0];

/// <inheritdoc/>
public IMeadowDevice ComputeModule { get; }

internal ClimaHardwareBase(IMeadowDevice device)
{
ComputeModule = device;
}

internal virtual I2cConnector? CreateQwiicConnector()
{
return null;
Expand Down
3 changes: 2 additions & 1 deletion Source/Meadow.Clima/Hardware/ClimaHardwareV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ public class ClimaHardwareV2 : ClimaHardwareBase
/// <param name="device">The meadow device</param>
/// <param name="i2cBus">The I2C bus</param>
public ClimaHardwareV2(IF7FeatherMeadowDevice device, II2cBus i2cBus)
: base(device)
{
_device = device;

I2cBus = i2cBus;

// See hack in Meadow.Core\Source\implementations\f7\Meadow.F7\Devices\DeviceChannelManager.cs
// See hack in Meadow.Core\source\implementations\f7\Meadow.F7\Devices\DeviceChannelManager.cs
// Must initialise any PWM based I/O first
GetRgbPwmLed();

Expand Down
3 changes: 2 additions & 1 deletion Source/Meadow.Clima/Hardware/ClimaHardwareV3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,15 @@ public class ClimaHardwareV3 : ClimaHardwareBase
/// <param name="i2cBus">The I2C bus</param>
/// <param name="mcpVersion">The Mcp23008 used to read version information</param>
public ClimaHardwareV3(IF7CoreComputeMeadowDevice device, II2cBus i2cBus, Mcp23008 mcpVersion)
: base(device)
{
McpVersion = mcpVersion;

_device = device;

I2cBus = i2cBus;

// See hack in Meadow.Core\Source\implementations\f7\Meadow.F7\Devices\DeviceChannelManager.cs
// See hack in Meadow.Core\source\implementations\f7\Meadow.F7\Devices\DeviceChannelManager.cs
// Must initialise any PWM based I/O first
GetRgbPwmLed();

Expand Down
13 changes: 10 additions & 3 deletions Source/Meadow.Clima/Hardware/ClimaHardwareV4.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
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;

Expand Down Expand Up @@ -49,14 +51,19 @@ public ClimaHardwareV4(IF7CoreComputeMeadowDevice device, II2cBus i2cBus, Mcp230
{
Logger?.Trace("Creating Light sensor");
_lightSensor = new Veml7700(_device.CreateI2cBus());
if (_lightSensor is PollingSensorBase<Illuminance> pollingSensor)
{
pollingSensor.CommunicationError += (s, e) => { _lightSensor.StopUpdating(); };
}
}
catch
{
Logger?.Warn("Light sensor not found on I2C bus");
_lightSensor = null;
}
}

_firstLightQuery = false;
_firstLightQuery = false;
}

return _lightSensor;
}
Expand Down
4 changes: 3 additions & 1 deletion Source/Meadow.Clima/Hardware/IClimaHardware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Meadow.Devices;
/// <summary>
/// Contract for the Clima hardware definitions
/// </summary>
public interface IClimaHardware
public interface IClimaHardware : IMeadowAppEmbeddedHardware
{
/// <summary>
/// The I2C Bus
Expand All @@ -21,6 +21,8 @@ public interface IClimaHardware

public ILightSensor? LightSensor { get; }

public IMeadowDevice ComputeModule { get; }

/// <summary>
/// Gets the ITemperatureSensor on the Clima board
/// </summary>
Expand Down
Loading

0 comments on commit 2b72395

Please sign in to comment.