Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion GpioController/Commands/GpioSetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,24 @@ protected override void RunOptionalPostCommandLogic(GpioSetRequest request, Gpio
{
if (request.Options == null) return;

var originalState = request.State;

var sleepTime = request.Options?.Milliseconds ?? 0;

for (var timesRepeated = 1; timesRepeated < request.Options?.RepeatTimes * 2; timesRepeated++)
{
Thread.Sleep(sleepTime);

if (request.CancellationToken.IsCancellationRequested)
break;
{
request.State = originalState;
break;
}

RunOpposite(request);
}

request.State = originalState;
}

private void RunOpposite(GpioSetRequest request)
Expand Down
1 change: 1 addition & 0 deletions GpioController/Services/ITokenManagementService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public interface ITokenManagementService
{
public void CancelAll();
public CancellationToken CreateToken(GpioSetRequest request);
public void RemoveCompletedTask(GpioSetRequest request);
}
40 changes: 27 additions & 13 deletions GpioController/Services/StateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@

namespace GpioController.Services;

public class StateService(ICommandFactory commandFactory, IGpioService gpioService, ITokenManagementService tokenManagementService) : IStateService
public class StateService : IStateService
{
private readonly ICommandFactory commandFactory;
private readonly IGpioService gpioService;
private readonly ITokenManagementService tokenManagementService;

public Action<IEnumerable<GpioSetRequest>> ValidateUpdateMultipleStates;

public StateService(ICommandFactory commandFactory, IGpioService gpioService, ITokenManagementService tokenManagementService)
{
this.commandFactory = commandFactory;
this.gpioService = gpioService;
this.tokenManagementService = tokenManagementService;

ValidateUpdateMultipleStates = ValidateUpdateRequests;
}

public GpioReadResult GetStateByGpioId(int chipsetId, int gpioId)
{
gpioService.GetGpioById(chipsetId, gpioId);
Expand All @@ -22,29 +37,28 @@ public GpioReadResult GetStateByGpioId(int chipsetId, int gpioId)

return result;
}

public void UpdateSingleState(GpioSetRequest request)
{
gpioService.GetGpioById(request.Chipset, request.Gpios.First());

request.CancellationToken = tokenManagementService.CreateToken(request);
var command = commandFactory.GetCommand<GpioSetRequest, GpioSetResult>();
command.Execute(request);
}

public void UpdateMultipleStates(IEnumerable<GpioSetRequest> updateRequests)
{
ValidateUpdateRequests(updateRequests);
ValidateUpdateMultipleStates(updateRequests);

new Action(() =>
{
foreach (var request in updateRequests)
{
{
request.CancellationToken = tokenManagementService.CreateToken(request);
var command = commandFactory.GetCommand<GpioSetRequest, GpioSetResult>();
command.Execute(request);
if (request.CancellationToken.IsCancellationRequested)
break;
tokenManagementService.RemoveCompletedTask(request);
}
}).StartOnBackgroundThread();
}
Expand All @@ -68,11 +82,11 @@ private void ValidateRequest(IEnumerable<int> gpioIdsToValidate, int chipsetId,
private void ValidateIndividualGpio(int chipsetId, int gpioId, string state)
{
var gpios = gpioService.GetGpios();
if(!gpios.Chipset(chipsetId).HasGpio(gpioId))

if (!gpios.Chipset(chipsetId).HasGpio(gpioId))
throw new NoGpiosFoundOnChipsetException(gpioId, chipsetId);
if(!State.CanParse(state))

if (!State.CanParse(state))
throw new InvalidStateException(state);
}
}
}
8 changes: 8 additions & 0 deletions GpioController/Services/TokenManagementService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public CancellationToken CreateToken(GpioSetRequest request)
return cts.Token;
}

public void RemoveCompletedTask(GpioSetRequest request)
{
lock (lockingMechanism)
{
activeTokenSources.RemoveAll(activeTask => activeTask.ActiveRequest == request );
}
}

public void CancelAll()
{
lock (lockingMechanism)
Expand Down
62 changes: 62 additions & 0 deletions GpioControllerTests/Services/IntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Text.Json;
using FakeItEasy;
using FluentAssertions;
using GpioController.Commands;
using GpioController.Commands.Request;
using GpioController.Commands.Results;
using GpioController.Factories;
using GpioController.Parsers;
using GpioController.Services;
using Microsoft.Extensions.Logging;

namespace GpioControllerTests.Services;

public class IntegrationTests
{
[Fact]
public void UpdateMultipleStateionTestShouldShowCorrectPinsTurnOff()
{

var commandFactory = A.Fake<ICommandFactory>();
var gpioService = A.Fake<IGpioService>();
var logger = A.Fake<ILogger<TokenManagementService>>();
var tokenManagementService = new TokenManagementService(commandFactory, logger);
var stateService = new StateService(commandFactory, gpioService, tokenManagementService);
var parser = A.Fake<IParser<GpioSetResult>>();
var terminalService = A.Fake<ITerminalService>();

var json = """
[
{"Gpios":[91,92,81],"Chipset":1,"State":"Low","Options":{"Milliseconds":1000,"RepeatTimes":1}},
{"Gpios":[91,92,95],"Chipset":1,"State":"Low","Options":{"Milliseconds":1000,"RepeatTimes":1}},
{"Gpios":[91,92,80],"Chipset":1,"State":"Low","Options":{"Milliseconds":1000,"RepeatTimes":1}}
]
""";

var requests = JsonSerializer.Deserialize<List<GpioSetRequest>>(json);

stateService.ValidateUpdateMultipleStates = (requests) => { };

var command = new GpioSetCommand(parser, terminalService);
A.CallTo(() => commandFactory.GetCommand<GpioSetRequest, GpioSetResult>()).ReturnsLazily(() => command);

stateService.UpdateMultipleStates(requests);

Thread.Sleep(2500);

tokenManagementService.CancelAll();

var allTerminalCalls = Fake.GetCalls(terminalService)
.Where(call => call.Method.Name == nameof(terminalService.RunCommand))
.Select(call => call.Arguments[0] as string)
.ToList();

allTerminalCalls[0].Should().Be("gpioset 1 91=0;gpioset 1 92=0;gpioset 1 81=0");
allTerminalCalls[1].Should().Be("gpioset 1 91=1;gpioset 1 92=1;gpioset 1 81=1");
allTerminalCalls[2].Should().Be("gpioset 1 91=0;gpioset 1 92=0;gpioset 1 95=0");
allTerminalCalls[3].Should().Be("gpioset 1 91=1;gpioset 1 92=1;gpioset 1 95=1");
allTerminalCalls[4].Should().Be("gpioset 1 91=0;gpioset 1 92=0;gpioset 1 80=0");
allTerminalCalls[5].Should().Be("gpioset 1 91=1;gpioset 1 92=1;gpioset 1 80=1");
}

}
Binary file modified Installation/linux-arm64/pinpanda-api-1.4.deb
Binary file not shown.
Binary file modified Installation/linux-x64/pinpanda-api-1.4.deb
Binary file not shown.
Loading