How can I log NMEA messages coming from a NmeaLocationDataSource?
public event EventHandler<Location>? LocationChanged; <--- this gives a location object, but not the raw messages that lead to that point. What are the chances of getting those in an event? Or some other way?
Regards,
Patrick Shearon
There's no out-of-the-box support for this today (it's on our backlog). However, you could intercept the NMEA stream with a stream interceptor class. For example:
public class StreamInterceptor : Stream
{
private readonly Stream _baseStream;
public StreamInterceptor(Stream baseStream)
{
_baseStream = baseStream;
}
public event EventHandler<string>? OnData;
public override int Read(byte[] buffer, int offset, int count)
{
int read = _baseStream.Read(buffer, offset, count);
if (read > 0)
{
OnData?.Invoke(this, Encoding.UTF8.GetString(buffer, 0, read));
}
return read;
}
public override bool CanRead => _baseStream.CanRead;
public override bool CanSeek => _baseStream.CanSeek;
public override bool CanWrite => _baseStream.CanWrite;
public override long Length => _baseStream.Length;
public override long Position { get => _baseStream.Position; set => _baseStream.Position = value; }
public override void Flush() => _baseStream.Flush();
public override long Seek(long offset, SeekOrigin origin) => _baseStream.Seek(offset, origin);
public override void SetLength(long value) => _baseStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => _baseStream.Write(buffer, offset, count);
}
Then you could create the nmea datasource using this new stream type and listen to the OnData event:
SerialPort p = new SerialPort("COM3");
NmeaLocationDataSource ds = NmeaLocationDataSource.FromStreamCreator(
onStart: (ds) =>
{
p.Open();
var sl = new StreamInterceptor(p.BaseStream);
sl.OnData += (s, nmeaString) =>
{
Console.Write(nmeaString); // NMEA raw data string
};
return Task.FromResult<System.IO.Stream>(sl);
},
onStop: (ds) =>
{
p.Close();
return Task.CompletedTask;
}
);
ds.StartAsync();
What would you recommend for FromBluetooth devices?
If you're using .NET 6, you don't actually need to use the bluetooth version, but can still use them as a serial port (Windows will assign them port numbers). But otherwise, you'd have to grab the bluetooth data stream yourself before using the above.
Thanks a lot, your insight has been very helpful. Since it's all on windows (.NET 6) I will be going with System.IO.Ports.SerialPort and that StreamInterceptor. All of my tests worked with your suggestions!
Regards,
Patrick Shearon