-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Initialise Command Controller (#50)
- Loading branch information
Showing
7 changed files
with
157 additions
and
776 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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,52 @@ | ||
using System.Text.Json.Serialization; | ||
using NodaTime; | ||
|
||
namespace Mortein.Types; | ||
|
||
|
||
public enum CommandType | ||
{ | ||
ToggleVibration, | ||
VibrateForDuration, | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Command for a device. | ||
/// </summary> | ||
[JsonDerivedType(typeof(ToggleVibrationCommand))] | ||
[JsonDerivedType(typeof(VibrateForDurationCommand))] | ||
public abstract class Command | ||
{ | ||
/// <summary> | ||
/// The unique identifier of a device. | ||
/// </summary> | ||
public required Guid DeviceId { get; set; } | ||
|
||
/// <summary> | ||
/// The timestamp for this command. | ||
/// </summary> | ||
public Instant Timestamp { get; set; } = SystemClock.Instance.GetCurrentInstant(); | ||
|
||
/// <summary> | ||
/// The type of command. | ||
/// </summary> | ||
public abstract CommandType Type { get; } | ||
} | ||
|
||
|
||
public class ToggleVibrationCommand : Command | ||
{ | ||
public override CommandType Type { get => CommandType.ToggleVibration; } | ||
} | ||
|
||
|
||
public class VibrateForDurationCommand : Command | ||
{ | ||
public override CommandType Type { get => CommandType.VibrateForDuration; } | ||
|
||
/// <summary> | ||
/// The duration for which to vibrate the device. | ||
/// </summary> | ||
public required int Seconds { get; set; } | ||
} |
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,99 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Mortein.Mqtt.Services; | ||
using Mortein.Types; | ||
using MQTTnet.Client; | ||
using NodaTime.Serialization.SystemTextJson; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Mortein.Controllers; | ||
|
||
|
||
/// <summary> | ||
/// API controller for device commands. | ||
/// </summary> | ||
/// | ||
/// <param name="context">The context which enables interaction with the database.</param> | ||
/// <param name="clientService">The service exposing the client which enables publishing to the MQTT client.</param> | ||
[ApiController] | ||
[Route("Device/{deviceId}/[controller]")] | ||
public class CommandController(DatabaseContext context, MqttClientService clientService) : ControllerBase | ||
{ | ||
/// The context which enables interaction with the database. | ||
private readonly DatabaseContext _context = context; | ||
|
||
/// The client which enables publishing to the MQTT client. | ||
private readonly IMqttClient _client = clientService.MqttClient; | ||
|
||
private static readonly JsonSerializerOptions jsonSerializerOptions = new() | ||
{ | ||
Converters = | ||
{ | ||
NodaConverters.InstantConverter, | ||
new JsonStringEnumConverter() | ||
} | ||
}; | ||
|
||
/// <summary> | ||
/// Publish a command to a device. | ||
/// </summary> | ||
/// | ||
/// <param name="deviceId">The device to which to publish a command.</param> | ||
/// <param name="command">The command to publish.</param> | ||
private async void PublishCommand(Guid deviceId, Command command) | ||
{ | ||
await _client.PublishStringAsync(ConstructTopicName(deviceId), JsonSerializer.Serialize(command, jsonSerializerOptions)); | ||
} | ||
|
||
/// <summary> | ||
/// Construct a topic name for a device | ||
/// </summary> | ||
/// <param name="deviceId">The device for which to construct a topic name.</param> | ||
/// <returns></returns> | ||
private static string ConstructTopicName(Guid deviceId) | ||
{ | ||
return deviceId.ToString(); | ||
} | ||
|
||
/// <summary> | ||
/// Toggle Device Vibration | ||
/// </summary> | ||
/// | ||
/// <remarks> | ||
/// Toggles the vibration of a device by ID. | ||
/// </remarks> | ||
/// | ||
/// <param name="deviceId">The device to vibrate.</param> | ||
[HttpPost("Toggle")] | ||
[ProducesResponseType(StatusCodes.Status204NoContent)] | ||
public IActionResult ToggleDeviceVibration(Guid deviceId) | ||
{ | ||
PublishCommand(deviceId, new ToggleVibrationCommand() | ||
{ | ||
DeviceId = deviceId, | ||
}); | ||
return NoContent(); | ||
} | ||
|
||
/// <summary> | ||
/// Vibrate Device for Duration | ||
/// </summary> | ||
/// | ||
/// <remarks> | ||
/// Vibrate a device by ID for a specified duration. | ||
/// </remarks> | ||
/// | ||
/// <param name="deviceId">The device to vibrate.</param> | ||
/// <param name="seconds">The duration of the vibration.</param> | ||
[HttpPost("VibrateForDuration")] | ||
[ProducesResponseType(StatusCodes.Status204NoContent)] | ||
public IActionResult VibrateDeviceForDuration(Guid deviceId, int seconds) | ||
{ | ||
PublishCommand(deviceId, new VibrateForDurationCommand() | ||
{ | ||
DeviceId = deviceId, | ||
Seconds = seconds, | ||
}); | ||
return NoContent(); | ||
} | ||
} |
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