Skip to content

Commit

Permalink
Merge pull request #72 from meshtastic/wip
Browse files Browse the repository at this point in the history
Updates
  • Loading branch information
thebentern authored Mar 26, 2024
2 parents 9a8bff9 + 3108b1a commit 44c8325
Show file tree
Hide file tree
Showing 24 changed files with 4,949 additions and 3,018 deletions.
51 changes: 19 additions & 32 deletions Meshtastic.Cli/CommandHandlers/FixedPositionCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,19 @@

namespace Meshtastic.Cli.CommandHandlers;

public class FixedPositionCommandHandler : DeviceCommandHandler
public class FixedPositionCommandHandler(decimal latitude,
decimal longitude,
int altitude,
bool clear,
DeviceConnectionContext context,
CommandContext commandContext) : DeviceCommandHandler(context, commandContext)
{
private readonly decimal latitude;
private readonly decimal longitude;
private readonly int altitude;
private readonly decimal latitude = latitude;
private readonly decimal longitude = longitude;
private readonly int altitude = altitude;
private readonly bool clear = clear;
private readonly decimal divisor = new(1e-7);

public FixedPositionCommandHandler(decimal latitude,
decimal longitude,
int altitude,
DeviceConnectionContext context,
CommandContext commandContext) : base(context, commandContext)
{
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
}

public async Task<DeviceStateContainer> Handle()
{
var wantConfig = new ToRadioMessageFactory().CreateWantConfigMessage();
Expand All @@ -35,31 +30,23 @@ public async Task<DeviceStateContainer> Handle()
public override async Task OnCompleted(FromRadio packet, DeviceStateContainer container)
{
var adminMessageFactory = new AdminMessageFactory(container, Destination);
var positionMessageFactory = new PositionMessageFactory(container, Destination);

await BeginEditSettings(adminMessageFactory);

var positionMessage = positionMessageFactory.CreatePositionPacket(new Position()
var position = new Position()
{
LatitudeI = latitude != 0 ? decimal.ToInt32(latitude / divisor) : 0,
LongitudeI = longitude != 0 ? decimal.ToInt32(longitude / divisor) : 0,
Altitude = altitude,
Time = DateTime.Now.GetUnixTimestamp(),
Timestamp = DateTime.Now.GetUnixTimestamp(),
});
await Connection.WriteToRadio(ToRadioMessageFactory.CreateMeshPacketMessage(positionMessage), AnyResponseReceived);
Logger.LogInformation($"Sending position to device...");

var positionConfig = container.LocalConfig.Position;
positionConfig.FixedPosition = true;
var adminMessage = adminMessageFactory.CreateSetConfigMessage(positionConfig);
Logger.LogInformation($"Setting Position.FixedPosition to True...");
};

await Connection.WriteToRadio(ToRadioMessageFactory.CreateMeshPacketMessage(adminMessage), (fromRadio, container) =>
{
return Task.FromResult(fromRadio.GetPayload<Routing>() != null);
});
var adminMessage = clear ? adminMessageFactory.RemovedFixedPositionMessage() : adminMessageFactory.CreateFixedPositionMessage(position);
Logger.LogInformation($"Setting fixed position...");

await CommitEditSettings(adminMessageFactory);
await Connection.WriteToRadio(ToRadioMessageFactory.CreateMeshPacketMessage(adminMessage),
(fromRadio, container) =>
{
return Task.FromResult(fromRadio.GetPayload<Routing>() != null);
});
}
}
4 changes: 2 additions & 2 deletions Meshtastic.Cli/CommandHandlers/MqttProxyCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ await mqttClient.PublishAsync(new MqttApplicationMessageBuilder()
});
}

