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
3 changes: 2 additions & 1 deletion GpioController/Controllers/GpioController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
return Unauthorized();

var gpios = gpioService.GetGpios();
var filteredResults = gpioService.OrderResultsByFilter(gpios);
var mappedResults = gpioService.MapGpioNames(gpios);
var filteredResults = gpioService.OrderResultsByFilter(mappedResults);

Check warning on line 23 in GpioController/Controllers/GpioController.cs

View workflow job for this annotation

GitHub Actions / build

Argument of type 'IEnumerable<Gpio?>' cannot be used for parameter 'results' of type 'IEnumerable<Gpio>' in 'IEnumerable<Gpio?> IGpioService.OrderResultsByFilter(IEnumerable<Gpio> results)' due to differences in the nullability of reference types.

return Ok(filteredResults);
}
Expand Down
2 changes: 1 addition & 1 deletion GpioController/Models/AuthorizationSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ namespace GpioController.Models;
public class AuthorizationSettings
{
public required bool Enabled { get; set; }
public required List<string> AuthorizedEmails { get; set; }
public required List<string> AuthorizedEmails { get; set; } = new();
}
10 changes: 2 additions & 8 deletions GpioController/Models/FilterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ namespace GpioController.Models;

public class FilterSettings
{
public FilterSettings()
{
AllowOnlyTheseChipsets = new();
AllowOnlyTheseGpios = new();
}

public List<int> AllowOnlyTheseChipsets { get; set; }
public List<int> AllowOnlyTheseGpios { get; set; }
public List<int> AllowOnlyTheseChipsets { get; set; } = new();
public List<int> AllowOnlyTheseGpios { get; set; } = new();
}
12 changes: 12 additions & 0 deletions GpioController/Models/MappingSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace GpioController.Models;

public class MappingSettings
{
public List<Map> GpioNames { get; set; } = new();
}

public class Map
{
public int Id { get; set; }
public required string Name { get; set; }
}
4 changes: 4 additions & 0 deletions GpioController/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public static void Main(string[] args)
builder.Configuration.GetSection("Filters")
);

builder.Services.Configure<MappingSettings>(
builder.Configuration.GetSection("Mappings")
);

var requireAuth = builder.Configuration.GetValue<bool>("Authorization:Enabled");

if (requireAuth)
Expand Down
19 changes: 18 additions & 1 deletion GpioController/Services/GpioService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace GpioController.Services;

