Skip to content

Commit

Permalink
working on sensor service
Browse files Browse the repository at this point in the history
  • Loading branch information
ctacke committed Oct 16, 2023
1 parent f082da3 commit 0516194
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
3 changes: 3 additions & 0 deletions source/Meadow.Core/MeadowOS.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Meadow.Cloud;
using Meadow.Logging;
using Meadow.Peripherals.Sensors;
using Meadow.Update;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -88,6 +89,8 @@ private static async Task Start(string[]? args, IApp? app)
ReportAppException(e, "Device (system) Initialization Failure");
}

Resolver.Services.Add<ISensorService>(new SensorService());

if (systemInitialized)
{
var stepName = "App Initialize";
Expand Down
105 changes: 105 additions & 0 deletions source/Meadow.Core/SensorService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Meadow.Peripherals.Sensors;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow;

internal class ThreadedPollingSensorMonitor : ISensorMonitor
{
public EventHandler<object> SampleAvailable = default!;

private readonly List<(ISensor sensor, MethodInfo readMethod)> _monitorList = new();
private Thread? _sampleThread;
private bool _stopRequested = false;
private PropertyInfo? _resultProperty;
private List<ISensor> _sensorList = new();
private long _tick;


public ThreadedPollingSensorMonitor()
{
}

public void AddSensor(ISensor sensor, TimeSpan updateInterval)
{
// find the Read method, if it exists
// this is just a limitation of C# generics - looking for a better way
var readMethod = sensor.GetType().GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);

if (readMethod != null)
{
_monitorList.Add((sensor, readMethod));
}
}

public void StartSampling(ISensor sensor)
{
if (_sampleThread == null)
{
_sampleThread = new Thread(SamplingThreadProc);
_sampleThread.Start();
}

_sensorList.Add(sensor);
}

private async void SamplingThreadProc()
{
while (!_stopRequested)
{
foreach (var monitor in _monitorList)
{
if (_sensorList.Contains(monitor.sensor))
{
// TODO: check to see if the sensor should be read

var task = (Task)monitor.readMethod.Invoke(monitor.sensor, null);
await task.ConfigureAwait(false);

if (_resultProperty == null)
{
_resultProperty = task.GetType().GetProperty("Result");
}
SampleAvailable?.Invoke(monitor.sensor, _resultProperty.GetValue(task));

_tick++;
}
}

Thread.Sleep(1000);
}

_stopRequested = false;
_sampleThread = null;
}

public void StopSampling(ISensor sensor)
{
_sensorList.Remove(sensor);
}
}

internal class SensorService : ISensorService
{
private ThreadedPollingSensorMonitor? _pollMonitor;

internal SensorService()
{
}

public void RegisterSensor(ISamplingSensor sensor)
{
if (_pollMonitor == null)
{
_pollMonitor = new ThreadedPollingSensorMonitor();
}

if (sensor is ISensor s)
{
_pollMonitor.StartSampling(s);
}
}
}

0 comments on commit 0516194

Please sign in to comment.