chore: added smappee api

This commit is contained in:
Willem Serruys
2026-08-21 08:02:09 +02:00
parent 1d0a5beb8c
commit c87c09dde3
7 changed files with 67 additions and 25 deletions

View File

@@ -131,6 +131,25 @@ services:
# Only enable if external services present # Only enable if external services present
# ports: # ports:
# - 4317:4317 # OTLP gRPC receiver # - 4317:4317 # OTLP gRPC receiver
smappee-api:
build:
context: ./smappee-api
labels:
- traefik.http.routers.smappeeapi.rule=Host(`smappee.pladijs`)
- traefik.http.services.smappeeapi.loadbalancer.server.port=8080
environment:
ASPNETCORE_ENVIRONMENT: Production
env_file:
- environment-variables/local.env
- environment-variables/production.env
restart: unless-stopped
smappee-api:
build: ./smappee-api
env_file:
- .env.smappee
labels:
- traefik.http.routers.smappee.rule=Host(`smappee.pladijs`)
- traefik.http.services.smappee.loadbalancer.server.port=8080
energy-management: energy-management:
build: build:
context: ./energy-management context: ./energy-management

17
smappee-api/Dockerfile Normal file
View File

@@ -0,0 +1,17 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY smappee-api.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
COPY --from=build /app .
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "smappee-api.dll"]

View File

@@ -31,12 +31,11 @@ app.MapPost(
app.MapPost( app.MapPost(
"/disable", "/disable",
() => async (IChargerService chargerService) =>
async (IChargerService chargerService) => {
{ await chargerService.ExecuteRequest(ChargerRequests.Disable);
await chargerService.ExecuteRequest(ChargerRequests.Disable); return;
return; }
}
) )
.WithName("Disable"); .WithName("Disable");

View File

@@ -3,6 +3,9 @@
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Information" "Microsoft.AspNetCore": "Information"
},
"Console": {
"FormatterName": "json"
} }
}, },
"CHARGER": { "CHARGER": {
@@ -17,8 +20,11 @@
"HttpClientLogging": { "HttpClientLogging": {
"LogRequestStart": false, "LogRequestStart": false,
"LogBody": true, "LogBody": true,
"LogContentHeaders": true,
"BodySizeLimit": 32768, "BodySizeLimit": 32768,
"BodyReadTimeout": "00:00:01", "BodyReadTimeout": "00:00:01",
"RequestBodyContentTypes": [ "application/json", "application/x-www-form-urlencoded" ],
"ResponseBodyContentTypes": [ "application/json" ],
"RequestHeadersDataClasses": { "RequestHeadersDataClasses": {
"User-Agent": "None", "User-Agent": "None",
"Content-Type": "None" "Content-Type": "None"
@@ -26,7 +32,6 @@
"ResponseHeadersDataClasses": { "ResponseHeadersDataClasses": {
"Content-Type": "None" "Content-Type": "None"
}, },
"RequestPathLoggingMode": "Formatted", "RequestPathParameterRedactionMode": "None"
"RequestPathParameterRedactionMode": "Strict"
} }
} }

View File

@@ -0,0 +1,7 @@
services:
smappee-api:
build: .
ports:
- "5057:8080"
env_file:
- .env

View File

@@ -33,11 +33,11 @@ internal class SmappeeChargerService : IChargerService
var response = request switch var response = request switch
{ {
ChargerRequests.Enable => await httpClient.PutAsJsonAsync<SmappeeRequestBody>( ChargerRequests.Enable => await httpClient.PutAsJsonAsync<SmappeeRequestBody>(
$"/dev/v3/chargingstations/${options.ChargingStation}/connectors/{options.Connector}/mode", $"/dev/v3/chargingstations/{options.ChargingStation}/connectors/{options.Connector}/mode",
new SmappeeRequestBody("NORMAL", new Limit("AMPERE", 6)) new SmappeeRequestBody("NORMAL", new Limit("AMPERE", 6))
), ),
ChargerRequests.Disable => await httpClient.PutAsJsonAsync( ChargerRequests.Disable => await httpClient.PutAsJsonAsync(
"/dev/v3/chargingstations", $"/dev/v3/chargingstations/{options.ChargingStation}/connectors/{options.Connector}/mode",
new SmappeeRequestBody("PAUSED", null) new SmappeeRequestBody("PAUSED", null)
), ),
_ => throw new NotImplementedException(), _ => throw new NotImplementedException(),

View File

@@ -39,14 +39,17 @@ internal class SmappeeTokenService : IBearerTokenService
var httpClient = httpClientFactory.CreateClient("smappeeTokenService"); var httpClient = httpClientFactory.CreateClient("smappeeTokenService");
httpClient.BaseAddress = options.Url; httpClient.BaseAddress = options.Url;
var result = await httpClient.PostAsJsonAsync<TokenRequestBody>( var result = await httpClient.PostAsync(
"/dev/v3/oauth2/token", "/dev/v3/oauth2/token",
new TokenRequestBody( new FormUrlEncodedContent(
"password", new Dictionary<string, string>
options.ClientId, {
options.ClientSecret, ["grant_type"] = "password",
options.UserName, ["client_id"] = options.ClientId,
options.Password ["client_secret"] = options.ClientSecret,
["username"] = options.UserName,
["password"] = options.Password,
}
) )
); );
result.EnsureSuccessStatusCode(); result.EnsureSuccessStatusCode();
@@ -59,14 +62,6 @@ internal class SmappeeTokenService : IBearerTokenService
); );
} }
record TokenRequestBody(
string grant_type,
string client_id,
string client_secret,
string username,
string password
);
record TokenResponse(string access_token, int expires_in); record TokenResponse(string access_token, int expires_in);
record TokenData(string Token, DateTime Expiration); record TokenData(string Token, DateTime Expiration);