public class GpioService(ICommandFactory commandFactory, IOptions<FilterSettings> filterSettings) : IGpioService
public class GpioService(ICommandFactory commandFactory, IOptions<FilterSettings> filterSettings, IOptions<MappingSettings> mappingSettings) : IGpioService
{
public IEnumerable<Gpio> GetGpios()
{
Expand All @@ -28,6 +28,23 @@ public IEnumerable<Gpio> GetGpios()
return results;
}

public IEnumerable<Gpio?> MapGpioNames(IEnumerable<Gpio> results)
{
var nameMap = mappingSettings?.Value?.GpioNames ?? [];

if (!results.Any() || !nameMap.Any()) return results;

var mapById = nameMap.ToDictionary(m => m.Id, m => m.Name);

foreach (var gpio in results)
{
if (mapById.TryGetValue(gpio.Id, out var customMappedName))
gpio.Name = customMappedName;
}

return results;
}

public IEnumerable<Gpio?> OrderResultsByFilter(IEnumerable<Gpio> results)
{
var filter = filterSettings?.Value?.AllowOnlyTheseGpios ?? [];
Expand Down
1 change: 1 addition & 0 deletions GpioController/Services/IGpioService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public interface IGpioService
{
IEnumerable<Gpio> GetGpios();
Gpio GetGpioById(int chipsetId, int gpioId);
IEnumerable<Gpio?> MapGpioNames(IEnumerable<Gpio> results);
IEnumerable<Gpio?> OrderResultsByFilter(IEnumerable<Gpio> results);
}
3 changes: 3 additions & 0 deletions GpioController/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"AllowOnlyTheseChipsets": [],
"AllowOnlyTheseGpios": []
},
"Mappings":{
"GpioNames":[]
},
"Logging": {
"LogLevel": {
"Default": "Information",
Expand Down
94 changes: 93 additions & 1 deletion GpioControllerTests/Services/GpioServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
{
private ICommandFactory commandFactory;
private IOptions<FilterSettings> filterSettings;
private IOptions<MappingSettings> mappingSettings;
private ICommand<GpioInfoRequest, GpioInfoResult> command;

public GpioService GetSystemUnderTest()
{
command = A.Fake<ICommand<GpioInfoRequest, GpioInfoResult>>();
commandFactory = A.Fake<ICommandFactory>();
filterSettings = A.Fake<IOptions<FilterSettings>>();
mappingSettings = A.Fake<IOptions<MappingSettings>>();

return new GpioService(commandFactory, filterSettings);
return new GpioService(commandFactory, filterSettings, mappingSettings);
}

[Fact]
Expand Down Expand Up @@ -107,9 +109,9 @@

var result = sut.OrderResultsByFilter(data).ToArray();

result[0].Id.Should().Be(81);

Check warning on line 112 in GpioControllerTests/Services/GpioServiceTests.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
result[1].Id.Should().Be(95);

Check warning on line 113 in GpioControllerTests/Services/GpioServiceTests.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
result[2].Id.Should().Be(80);

Check warning on line 114 in GpioControllerTests/Services/GpioServiceTests.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

[Fact]
Expand Down Expand Up @@ -147,8 +149,98 @@

var result = sut.OrderResultsByFilter(data).ToArray();

result[0].Id.Should().Be(95);

Check warning on line 152 in GpioControllerTests/Services/GpioServiceTests.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
result[1].Id.Should().Be(80);
result[2].Id.Should().Be(81);
}

[Fact]
public void MapGpioNames_WhenCustomMapsAreDefined_MapsNamesCorrectly()
{
var sut = GetSystemUnderTest();

A.CallTo(() => mappingSettings.Value).Returns(new MappingSettings
{
GpioNames =
[
new Map
{
Id = 91,
Name = "VCC"
},
new Map
{
Id = 92,
Name = "Common"
},
new Map
{
Id = 81,
Name = "Zone 1"
}
]
});

var data = new List<Gpio>
{
new()
{
Chipset = 1,
Id = 91,
Name = "Gpio 91"
},
new()
{
Chipset = 1,
Id = 92,
Name = "Gpio 92"
},
new()
{
Chipset = 1,
Id = 81,
Name = "Gpio 81"
}
};

var result = sut.MapGpioNames(data).ToArray();

result[0].Name.Should().Be("VCC");
result[1].Name.Should().Be("Common");
result[2].Name.Should().Be("Zone 1");
}

[Fact]
public void MapGpioNames_WhenNoMapsAreDefined_DoesNotError()
{
var sut = GetSystemUnderTest();

A.CallTo(() => mappingSettings.Value).Returns(new MappingSettings());

var data = new List<Gpio>
{
new()
{
Chipset = 1,
Id = 91,
Name = "Gpio 91"
},
new()
{
Chipset = 1,
Id = 92,
Name = "Gpio 92"
},
new()
{
Chipset = 1,
Id = 81,
Name = "Gpio 81"
}
};

var result = sut.MapGpioNames(data).ToArray();

result.Should().BeEquivalentTo(data);
}
}
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.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,28 @@ To update your API settings, refer to the [AppSettings](https://github.com/Spark
- `Filters:AllowOnlyTheseGpios` - `GET /sbc/chipsets/gpios` will usually return all <b>GPIOs</b> from your board. Some projects only require a subset of these. Adding IDs here filters results.
- Example: `[91, 92, 81,95,80,79,94,93]`

### Mappings:

- `Mappings:GpioNames` - `GET /sbc/chipsets/gpios` will usually return the names assigned by the SBC. If you'd like to return custom names in their place, use this setting.
- Example: ```[
{
"Id": 91,
"Name": "VCC Power"
},
{
"Id": 92,
"Name": "Common"
},
{
"Id": 81,
"Name": "Zone 1"
},
{
"Id": 85,
"Name": "Zone 2"
}
]```


<b>Important!</b><br/>If you expose your IP and Port to the public (By adding a rule to your router / firewall) it is <b>highly recommended</b> to set `Authorization:Enabled` to `true`. Without it, anybody can call your API.
<br/>
Expand Down
Loading