private MqttClientOptions GetMqttClientOptions(DeviceStateContainer container)
private static MqttClientOptions GetMqttClientOptions(DeviceStateContainer container)
{
var builder = new MqttClientOptionsBuilder()
.WithClientId(container.GetDeviceNodeInfo()?.User?.Id ?? container.MyNodeInfo.MyNodeNum.ToString());

var address = container.LocalModuleConfig.Mqtt.Address;
var host = address.Split(':').FirstOrDefault() ?? container.LocalModuleConfig.Mqtt.Address;
var port = address.Contains(":") ? address.Split(':').LastOrDefault() : null;
var port = address.Contains(':') ? address.Split(':').LastOrDefault() : null;

if (container.LocalModuleConfig.Mqtt.TlsEnabled)
{
Expand Down
9 changes: 7 additions & 2 deletions Meshtastic.Cli/Commands/FixedPositionCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@ public FixedPositionCommand(string name, string description, Option<string> port
altArg.SetDefaultValue(0);
AddArgument(altArg);

this.SetHandler(async (lat, lon, alt, context, commandContext) =>
var clearOption = new Option<bool>("clear", description: "Clear fixed position");
clearOption.SetDefaultValue(false);
AddOption(clearOption);

this.SetHandler(async (lat, lon, alt, clear, context, commandContext) =>
{
var handler = new FixedPositionCommandHandler(lat, lon, alt, context, commandContext);
var handler = new FixedPositionCommandHandler(lat, lon, alt, clear, context, commandContext);
await handler.Handle();
},
latArg,
lonArg,
altArg,
clearOption,
new DeviceConnectionBinder(port, host),
new CommandContextBinder(log, output, dest, selectDest));
}
Expand Down
2 changes: 1 addition & 1 deletion Meshtastic.Cli/Display/ProtobufPrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public void PrintRoute(RepeatedField<uint> route)
public Panel PrintTrafficCharts()
{
var myInfo = container.Nodes.FirstOrDefault(n => n.Num == container.MyNodeInfo.MyNodeNum);
var airTimeStats = myInfo != null ? $"Channel Utilization {myInfo.DeviceMetrics.ChannelUtilization:N2}% / Airtime {myInfo.DeviceMetrics.AirUtilTx:N2}%" : String.Empty;
var airTimeStats = myInfo?.DeviceMetrics != null ? $"Channel Utilization {myInfo.DeviceMetrics.ChannelUtilization:N2}% / Airtime {myInfo.DeviceMetrics.AirUtilTx:N2}%" : String.Empty;

var byNodeChart = new BreakdownChart()
.FullSize();
Expand Down
24 changes: 12 additions & 12 deletions Meshtastic.Cli/Meshtastic.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Meshtastic.Cli</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand Down Expand Up @@ -34,20 +34,20 @@


<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.22.3" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.22.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="MQTTnet" Version="4.2.1.781" />
<PackageReference Include="Google.Protobuf" Version="3.25.3" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.25.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="QRCoder" Version="1.4.3" />
<PackageReference Include="SimpleExec" Version="11.0.0" />
<PackageReference Include="Spectre.Console" Version="0.46.0" />
<PackageReference Include="SimpleExec" Version="12.0.0" />
<PackageReference Include="Spectre.Console" Version="0.48.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
<PackageReference Include="YamlDotNet" Version="13.1.0" />
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
<PackageReference Include="YamlDotNet" Version="15.1.2" />
</ItemGroup>


Expand Down
4 changes: 2 additions & 2 deletions Meshtastic.Cli/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
},
"fixed-position": {
"commandName": "Project",
"commandLineArgs": "fixed-position 34.000 -90.023 123 --log debug"
"commandLineArgs": "fixed-position 34.000 -90.023 123 --log debug --port COM3"
},
"text": {
"commandName": "Project",
Expand Down Expand Up @@ -122,7 +122,7 @@
},
"live": {
"commandName": "Project",
"commandLineArgs": "live"
"commandLineArgs": "live --port COM3"
},
"live host": {
"commandName": "Project",
Expand Down
14 changes: 7 additions & 7 deletions Meshtastic.Test/Meshtastic.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -15,17 +15,17 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="ILogger.Moq" Version="1.1.10" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<PackageReference Include="coverlet.collector" Version="6.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
25 changes: 15 additions & 10 deletions Meshtastic/Connections/DeviceConnection.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
using Meshtastic.Data;
using Meshtastic.Data.MessageFactories;
using Meshtastic.Extensions;
using Meshtastic.Protobufs;
using Microsoft.Extensions.Logging;

namespace Meshtastic.Connections;

public abstract class DeviceConnection
public abstract class DeviceConnection(ILogger logger)
{
protected ILogger Logger { get; set; }
protected ILogger Logger { get; set; } = logger;
public ToRadioMessageFactory ToRadioFactory { get; private set; } = new ToRadioMessageFactory();
public DeviceStateContainer DeviceStateContainer { get; set; } = new DeviceStateContainer();
protected List<byte> Buffer { get; set; } = new List<byte>();
protected List<byte> Buffer { get; set; } = [];
protected int PacketLength { get; set; }

public DeviceConnection(ILogger logger)
public DeviceConnection(ILogger logger, DeviceStateContainer container) : this(logger)
{
Logger = logger;
}

public DeviceConnection(ILogger logger, DeviceStateContainer container)
{
Logger = logger;
DeviceStateContainer = container;
}

Expand Down Expand Up @@ -64,6 +60,13 @@ protected async Task<bool> ParsePackets(byte item, Func<FromRadio, DeviceStateCo
{
DeviceStateContainer.AddFromRadio(fromRadio);
Logger.LogDebug($"Received: {fromRadio}");
// Use telemetry packets as a cue to keep the connection alive
if (fromRadio.GetPayload<Telemetry>() != null)
{
Logger.LogDebug($"Sending heartbeat");
await WriteToRadio(ToRadioFactory.CreateKeepAliveMessage());
}

if (await isComplete(fromRadio, DeviceStateContainer))
{
Buffer.Clear();
Expand Down Expand Up @@ -91,6 +94,8 @@ protected void VerboseLogPacket(ToRadio toRadio)
toRadio.GetPayload<Telemetry>()?.ToString() ??
toRadio.GetPayload<Routing>()?.ToString() ??
toRadio.GetPayload<RouteDiscovery>()?.ToString() ??
toRadio.GetPayload<TAKPacket>()?.ToString() ??
toRadio.GetPayload<Neighbor>()?.ToString() ??
toRadio.GetPayload<string>()?.ToString();

if (!String.IsNullOrWhiteSpace(payload))
Expand Down
10 changes: 10 additions & 0 deletions Meshtastic/Data/MessageFactories/AdminMessageFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,14 @@ public MeshPacket CreateSetOwnerMessage(User user)
{
return GetNewMeshPacket(new AdminMessage() { SetOwner = user });
}

public MeshPacket CreateFixedPositionMessage(Position position)
{
return GetNewMeshPacket(new AdminMessage() { SetFixedPosition = position });
}

public MeshPacket RemovedFixedPositionMessage()
{
return GetNewMeshPacket(new AdminMessage() { RemoveFixedPosition = true });
}
}
7 changes: 7 additions & 0 deletions Meshtastic/Data/MessageFactories/ToRadioMessageFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ public ToRadioMessageFactory()
{
}

// Create a ToRadio message with a empty payload
public ToRadio CreateKeepAliveMessage() =>
new()
{
Heartbeat = new Heartbeat()
};

public ToRadio CreateWantConfigMessage() =>
new()
{
Expand Down
Loading

0 comments on commit 44c8325

Please sign in to comment.