Skip to content

Commit

Permalink
Waypoint command and serial fix
Browse files Browse the repository at this point in the history
  • Loading branch information
thebentern committed Jan 12, 2023
1 parent a74248c commit 7960d4b
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public FixedPositionCommandHandler(decimal latitude,
this.longitude = longitude;
this.altitude = altitude;
}

public async Task Handle()
{
var wantConfig = new ToRadioMessageFactory().CreateWantConfigMessage();
Expand Down
74 changes: 74 additions & 0 deletions Meshtastic.Cli/CommandHandlers/SendWaypointCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Meshtastic.Data;
using Meshtastic.Protobufs;
using Microsoft.Extensions.Logging;
using System.Text;

namespace Meshtastic.Cli.CommandHandlers;

public class SendWaypointCommandHandler : DeviceCommandHandler
{
private readonly decimal latitude;
private readonly decimal longitude;
private readonly string name;
private readonly string description;
private readonly string icon;
private readonly bool locked;
private readonly decimal divisor = new(1e-7);

public SendWaypointCommandHandler(decimal latitude,
decimal longitude,
string name,
string description,
string icon,
bool locked,
DeviceConnectionContext context,
CommandContext commandContext) : base(context, commandContext)
{
this.latitude = latitude;
this.longitude = longitude;
this.name = name;
this.description = description;
this.icon = icon;
this.locked = locked;
}

public async Task Handle()
{
var wantConfig = new ToRadioMessageFactory().CreateWantConfigMessage();
await Connection.WriteToRadio(wantConfig, CompleteOnConfigReceived);
}

public override async Task OnCompleted(FromDeviceMessage packet, DeviceStateContainer container)
{
var factory = new WaypointMessageFactory(container, Destination);

var message = factory.CreateWaypointPacket(new Waypoint()
{
Id = (uint)Math.Floor(Random.Shared.Next() * 1e9),
LatitudeI = latitude != 0 ? decimal.ToInt32(latitude / divisor) : 0,
LongitudeI = longitude != 0 ? decimal.ToInt32(longitude / divisor) : 0,
Icon = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(icon)),
Name = name,
Description = description ?? String.Empty,
Locked = locked,
});
Logger.LogInformation($"Sending waypoint to device...");
await Connection.WriteToRadio(ToRadioMessageFactory.CreateMeshPacketMessage(message),
(fromDevice, container) =>
{
if (fromDevice.ParsedMessage.fromRadio?.Packet?.Decoded.Portnum == PortNum.RoutingApp &&
fromDevice.ParsedMessage.fromRadio?.Packet?.Priority == MeshPacket.Types.Priority.Ack)
{
var routingResult = Routing.Parser.ParseFrom(fromDevice.ParsedMessage.fromRadio?.Packet.Decoded.Payload);
if (routingResult.ErrorReason == Routing.Types.Error.None)
Logger.LogInformation("Acknowledged");
else
Logger.LogInformation($"Message delivery failed due to reason: {routingResult.ErrorReason}");

return Task.FromResult(true);
}

return Task.FromResult(false);
});
}
}
67 changes: 67 additions & 0 deletions Meshtastic.Cli/Commands/SendWaypointCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Meshtastic.Cli.Binders;
using Meshtastic.Cli.CommandHandlers;
using Meshtastic.Cli.Enums;
using Microsoft.Extensions.Logging;
using Spectre.Console;
using System.Text;
using System.Text.RegularExpressions;

namespace Meshtastic.Cli.Commands;

public class SendWaypointCommand : Command
{
public SendWaypointCommand(string name, string description, Option<string> port, Option<string> host,
Option<OutputFormat> output, Option<LogLevel> log, Option<uint?> dest, Option<bool> selectDest) : base(name, description)
{
var latArg = new Argument<decimal>("lat", description: "Latitude of the node (decimal format)");
latArg.AddValidator(result =>
{
if (Math.Abs(result.GetValueForArgument(latArg)) > 90)
result.ErrorMessage = "Invalid latitude";
});
AddArgument(latArg);

var lonArg = new Argument<decimal>("lon", description: "Longitude of the waypoint (decimal format)");
lonArg.AddValidator(result =>
{
if (Math.Abs(result.GetValueForArgument(lonArg)) > 180)
result.ErrorMessage = "Invalid latitude";
});
AddArgument(lonArg);

var nameOption = new Option<string>("--name", description: "Name for the waypoint");
AddOption(nameOption);

var descriptionOption = new Option<string>("--description", description: "Description for the waypoint");
AddOption(descriptionOption);

var iconOption = new Option<string>("--icon", description: "Icon emoji for the waypoint");
iconOption.SetDefaultValue("📍");
iconOption.AddValidator(ctx =>
{
var emoji = ctx.GetValueOrDefault()?.ToString();
if (emoji == null)// || !Regex.IsMatch(emoji, EmojiRegexPattern))
{
ctx.ErrorMessage = "Must specifiy a valid emoji character for waypoint icon";
}
});
AddOption(iconOption);

var lockedOption = new Option<bool>("--locked", description: "Lock the waypoint from updates");
AddOption(lockedOption);

this.SetHandler(async (lat, lon, name, description, icon, locked, context, commandContext) =>
{
var handler = new SendWaypointCommandHandler(lat, lon, name, description, icon, locked, context, commandContext);
await handler.Handle();
},
latArg,
lonArg,
nameOption,
descriptionOption,
iconOption,
lockedOption,
new DeviceConnectionBinder(port, host),
new CommandContextBinder(log, output, dest, selectDest));
}
}
1 change: 1 addition & 0 deletions Meshtastic.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
root.AddCommand(new TraceRouteCommand("trace-route", "Trace the sequence of nodes routing to the destination", port, host, output, log, dest, selectDest));
root.AddCommand(new SetCannedMessagesCommand("set-canned-messages", "Set the collection of canned messages on the device", port, host, output, log, dest, selectDest));
root.AddCommand(new GetCannedMessagesCommand("get-canned-messages", "Get the collection of canned messages on the device", port, host, output, log, dest, selectDest));
root.AddCommand(new SendWaypointCommand("waypoint", "Send a waypoint from the device", port, host, output, log, dest, selectDest));

var parser = new CommandLineBuilder(root)
.UseExceptionHandler((ex, context) =>
Expand Down
4 changes: 4 additions & 0 deletions Meshtastic.Cli/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
"set-canned-messages": {
"commandName": "Project",
"commandLineArgs": "set-canned-messages \"I need an alpinist!|Call Me|Roger Roger|Keep Calm|On my way\" --log debug"
},
"waypoint": {
"commandName": "Project",
"commandLineArgs": "waypoint 34.000 -90.023 --name Turd --icon 💩 --log debug"
}
}
}
1 change: 1 addition & 0 deletions Meshtastic/Connections/SerialConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public override async Task WriteToRadio(ToRadio data, Func<FromDeviceMessage, De
serialPort.Open();
await serialPort.BaseStream.WriteAsync(PacketFraming.SERIAL_PREAMBLE, 0, PacketFraming.SERIAL_PREAMBLE.Length);
await serialPort.BaseStream.WriteAsync(toRadio, 0, toRadio.Length);
serialPort.RtsEnable = false;
Logger.LogDebug($"Sent: {data}");
await ReadFromRadio(isComplete);
}
Expand Down
33 changes: 33 additions & 0 deletions Meshtastic/Data/WaypointMessageFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Google.Protobuf;
using Meshtastic.Protobufs;

namespace Meshtastic.Data;

public class WaypointMessageFactory
{
private readonly DeviceStateContainer container;
private readonly uint? dest;

public WaypointMessageFactory(DeviceStateContainer container, uint? dest = null)
{
this.container = container;
this.dest = dest;
}

public MeshPacket CreateWaypointPacket(Waypoint waypoint, uint channel = 0)
{
return new MeshPacket()
{
Channel = channel,
WantAck = true,
To = dest ?? 0xffffffff, // Default to broadcast
Id = (uint)Math.Floor(Random.Shared.Next() * 1e9),
HopLimit = container.GetHopLimitOrDefault(),
Decoded = new Protobufs.Data()
{
Portnum = PortNum.WaypointApp,
Payload = waypoint.ToByteString(),
},
};
}
}
Loading

0 comments on commit 7960d4b

Please sign in to comment.