From 676784c089586ffee022b8c8a41157c3a45422b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Wed, 21 Feb 2024 19:14:53 +0100 Subject: [PATCH 1/2] fix(TeslaFleetApiSerice): can get token from backend again --- .../Resources/PossibleIssues/PossibleIssues.cs | 2 +- .../Scheduling/Jobs/FleetApiTokenRefreshJob.cs | 1 + .../Services/Contracts/ITeslaFleetApiService.cs | 2 ++ .../Server/Services/TeslaFleetApiService.cs | 16 +++++++++------- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs b/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs index 42f94acef..9787b89d1 100644 --- a/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs +++ b/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs @@ -164,7 +164,7 @@ public PossibleIssues(IssueKeys issueKeys) issueKeys.FleetApiTokenRequestExpired, CreateIssue("The Tesla token could not be received.", IssueType.Error, "Open the Base Configuration and request a new token.", - "If this issue keeps occuring, feel free to open an issue on Github including the last 5 chars of your installation ID (bottom of the page). Do NOT include the whole ID." + "If this issue keeps occuring, feel free to open an issue on Github including the first 10 chars of your installation ID (bottom of the page). Do NOT include the whole ID." ) }, { diff --git a/TeslaSolarCharger/Server/Scheduling/Jobs/FleetApiTokenRefreshJob.cs b/TeslaSolarCharger/Server/Scheduling/Jobs/FleetApiTokenRefreshJob.cs index 35bd5cead..d1bc0a18e 100644 --- a/TeslaSolarCharger/Server/Scheduling/Jobs/FleetApiTokenRefreshJob.cs +++ b/TeslaSolarCharger/Server/Scheduling/Jobs/FleetApiTokenRefreshJob.cs @@ -11,6 +11,7 @@ public class FleetApiTokenRefreshJob(ILogger logger, public async Task Execute(IJobExecutionContext context) { logger.LogTrace("{method}({context})", nameof(Execute), context); + await service.RefreshFleetApiRequestsAreAllowed().ConfigureAwait(false); await service.GetNewTokenFromBackend().ConfigureAwait(false); await service.RefreshTokensIfAllowedAndNeeded().ConfigureAwait(false); } diff --git a/TeslaSolarCharger/Server/Services/Contracts/ITeslaFleetApiService.cs b/TeslaSolarCharger/Server/Services/Contracts/ITeslaFleetApiService.cs index 72d3d649d..3097349c9 100644 --- a/TeslaSolarCharger/Server/Services/Contracts/ITeslaFleetApiService.cs +++ b/TeslaSolarCharger/Server/Services/Contracts/ITeslaFleetApiService.cs @@ -16,4 +16,6 @@ public interface ITeslaFleetApiService Task IsFleetApiProxyNeededInDatabase(); Task RefreshCarData(); Task RefreshTokensIfAllowedAndNeeded(); + Task RefreshFleetApiRequestsAreAllowed(); + } diff --git a/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs b/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs index 3314d7a52..06cfddeb8 100644 --- a/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs +++ b/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs @@ -14,6 +14,7 @@ using TeslaSolarCharger.Shared.Contracts; using TeslaSolarCharger.Shared.Dtos; using TeslaSolarCharger.Shared.Dtos.Contracts; +using TeslaSolarCharger.Shared.Dtos.Settings; using TeslaSolarCharger.Shared.Enums; using TeslaSolarCharger.SharedBackend.Contracts; using TeslaSolarCharger.SharedBackend.Dtos; @@ -578,7 +579,7 @@ public async Task GetNewTokenFromBackend() logger.LogError("Token has not been requested. Fleet API currently not working"); return; } - if (tokenRequestedDate < dateTimeProvider.UtcNow().Add(TimeSpan.MaxValue)) + if (tokenRequestedDate < dateTimeProvider.UtcNow().Subtract(constants.MaxTokenRequestWaitTime)) { logger.LogError("Last token request is too old. Request a new token."); return; @@ -605,7 +606,6 @@ public async Task GetNewTokenFromBackend() public async Task RefreshTokensIfAllowedAndNeeded() { logger.LogTrace("{method}()", nameof(RefreshTokensIfAllowedAndNeeded)); - settings.AllowUnlimitedFleetApiRequests = await CheckIfFleetApiRequestsAreAllowed().ConfigureAwait(false); var tokens = await teslaSolarChargerContext.TeslaTokens.ToListAsync().ConfigureAwait(false); if (tokens.Count < 1) { @@ -661,11 +661,12 @@ await backendApiService.PostErrorInformation(nameof(TeslaFleetApiService), nameo } } - private async Task CheckIfFleetApiRequestsAreAllowed() + public async Task RefreshFleetApiRequestsAreAllowed() { + logger.LogTrace("{method}()", nameof(RefreshFleetApiRequestsAreAllowed)); if (settings.AllowUnlimitedFleetApiRequests && (settings.LastFleetApiRequestAllowedCheck > dateTimeProvider.UtcNow().AddHours(-1))) { - return true; + return; } settings.LastFleetApiRequestAllowedCheck = dateTimeProvider.UtcNow(); using var httpClient = new HttpClient(); @@ -678,15 +679,16 @@ private async Task CheckIfFleetApiRequestsAreAllowed() var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); if (!response.IsSuccessStatusCode) { - return true; + settings.AllowUnlimitedFleetApiRequests = true; + return; } var responseValue = JsonConvert.DeserializeObject>(responseString); - return responseValue?.Value != false; + settings.AllowUnlimitedFleetApiRequests = responseValue?.Value != false; } catch (Exception) { - return true; + settings.AllowUnlimitedFleetApiRequests = true; } } From c7ad55efbf0a00c246c4a8fc7c7d9de8a6d1d580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Wed, 21 Feb 2024 19:42:16 +0100 Subject: [PATCH 2/2] feat(TeslaFleetApiService): allow token refresh more often than token usage if unauthorized --- TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs b/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs index 06cfddeb8..99a0374db 100644 --- a/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs +++ b/TeslaSolarCharger/Server/Services/TeslaFleetApiService.cs @@ -624,9 +624,17 @@ public async Task RefreshTokensIfAllowedAndNeeded() logger.LogError("Due to rate limitations fleet api requests are not allowed. As this version can not handle rate limits try updating to the latest version."); return; } + foreach (var tokenToRefresh in tokensToRefresh) { logger.LogWarning("Token {tokenId} needs to be refreshed as it expires on {expirationDateTime}", tokenToRefresh.Id, tokenToRefresh.ExpiresAtUtc); + + //DO NOTE REMOVE *2: As normal requests could result in reaching max unauthorized count, the max value is higher here, so even if token is unauthorized, refreshing it is still tried a couple of times. + if (tokenToRefresh.UnauthorizedCounter > (constants.MaxTokenUnauthorizedCount * 2)) + { + logger.LogError("Token {tokenId} has been unauthorized too often. Do not refresh token.", tokenToRefresh.Id); + continue; + } using var httpClient = new HttpClient(); var tokenUrl = "https://auth.tesla.com/oauth2/v3/token"; var requestData = new Dictionary