Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions Source/Meadow.Clima/Controllers/LocationController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Meadow.Devices.Clima.Hardware;
using Meadow.Peripherals.Sensors.Location.Gnss;
using Meadow.Units;
using System;
using System.Threading;

namespace Meadow.Devices.Clima.Controllers;

Expand All @@ -21,6 +23,8 @@ public class LocationController
/// </summary>
public event EventHandler<GnssPositionInfo>? PositionReceived = null;

private ManualResetEvent positionReceived = new ManualResetEvent(false);

/// <summary>
/// Initializes a new instance of the <see cref="LocationController"/> class.
/// </summary>
Expand All @@ -31,21 +35,66 @@ public LocationController(IClimaHardware clima)
{
this.gnss = gnss;
this.gnss.GnssDataReceived += OnGnssDataReceived;
this.gnss.StartUpdating();
}
}

/// <summary>
/// Gets the current geographic position as a <see cref="GeographicCoordinate"/>.
/// </summary>
/// <value>
/// The geographic position, including latitude, longitude, and altitude, if available.
/// </value>
/// <remarks>
/// This property is updated when valid GNSS data is received. It represents the last known position
/// and remains unchanged until new valid data is processed.
/// </remarks>
public GeographicCoordinate? Position { get; private set; } = default;

private void OnGnssDataReceived(object sender, IGnssResult e)
{
if (e is GnssPositionInfo pi)
{
if (pi.IsValid && pi.Position != null)
{
// remember our position
Position = pi.Position;
// 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.Set();
PositionReceived?.Invoke(this, pi);
gnss?.StopUpdating();
StopUpdating();
}
}
}
}

/// <summary>
/// Starts the GNSS sensor to begin updating location data.
/// </summary>
/// <remarks>
/// This method invokes the <see cref="IGnssSensor.StartUpdating"/> method on the associated GNSS sensor,
/// if it is available, to start receiving GNSS data updates.
/// </remarks>
public void StartUpdating(bool forced = false)
{
// start updating if forced to find new data or we don;t have current location
if (forced || !positionReceived.WaitOne(0))
{
gnss?.StartUpdating();
};
}

/// <summary>
/// Stops the GNSS sensor from updating location data.
/// </summary>
/// <remarks>
/// This method halts the GNSS data updates by invoking the <see cref="IGnssSensor.StopUpdating"/>
/// method on the associated GNSS sensor, if it is available.
/// </remarks>
public void StopUpdating()
{
// stop listening to data arriving from GNSS
gnss?.StopUpdating();

// TODO: can we tell GNSS sensor to stop calculating GPS location and stop sending data to reduce power consumption?
}
}
19 changes: 16 additions & 3 deletions Source/Meadow.Clima/MainController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
/// </summary>
public class MainController
{
private NotificationController notificationController;

Check warning on line 17 in Source/Meadow.Clima/MainController.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'notificationController' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
private SensorController sensorController;

Check warning on line 18 in Source/Meadow.Clima/MainController.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'sensorController' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
private PowerController powerController;

Check warning on line 19 in Source/Meadow.Clima/MainController.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'powerController' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
private LocationController locationController;
private NetworkController? networkController;
private CloudController cloudController;
Expand Down Expand Up @@ -58,9 +58,9 @@
powerController.SolarVoltageWarning += OnSolarVoltageWarning;
powerController.BatteryVoltageWarning += OnBatteryVoltageWarning;

locationController = new LocationController(hardware);

locationController.PositionReceived += OnPositionReceived;



if (networkAdapter == null)
{
Expand Down Expand Up @@ -91,6 +91,9 @@
Resolver.MeadowCloudService.ConnectionStateChanged += OnMeadowCloudServiceConnectionStateChanged;
cloudController.LogAppStartup(hardware.RevisionString);

locationController = new LocationController(hardware);
locationController.PositionReceived += OnPositionReceived;

Resolver.Device.PlatformOS.AfterWake += PlatformOS_AfterWake;

if (!lowPowerMode)
Expand All @@ -113,6 +116,7 @@
Resolver.Log.Info($"Start Updating");
sensorController.StartUpdating(sensorController.UpdateInterval);
powerController.StartUpdating(powerController.UpdateInterval);
locationController.StartUpdating();
}

/// <summary>
Expand All @@ -123,6 +127,7 @@
Resolver.Log.Info($"Stop Updating");
sensorController.StopUpdating();
powerController.StopUpdating();
locationController.StopUpdating();
sleepSimulationTimer.Change(-1, -1); // stop timer
}

Expand Down Expand Up @@ -206,7 +211,15 @@
{
case CloudConnectionState.Connected:
notificationController.SetSystemStatus(NotificationController.SystemStatus.Connected);

locationController.StartUpdating();
break;

case CloudConnectionState.Disconnected:
case CloudConnectionState.Unknown:
locationController.StopUpdating();
break;

default:
notificationController.SetSystemStatus(NotificationController.SystemStatus.ConnectingToCloud);
break;
Expand Down Expand Up @@ -312,4 +325,4 @@
Resolver.Log.Info(report);
}
}
}
}
Loading