Generic GnssDevice (#1100)
Co-authored-by: Laurent Ellerbach <laurelle@microsoft.com>
This commit is contained in:
Родитель
d4c1035125
Коммит
f1a29eb0fe
|
@ -0,0 +1,25 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the Gnss module fix status.
|
||||
/// </summary>
|
||||
public enum Fix : byte
|
||||
{
|
||||
/// <summary> Represents no fix mode of the Gnss module.
|
||||
/// </summary>
|
||||
NoFix = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Represents a 2D fix status of the Gnss module.
|
||||
/// </summary>
|
||||
Fix2D = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Represents a 3D fix status of the Gnss module.
|
||||
/// </summary>
|
||||
Fix3D = 3
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using UnitsNet;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a geographic position with latitude and longitude coordinates.
|
||||
/// </summary>
|
||||
public class GeoPosition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the latitude of a geographic position.
|
||||
/// </summary>
|
||||
public double Latitude { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the longitude of a geographic position.
|
||||
/// </summary>
|
||||
public double Longitude { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the altitude of the GNSS position.
|
||||
/// </summary>
|
||||
public double Altitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the speed of the GNSS position.
|
||||
/// </summary>
|
||||
public double Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the course angle of the GNSS position.
|
||||
/// </summary>
|
||||
public Angle Course { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the horizontal accuracy(in meters) of the location.
|
||||
/// </summary>
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vertical accuracy (in meters) of the location.
|
||||
/// </summary>
|
||||
public double VerticalAccuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time of the GNSS position.
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts latitude and longitude coordinates from decimal degrees format to a GeoPosition object.
|
||||
/// </summary>
|
||||
/// <param name="latitude">The latitude coordinate in decimal degrees.</param>
|
||||
/// <param name="longitude">The longitude coordinate in decimal degrees.</param>
|
||||
/// <returns>A GeoPosition object with the specified latitude and longitude coordinates.</returns>
|
||||
public static GeoPosition FromDecimalDegrees(double latitude, double longitude)
|
||||
{
|
||||
return new GeoPosition()
|
||||
{
|
||||
Latitude = latitude,
|
||||
Longitude = longitude
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the GNGSA data parsed from NMEA0183 sentences.
|
||||
/// </summary>
|
||||
public class GngsaData : INmeaData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Gnss module mode.
|
||||
/// </summary>
|
||||
public GnssOperation Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Gnss module fix status.
|
||||
/// </summary>
|
||||
public Fix Fix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GngsaData" /> class.
|
||||
/// </summary>
|
||||
/// <param name="mode">Gnss mode.</param>
|
||||
/// <param name="fix">Gnss fix.</param>
|
||||
public GngsaData(GnssOperation mode, Fix fix)
|
||||
{
|
||||
Mode = mode;
|
||||
Fix = fix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GngsaData" /> class.
|
||||
/// </summary>
|
||||
public GngsaData()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INmeaData Parse(string inputData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = inputData.Split(',');
|
||||
var mode = Nmea0183Parser.ConvertToMode(data[1]);
|
||||
var fix = Nmea0183Parser.ConvertToFix(data[2]);
|
||||
|
||||
return new GngsaData(mode, fix);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all Gnss devices.
|
||||
/// </summary>
|
||||
public abstract class GnssDevice
|
||||
{
|
||||
private Fix _fix = Fix.NoFix;
|
||||
private GnssOperation _mode = GnssOperation.Unknown;
|
||||
private GeoPosition _location;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type to handle the event when the Gnss module fix status changes.
|
||||
/// </summary>
|
||||
/// <param name="fix">The new fix status.</param>
|
||||
public delegate void FixChangedHandler(Fix fix);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type to handle the event when the Gnss module mode changes.
|
||||
/// </summary>
|
||||
/// <param name="mode">The new Gnss module mode.</param>
|
||||
public delegate void ModeChangedHandler(GnssOperation mode);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type to handle the event when the Gnss module location changes.
|
||||
/// </summary>
|
||||
/// <param name="position">The new position.</param>
|
||||
public delegate void LocationChangeHandler(GeoPosition position);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the fix status of the Gnss module.
|
||||
/// </summary>
|
||||
public Fix Fix
|
||||
{
|
||||
get => _fix;
|
||||
protected set
|
||||
{
|
||||
if (_fix == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_fix = value;
|
||||
FixChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the mode of the GNSS device.
|
||||
/// </summary>
|
||||
public virtual GnssMode GnssMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the mode of the Gnss module.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The mode of the Gnss module.
|
||||
/// </value>
|
||||
public GnssOperation GnssOperation
|
||||
{
|
||||
get => _mode;
|
||||
protected set
|
||||
{
|
||||
if (value == _mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_mode = value;
|
||||
OperationModeChanged?.Invoke(_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last known location.
|
||||
/// </summary>
|
||||
public GeoPosition Location
|
||||
{
|
||||
get => _location;
|
||||
protected set
|
||||
{
|
||||
_location = value;
|
||||
LocationChanged?.Invoke(_location);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the event handler for when the fix status of the Gnss module changes.
|
||||
/// </summary>
|
||||
public event FixChangedHandler FixChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that occurs when the location changes.
|
||||
/// </summary>
|
||||
public event LocationChangeHandler LocationChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the event that is raised when the mode of the Gnss module is changed.
|
||||
/// </summary>
|
||||
public event ModeChangedHandler OperationModeChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.props" Condition="Exists('packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<ProjectGuid>d3085490-46b6-488a-96f1-ef820e67acc0</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<RootNamespace>Iot.Device.Common.GnssDevice</RootNamespace>
|
||||
<AssemblyName>Iot.Device.Common.GnssDevice</AssemblyName>
|
||||
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
|
||||
<DocumentationFile>bin\$(Configuration)\Iot.Device.Common.GnssDevice.xml</DocumentationFile>
|
||||
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<RestoreLockedMode Condition="'$(TF_BUILD)' == 'True' or '$(ContinuousIntegrationBuild)' == 'True'">true</RestoreLockedMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DelaySign>false</DelaySign>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
|
||||
<ItemGroup>
|
||||
<Compile Include="Fix.cs" />
|
||||
<Compile Include="GeoPosition.cs" />
|
||||
<Compile Include="GpggaData.cs" />
|
||||
<Compile Include="GpgllData.cs" />
|
||||
<Compile Include="GngsaData.cs" />
|
||||
<Compile Include="GnssDevice.cs" />
|
||||
<Compile Include="GnssMode.cs" />
|
||||
<Compile Include="GnssOperation.cs" />
|
||||
<Compile Include="GpgsaData.cs" />
|
||||
<Compile Include="Nmea0183Parser.cs" />
|
||||
<Compile Include="INmeaData.cs" />
|
||||
<Compile Include="PositioningIndicator.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Status.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib, Version=1.15.6.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>packages\nanoFramework.CoreLibrary.1.15.5\lib\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Collections, Version=1.5.31.0, Culture=neutral, PublicKeyToken=c07d481e9758c731, processorArchitecture=MSIL">
|
||||
<HintPath>packages\nanoFramework.System.Collections.1.5.31\lib\nanoFramework.System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Math, Version=1.5.43.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>packages\nanoFramework.System.Math.1.5.43\lib\System.Math.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnitsNet.Angle">
|
||||
<HintPath>packages\UnitsNet.nanoFramework.Angle.5.55.0\lib\UnitsNet.Angle.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="packages.lock.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
|
||||
<ProjectExtensions>
|
||||
<ProjectCapabilities>
|
||||
<ProjectConfigurationsDeclaredAsItems />
|
||||
</ProjectCapabilities>
|
||||
</ProjectExtensions>
|
||||
<Import Project="packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets" Condition="Exists('packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets'))" />
|
||||
<Error Condition="!Exists('packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.props'))" />
|
||||
<Error Condition="!Exists('packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.targets'))" />
|
||||
</Target>
|
||||
<Import Project="packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.targets" Condition="Exists('packages\Nerdbank.GitVersioning.3.6.139\build\Nerdbank.GitVersioning.targets')" />
|
||||
</Project>
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>nanoFramework.Iot.Device.Common.GnssDevice</id>
|
||||
<version>$version$</version>
|
||||
<title>nanoFramework.Iot.Device.Common.GnssDevice</title>
|
||||
<authors>nanoframework</authors>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="file">LICENSE.md</license>
|
||||
<releaseNotes>
|
||||
</releaseNotes>
|
||||
<readme>docs/README.md</readme>
|
||||
<developmentDependency>false</developmentDependency>
|
||||
<projectUrl>https://github.com/nanoframework/nanoFramework.IoT.Device</projectUrl>
|
||||
<icon>images\nf-logo.png</icon>
|
||||
<repository type="git" url="https://github.com/nanoframework/nanoFramework.IoT.Device" commit="$commit$" />
|
||||
<copyright>Copyright (c) .NET Foundation and Contributors</copyright>
|
||||
<description>This package includes the .NET IoT Core binding Iot.Device.Common.GnssDevice for .NET nanoFramework C# projects.</description>
|
||||
<summary>Iot.Device.Common.GnssDevice assembly for .NET nanoFramework C# projects</summary>
|
||||
<tags>nanoFramework C# csharp netmf netnf Weather Helper</tags>
|
||||
<dependencies>
|
||||
<dependency id="nanoFramework.CoreLibrary" version="1.15.5" />
|
||||
<dependency id="nanoFramework.System.Math" version="1.5.43" />
|
||||
<dependency id="nanoFramework.System.Collections" version="1.5.31" />
|
||||
<dependency id="UnitsNet.nanoFramework.Angle" version="5.55.0" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="bin\Release\Iot.Device.Common.GnssDevice.dll" target="lib\Iot.Device.Common.GnssDevice.dll" />
|
||||
<file src="bin\Release\Iot.Device.Common.GnssDevice.pdb" target="lib\Iot.Device.Common.GnssDevice.pdb" />
|
||||
<file src="bin\Release\Iot.Device.Common.GnssDevice.pdbx" target="lib\Iot.Device.Common.GnssDevice.pdbx" />
|
||||
<file src="bin\Release\Iot.Device.Common.GnssDevice.pe" target="lib\Iot.Device.Common.GnssDevice.pe" />
|
||||
<file src="bin\Release\Iot.Device.Common.GnssDevice.xml" target="lib\Iot.Device.Common.GnssDevice.xml" />
|
||||
<file src="README.md" target="docs\" />
|
||||
<file src="..\..\assets\nf-logo.png" target="images" />
|
||||
<file src="..\..\LICENSE.md" target="" />
|
||||
</files>
|
||||
</package>
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35004.147
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "GnssDevice", "GnssDevice.nfproj", "{D3085490-46B6-488A-96F1-EF820E67ACC0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{321E1274-146C-4F3A-8C78-DE873A6DD1F0}"
|
||||
EndProject
|
||||
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "GnssDevice.Tests", "Tests\GnssDeviceTests\GnssDevice.Tests.nfproj", "{A9B49F93-BF2A-41C7-84AE-770DD2388362}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D3085490-46B6-488A-96F1-EF820E67ACC0}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{A9B49F93-BF2A-41C7-84AE-770DD2388362} = {321E1274-146C-4F3A-8C78-DE873A6DD1F0}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F63D93E7-29AF-4075-93F4-C6A55CA958C8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,54 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// The Global Navigation Satellite System mode.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum GnssMode
|
||||
{
|
||||
/// <summary>
|
||||
/// No GNSS mode selected.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Global Positioning System.
|
||||
/// </summary>
|
||||
Gps = 0b0000_0001,
|
||||
|
||||
/// <summary>
|
||||
/// BeiDou Navigation Satellite System.
|
||||
/// </summary>
|
||||
Bds = 0b0000_0010,
|
||||
|
||||
/// <summary>
|
||||
/// Global Navigation Satellite System.
|
||||
/// </summary>
|
||||
Glonass = 0b0000_0100,
|
||||
|
||||
/// <summary>
|
||||
/// Quasi-Zenith Satellite System.
|
||||
/// </summary>
|
||||
Qzss = 0b0000_1000,
|
||||
|
||||
/// <summary>
|
||||
/// Galileo.
|
||||
/// </summary>
|
||||
Galileo = 0b0001_0000,
|
||||
|
||||
/// <summary>
|
||||
/// Satellite-Based Augmentation Systems.
|
||||
/// </summary>
|
||||
Sbas = 0b0010_0000,
|
||||
|
||||
/// <summary>
|
||||
/// Wide Area Augmentation System.
|
||||
/// </summary>
|
||||
Wass = 0b0100_0000,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the Gnss module mode.
|
||||
/// </summary>
|
||||
public enum GnssOperation : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an unknown mode of the Gnss module.
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// A for an automatic mode of operation for the Gnss module.
|
||||
/// </summary>
|
||||
Auto = 1,
|
||||
|
||||
/// <summary>
|
||||
/// M for a manual mode of the Gnss module.
|
||||
/// </summary>
|
||||
Manual = 2
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the NMEA0183 data for GPGGA.
|
||||
/// </summary>
|
||||
public class GpggaData : INmeaData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the location information in Global Navigation Satellite System (GNSS) coordinates.
|
||||
/// </summary>
|
||||
public GeoPosition Location { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of satellites in use.
|
||||
/// </summary>
|
||||
public int SatellitesInView { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the geodetic separation.
|
||||
/// </summary>
|
||||
public double GeodidSeparation { get; internal set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INmeaData Parse(string inputData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = inputData.Split(',');
|
||||
var lat = data[2];
|
||||
var latDir = data[3];
|
||||
var lon = data[4];
|
||||
var lonDir = data[5];
|
||||
var latitude = Nmea0183Parser.ConvertToGeoLocation(lat, latDir);
|
||||
var longitude = Nmea0183Parser.ConvertToGeoLocation(lon, lonDir);
|
||||
var altitude = double.Parse(data[9]);
|
||||
var hdop = double.Parse(data[8]);
|
||||
var time = Nmea0183Parser.ConvertToTimeSpan(data[1]);
|
||||
|
||||
var position = GeoPosition.FromDecimalDegrees(latitude, longitude);
|
||||
position.Altitude = altitude;
|
||||
position.Accuracy = hdop;
|
||||
position.Timestamp = DateTime.UtcNow.Date.Add(time);
|
||||
return new GpggaData(position)
|
||||
{
|
||||
SatellitesInView = int.Parse(data[7]),
|
||||
GeodidSeparation = double.Parse(data[11]),
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GpggaData" /> class.
|
||||
/// </summary>
|
||||
/// <param name="location">A <see cref="GeoPosition"/> item.</param>
|
||||
public GpggaData(GeoPosition location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GpggaData" /> class.
|
||||
/// </summary>
|
||||
public GpggaData()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the GNGLL NMEA0183 data from a Gnss device.
|
||||
/// </summary>
|
||||
public class GpgllData : INmeaData
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public INmeaData Parse(string inputData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = inputData.Split(',');
|
||||
var lat = data[1];
|
||||
var latDir = data[2];
|
||||
var lon = data[3];
|
||||
var lonDir = data[4];
|
||||
var latitude = Nmea0183Parser.ConvertToGeoLocation(lat, latDir);
|
||||
var longitude = Nmea0183Parser.ConvertToGeoLocation(lon, lonDir);
|
||||
var time = Nmea0183Parser.ConvertToTimeSpan(data[5]);
|
||||
|
||||
var geo = GeoPosition.FromDecimalDegrees(latitude, longitude);
|
||||
geo.Timestamp = DateTime.UtcNow.Date.Add(time);
|
||||
return new GpgllData(geo)
|
||||
{
|
||||
Status = Nmea0183Parser.ConvertToStatus(data[6]),
|
||||
Mode = Nmea0183Parser.ConvertToPositioningIndicator(data[7]),
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location information in Global Navigation Satellite System (GNSS) coordinates.
|
||||
/// </summary>
|
||||
public GeoPosition Location { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the positioning mode.
|
||||
/// </summary>
|
||||
public PositioningIndicator Mode { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data status.
|
||||
/// </summary>
|
||||
public Status Status { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GpgllData" /> class.
|
||||
/// </summary>
|
||||
/// <param name="location">Location information.</param>
|
||||
public GpgllData(GeoPosition location)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GpgllData" /> class.
|
||||
/// </summary>
|
||||
public GpgllData()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the GPGSA NMEA0183 data from a Gnss device.
|
||||
/// </summary>
|
||||
public class GpgsaData : INmeaData
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GpgsaData class.
|
||||
/// </summary>
|
||||
public GpgsaData()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the operation mode of the Gnss module.
|
||||
/// </summary>
|
||||
public GnssOperation OperationMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the positioning indicator.
|
||||
/// </summary>
|
||||
public PositioningIndicator PositioningIndicator { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the satellite in use.
|
||||
/// </summary>
|
||||
public int[] SatellitesInUse { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Position Dilution of Precision of the GNSS position.
|
||||
/// </summary>
|
||||
public double PositionDilutionOfPrecision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Horizontal Dilution of Precision of the GNSS position.
|
||||
/// </summary>
|
||||
public double HorizontalDilutionOfPrecision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Vertical Dilution of Precision of the GNSS position.
|
||||
/// </summary>
|
||||
public double VerticalDilutionOfPrecision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parse the GPGSA data.
|
||||
/// </summary>
|
||||
/// <param name="inputData">The input data string.</param>
|
||||
/// <returns>An NmeaData.</returns>
|
||||
public INmeaData Parse(string inputData)
|
||||
{
|
||||
string[] subfields = inputData.Split(',');
|
||||
if (subfields[0] != "$GPGSA")
|
||||
{
|
||||
throw new ArgumentException("GPGSA data is expected.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var sats = new int[12];
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
sats[i] = int.Parse(subfields[i + 3]);
|
||||
}
|
||||
|
||||
var gsa = new GpgsaData()
|
||||
{
|
||||
OperationMode = Nmea0183Parser.ConvertToMode(subfields[1]),
|
||||
PositioningIndicator = Nmea0183Parser.ConvertToPositioningIndicator(subfields[2]),
|
||||
SatellitesInUse = sats,
|
||||
PositionDilutionOfPrecision = double.Parse(subfields[15]),
|
||||
HorizontalDilutionOfPrecision = double.Parse(subfields[16]),
|
||||
VerticalDilutionOfPrecision = double.Parse(subfields[17]),
|
||||
};
|
||||
|
||||
return gsa;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// NMEA0183 Data Interface.
|
||||
/// </summary>
|
||||
public interface INmeaData
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse for the specific data type.
|
||||
/// </summary>
|
||||
/// <param name="inputData">The input data string.</param>
|
||||
/// <returns>An NmeaData.</returns>
|
||||
public INmeaData Parse(string inputData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for parsing NMEA0183 data from a Gnss device.
|
||||
/// </summary>
|
||||
public static class Nmea0183Parser
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an array of parsable <see cref="INmeaData"/> parsers.
|
||||
/// </summary>
|
||||
public static Hashtable MneaDatas { get; } = new ()
|
||||
{
|
||||
{ "$GPGLL", new GpgllData() },
|
||||
{ "$GNGSA", new GngsaData() },
|
||||
{ "$GPGGA", new GpggaData() },
|
||||
{ "$GPGSA", new GpggaData() }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Adds a parser to the list of available parsers.
|
||||
/// </summary>
|
||||
/// <param name="dataId">The data type to parse eg $GPGLL.</param>
|
||||
/// <param name="parser">The parser class.</param>
|
||||
public static void AddParser(string dataId, INmeaData parser)
|
||||
{
|
||||
MneaDatas.Add(dataId, parser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a parser from the list of available parsers.
|
||||
/// </summary>
|
||||
/// <param name="dataId">The data type to parse eg $GPGLL.</param>
|
||||
public static void RemoveParser(string dataId)
|
||||
{
|
||||
MneaDatas.Remove(dataId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string and return the parsed NmeaData object.
|
||||
/// </summary>
|
||||
/// <param name="inputData">A valid MNEA string.</param>
|
||||
/// <returns>Parsed NmeaData object if any or null.</returns>
|
||||
public static INmeaData Parse(string inputData)
|
||||
{
|
||||
var data = inputData.Split(',');
|
||||
var dataId = data[0];
|
||||
|
||||
var mnea = MneaDatas[dataId] as INmeaData;
|
||||
if (mnea is null)
|
||||
{
|
||||
Debug.WriteLine($"Parser for {dataId} not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return mnea.Parse(inputData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a geographic location.
|
||||
/// </summary>
|
||||
/// <param name="data">Valid input data.</param>
|
||||
/// <param name="direction">The direction.</param>
|
||||
/// <returns>A double representing an coordinate elements.</returns>
|
||||
internal static double ConvertToGeoLocation(string data, string direction)
|
||||
{
|
||||
var degreesLength = data.Length > 12 ? 3 : 2;
|
||||
|
||||
var degrees = double.Parse(data.Substring(0, degreesLength));
|
||||
var minutes = double.Parse(data.Substring(degreesLength));
|
||||
|
||||
var result = degrees + (minutes / 60);
|
||||
|
||||
if (direction == "S" || direction == "W")
|
||||
{
|
||||
return -result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a GnssOperation.
|
||||
/// </summary>
|
||||
/// <param name="data">A valid string.</param>
|
||||
/// <returns>A <see cref="GnssOperation"/>.</returns>
|
||||
internal static GnssOperation ConvertToMode(string data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case "M":
|
||||
return GnssOperation.Manual;
|
||||
case "A":
|
||||
return GnssOperation.Auto;
|
||||
default:
|
||||
return GnssOperation.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a Fix.
|
||||
/// </summary>
|
||||
/// <param name="data">A valid string.</param>
|
||||
/// <returns>A <see cref="Fix"/>.</returns>
|
||||
/// <exception cref="Exception">Not a valid fix.</exception>
|
||||
internal static Fix ConvertToFix(string data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case "1":
|
||||
return Fix.NoFix;
|
||||
case "2":
|
||||
return Fix.Fix2D;
|
||||
case "3":
|
||||
return Fix.Fix3D;
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a PositioningIndicator.
|
||||
/// </summary>
|
||||
/// <param name="data">A valid string.</param>
|
||||
/// <returns>The proper <see cref="PositioningIndicator"/> mode.</returns>
|
||||
/// <exception cref="Exception">Not a valid positioning.</exception>
|
||||
internal static PositioningIndicator ConvertToPositioningIndicator(string data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case "A":
|
||||
return PositioningIndicator.Autonomous;
|
||||
case "D":
|
||||
return PositioningIndicator.Differential;
|
||||
case "E":
|
||||
return PositioningIndicator.Estimated;
|
||||
case "M":
|
||||
return PositioningIndicator.Manual;
|
||||
case "N":
|
||||
return PositioningIndicator.NotValid;
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a Status.
|
||||
/// </summary>
|
||||
/// <param name="data">A valid string.</param>
|
||||
/// <returns>The proper <see cref="Status"/>.</returns>
|
||||
/// <exception cref="Exception">Not a valid status.</exception>
|
||||
internal static Status ConvertToStatus(string data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case "A":
|
||||
return Status.Valid;
|
||||
case "V":
|
||||
return Status.NotValid;
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string date and time to a DateTime.
|
||||
/// </summary>
|
||||
/// <param name="date">The date string as YYMMDD.</param>
|
||||
/// <param name="time">The time as HHMMSS.ss.</param>
|
||||
/// <returns>A <see cref="DateTime"/> object.</returns>
|
||||
internal static DateTime ConvertToUtcDateTime(string date, string time)
|
||||
{
|
||||
var timespan = ConvertToTimeSpan(time);
|
||||
|
||||
var day = int.Parse(date.Substring(0, 2));
|
||||
var month = int.Parse(date.Substring(2, 2));
|
||||
var year = int.Parse(date.Substring(4, 2)) + 2000;
|
||||
|
||||
return new DateTime(year, month, day).Add(timespan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string time to a TimeSpan.
|
||||
/// </summary>
|
||||
/// <param name="time">The time as HHMMSS.ss.</param>
|
||||
/// <returns>A <see cref="TimeSpan"/> object.</returns>
|
||||
internal static TimeSpan ConvertToTimeSpan(string time)
|
||||
{
|
||||
var hour = int.Parse(time.Substring(0, 2));
|
||||
var minute = int.Parse(time.Substring(2, 2));
|
||||
var second = int.Parse(time.Substring(4, 2));
|
||||
var millec = int.Parse(time.Substring(7));
|
||||
|
||||
return new TimeSpan(0, hour, minute, second, millec);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// NMEA Positioning System Mode Indicator.
|
||||
/// </summary>
|
||||
public enum PositioningIndicator
|
||||
{
|
||||
/// <summary>A for Autonomous.</summary>
|
||||
Autonomous,
|
||||
|
||||
/// <summary>D for Differential.</summary>
|
||||
Differential,
|
||||
|
||||
/// <summary>E for Estimated (dead reckoning) mode.</summary>
|
||||
Estimated,
|
||||
|
||||
/// <summary>M for Manual input.</summary>
|
||||
Manual,
|
||||
|
||||
/// <summary>N for Data not valid.</summary>
|
||||
NotValid,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("Iot.Device.GnssDevice")]
|
||||
[assembly: AssemblyCompany("nanoFramework Contributors")]
|
||||
[assembly: AssemblyCopyright("Copyright(c).NET Foundation and Contributors")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,3 @@
|
|||
# Iot.Device.GnsssDevice
|
||||
|
||||
Base Gnss classes for all NF Gnss modules. See [Atgm336h](../Atgm336h/) for a detailed usage.
|
|
@ -0,0 +1,112 @@
|
|||
<StyleCopSettings Version="105">
|
||||
<Analyzers>
|
||||
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
|
||||
<Rules>
|
||||
<Rule Name="FileHeaderMustContainFileName">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FileHeaderMustHaveValidCompanyText">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="PropertyDocumentationMustHaveValueText">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">True</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="DocumentationTextMustBeginWithACapitalLetter">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">True</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="DocumentationTextMustEndWithAPeriod">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">True</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FileHeaderMustShowCopyright">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FileHeaderMustHaveCopyrightText">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="ElementDocumentationMustBeSpelledCorrectly">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="DocumentationTextMustContainWhitespace">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings>
|
||||
<BooleanProperty Name="IgnorePrivates">True</BooleanProperty>
|
||||
<BooleanProperty Name="IgnoreInternals">True</BooleanProperty>
|
||||
</AnalyzerSettings>
|
||||
</Analyzer>
|
||||
<Analyzer AnalyzerId="StyleCop.CSharp.ReadabilityRules">
|
||||
<Rules>
|
||||
<Rule Name="PrefixLocalCallsWithThis">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="PrefixCallsCorrectly">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings />
|
||||
</Analyzer>
|
||||
<Analyzer AnalyzerId="StyleCop.CSharp.OrderingRules">
|
||||
<Rules>
|
||||
<Rule Name="UsingDirectivesMustBePlacedWithinNamespace">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="ElementsMustAppearInTheCorrectOrder">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="ElementsMustBeOrderedByAccess">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings />
|
||||
</Analyzer>
|
||||
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
|
||||
<Rules>
|
||||
<Rule Name="FieldNamesMustNotBeginWithUnderscore">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FieldNamesMustNotUseHungarianNotation">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings />
|
||||
</Analyzer>
|
||||
</Analyzers>
|
||||
</StyleCopSettings>
|
|
@ -0,0 +1,17 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace Iot.Device.Common.GnssDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// NMEA data status.
|
||||
/// </summary>
|
||||
public enum Status
|
||||
{
|
||||
/// <summary>A for Valid data.</summary>
|
||||
Valid,
|
||||
|
||||
/// <summary>V for invalid data.</summary>
|
||||
NotValid,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
|
||||
<ItemGroup>
|
||||
<ProjectCapability Include="TestContainer" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<ProjectGuid>a9b49f93-bf2a-41c7-84ae-770dd2388362</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<RootNamespace>GnssDeviceTests</RootNamespace>
|
||||
<AssemblyName>NFUnitTest</AssemblyName>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
|
||||
<PropertyGroup>
|
||||
<RunSettingsFilePath>$(MSBuildProjectDirectory)\nano.runsettings</RunSettingsFilePath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="NMEA0183ParserTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>..\..\packages\nanoFramework.CoreLibrary.1.15.5\lib\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Collections">
|
||||
<HintPath>..\..\packages\nanoFramework.System.Collections.1.5.31\lib\nanoFramework.System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.TestFramework">
|
||||
<HintPath>..\..\packages\nanoFramework.TestFramework.2.1.107\lib\nanoFramework.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.UnitTestLauncher">
|
||||
<HintPath>..\..\packages\nanoFramework.TestFramework.2.1.107\lib\nanoFramework.UnitTestLauncher.exe</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Math">
|
||||
<HintPath>..\..\packages\nanoFramework.System.Math.1.5.43\lib\System.Math.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnitsNet.Angle">
|
||||
<HintPath>..\..\packages\UnitsNet.nanoFramework.Angle.5.55.0\lib\UnitsNet.Angle.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="nano.runsettings" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\GnssDevice.nfproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
|
||||
</Project>
|
|
@ -0,0 +1,55 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Iot.Device.Common.GnssDevice;
|
||||
using nanoFramework.TestFramework;
|
||||
using System;
|
||||
|
||||
namespace GnssDevice.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class NMEA0183ParserTests
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow("$GNGSA,A,3,65,67,80,81,82,88,66,,,,,,1.2,0.7,1.0*20", (byte)GnssOperation.Auto, (byte)Fix.Fix3D)]
|
||||
[DataRow("$GNGSA,A,2,65,67,80,81,82,88,66,,,,,,1.2,0.7,1.0*20", (byte)GnssOperation.Auto, (byte)Fix.Fix2D)]
|
||||
[DataRow("$GNGSA,A,1,65,67,80,81,82,88,66,,,,,,1.2,0.7,1.0*20", (byte)GnssOperation.Auto, (byte)Fix.NoFix)]
|
||||
[DataRow("$GNGSA,M,1,65,67,80,81,82,88,66,,,,,,1.2,0.7,1.0*20", (byte)GnssOperation.Manual, (byte)Fix.NoFix)]
|
||||
public void ParseGngsa(string command, byte expectedMode, byte expectedFix)
|
||||
{
|
||||
// Act
|
||||
GngsaData result = (GngsaData)Nmea0183Parser.Parse(command);
|
||||
OutputHelper.WriteLine($"{(result == null ? "result null" : "result not null")}");
|
||||
// Assert
|
||||
Assert.AreEqual(expectedMode, (byte)result.Mode);
|
||||
Assert.AreEqual(expectedFix, (byte)result.Fix);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow("$GPGLL,5109.0262317,N,11401.8407304,W,202725.00,A,D*79", 51.1504372f, -114.03067884f)]
|
||||
public void ParseGpgll(string command, float expectedLatitude, float expectedLongitude)
|
||||
{
|
||||
// Act
|
||||
GpgllData result = (GpgllData)Nmea0183Parser.Parse(command);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(expectedLongitude, (float)result.Location.Longitude);
|
||||
Assert.AreEqual(expectedLatitude, (float)result.Location.Latitude);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow("$GPGGA,002153.000,3342.6618,N,11751.3858,W,1,10,1.2,27.0,M,-34.2,M,,0000*5E", 33.7110291f, -23.5230961f, 27.0f, 1.2f, 1313000d)]
|
||||
public void ParseGpgga(string command, float expectedLatitude, float expectedLongitude, float altitude, float accuracy, double time)
|
||||
{
|
||||
// Act
|
||||
GpggaData result = (GpggaData)Nmea0183Parser.Parse(command);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(expectedLongitude, (float)result.Location.Longitude);
|
||||
Assert.AreEqual(expectedLatitude, (float)result.Location.Latitude);
|
||||
Assert.AreEqual(altitude, (float)result.Location.Altitude);
|
||||
Assert.AreEqual(accuracy, (float)result.Location.Accuracy);
|
||||
Assert.AreEqual(time, result.Location.Timestamp.TimeOfDay.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) 2021 nanoFramework contributors")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RunSettings>
|
||||
<!-- Configurations that affect the Test Framework -->
|
||||
<RunConfiguration>
|
||||
<ResultsDirectory>.\TestResults</ResultsDirectory><!-- Path relative to solution directory -->
|
||||
<TestSessionTimeout>120000</TestSessionTimeout><!-- Milliseconds -->
|
||||
<TargetFrameworkVersion>net48</TargetFrameworkVersion>
|
||||
<TargetPlatform>x64</TargetPlatform>
|
||||
</RunConfiguration>
|
||||
<nanoFrameworkAdapter>
|
||||
<Logging>None</Logging> <!--Set to the desired level of logging for Unit Test execution. Possible values are: None, Detailed, Verbose, Error. -->
|
||||
<IsRealHardware>False</IsRealHardware><!--Set to true to run tests on real hardware. -->
|
||||
<RealHardwarePort>COM3</RealHardwarePort><!--Specify the COM port to use to connect to a nanoDevice. If none is specified, a device detection is performed and the 1st available one will be used. -->
|
||||
<CLRVersion></CLRVersion><!--Specify the nanoCLR version to use. If not specified, the latest available will be used. -->
|
||||
<PathToLocalCLRInstance></PathToLocalCLRInstance><!--Specify the path to a local nanoCLR instance. If not specified, the default one installed with nanoclr CLR witll be used. -->
|
||||
</nanoFrameworkAdapter>
|
||||
</RunSettings>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="nanoFramework.CoreLibrary" version="1.15.5" targetFramework="netnano1.0" />
|
||||
<package id="nanoFramework.System.Collections" version="1.5.31" targetFramework="netnano1.0" />
|
||||
<package id="nanoFramework.System.Math" version="1.5.43" targetFramework="netnano1.0" />
|
||||
<package id="nanoFramework.TestFramework" version="2.1.107" targetFramework="netnano1.0" developmentDependency="true" />
|
||||
<package id="UnitsNet.nanoFramework.Angle" version="5.55.0" targetFramework="netnano1.0" />
|
||||
</packages>
|
|
@ -0,0 +1,2 @@
|
|||
positioning
|
||||
helper
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="nanoFramework.CoreLibrary" version="1.15.5" targetFramework="netnano1.0" />
|
||||
<package id="nanoFramework.System.Collections" version="1.5.31" targetFramework="netnano1.0" />
|
||||
<package id="nanoFramework.System.Math" version="1.5.43" targetFramework="netnano1.0" />
|
||||
<package id="Nerdbank.GitVersioning" version="3.6.139" developmentDependency="true" targetFramework="netnano1.0" />
|
||||
<package id="StyleCop.MSBuild" version="6.2.0" targetFramework="netnano1.0" developmentDependency="true" />
|
||||
<package id="UnitsNet.nanoFramework.Angle" version="5.55.0" targetFramework="netnano1.0" />
|
||||
</packages>
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
".NETnanoFramework,Version=v1.0": {
|
||||
"nanoFramework.CoreLibrary": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.15.5, 1.15.5]",
|
||||
"resolved": "1.15.5",
|
||||
"contentHash": "u2+GvAp1uxLrGdILACAZy+EVKOs28EQ52j8Lz7599egXZ3GBGejjnR2ofhjMQwzrJLlgtyrsx8nSLngDfJNsAg=="
|
||||
},
|
||||
"nanoFramework.System.Collections": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.5.31, 1.5.31]",
|
||||
"resolved": "1.5.31",
|
||||
"contentHash": "q7G0BHkbhUzpUJiOQNlZZDSMcZEU2/QJBDiSEQAF23wOya4EBaCXS74jAVcEfkHBgOkF413jKZq5vldpjqUfUw=="
|
||||
},
|
||||
"nanoFramework.System.Math": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.5.43, 1.5.43]",
|
||||
"resolved": "1.5.43",
|
||||
"contentHash": "JEOEGHoIpknJFwPjjz77sT5mej2PiT7JTv59jabzFf+d8XYy8Z4SH+NdX00Xc/yDS8LIPuWb7+C245XGUUx99A=="
|
||||
},
|
||||
"Nerdbank.GitVersioning": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.6.139, 3.6.139]",
|
||||
"resolved": "3.6.139",
|
||||
"contentHash": "rq0Ub/Jik7PtMtZtLn0tHuJ01Yt36RQ+eeBe+S7qnJ/EFOX6D4T9zuYD3vQPYKGI6Ro4t2iWgFm3fGDgjBrMfg=="
|
||||
},
|
||||
"StyleCop.MSBuild": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.2.0, 6.2.0]",
|
||||
"resolved": "6.2.0",
|
||||
"contentHash": "6J51Kt5X+Os+Ckp20SFP1SlLu3tZl+3qBhCMtJUJqGDgwSr4oHT+eg545hXCdp07tRB/8nZfXTOBDdA1XXvjUw=="
|
||||
},
|
||||
"UnitsNet.nanoFramework.Angle": {
|
||||
"type": "Direct",
|
||||
"requested": "[5.55.0, 5.55.0]",
|
||||
"resolved": "5.55.0",
|
||||
"contentHash": "8x2W/kkFpVpQ7HzhSAkeZ+VhfgFY86URwkGHTqHNOquscoF31CB+q/hQSq7QlZG8Vm1t2uSGtuLQC2IyRorUcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
|
||||
"version": "1.0",
|
||||
"semVer1NumericIdentifierPadding": 3,
|
||||
"nuGetPackageVersion": {
|
||||
"semVer": 2.0
|
||||
},
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/develop$",
|
||||
"^refs/heads/main$",
|
||||
"^refs/heads/v\\d+(?:\\.\\d+)?$"
|
||||
],
|
||||
"cloudBuild": {
|
||||
"setAllVariables": true
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче