Co-authored-by: Laurent Ellerbach <laurelle@microsoft.com>
This commit is contained in:
Marcin Torba 2024-08-06 13:30:01 +02:00 коммит произвёл GitHub
Родитель d4c1035125
Коммит f1a29eb0fe
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
28 изменённых файлов: 1386 добавлений и 0 удалений

25
devices/GnssDevice/Fix.cs Normal file
Просмотреть файл

@ -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
}
}