-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a74248c
commit 7960d4b
Showing
9 changed files
with
264 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
Meshtastic.Cli/CommandHandlers/SendWaypointCommandHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(), | ||
}, | ||
}; | ||
} | ||
} |
Oops, something went wrong.