Skip to content

Commit 4dfaef9

Browse files
authored
[mybmw] Fix charging statistics URL (openhab#18153)
* [mybmw] add stop charging command Signed-off-by: Martin Grassl <[email protected]>
1 parent e7acb14 commit 4dfaef9

File tree

4 files changed

+49
-26
lines changed

4 files changed

+49
-26
lines changed

bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/auth/MyBMWTokenController.java

+32-18
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.OCP_APIM_KEYS;
2626
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.REFRESH_TOKEN;
2727
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.REGION_CHINA;
28-
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.REGION_NORTH_AMERICA;
29-
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.REGION_ROW;
3028
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.USER_AGENT;
3129
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.X_USER_AGENT;
3230
import static org.openhab.binding.mybmw.internal.utils.HTTPConstants.AUTHORIZATION;
@@ -110,7 +108,7 @@ public MyBMWTokenController(MyBMWBridgeConfiguration configuration, HttpClient h
110108
this.httpClient = httpClient;
111109
}
112110

113-
public void setBridgeConfiguration(MyBMWBridgeConfiguration bridgeConfiguration) {
111+
public synchronized void setBridgeConfiguration(MyBMWBridgeConfiguration bridgeConfiguration) {
114112
this.bridgeConfiguration = bridgeConfiguration;
115113
}
116114

@@ -122,9 +120,22 @@ public void setBridgeConfiguration(MyBMWBridgeConfiguration bridgeConfiguration)
122120
*
123121
* @return token
124122
*/
125-
public Token getToken() {
126-
if (!bridgeConfiguration.getHcaptchatoken().isBlank()) {
123+
public synchronized Token getToken() {
124+
125+
logger.trace("getToken, current token {}", token.toString());
126+
127+
if (REGION_CHINA.equals(bridgeConfiguration.getRegion()) && !token.isValid()) {
128+
// in China no hcaptchatoken is required
129+
boolean tokenUpdateSuccess = false;
130+
tokenUpdateSuccess = getAndUpdateTokenChina();
131+
if (!tokenUpdateSuccess) {
132+
logger.warn("Authorization failed!");
133+
}
134+
} else if (!bridgeConfiguration.getHcaptchatoken().isBlank()) {
127135
// if the hcaptchastring is available, then a new login is triggered
136+
137+
logger.trace("initial login, using captchatoken {}", bridgeConfiguration.getHcaptchatoken());
138+
128139
boolean tokenCreationSuccess = getInitialToken();
129140

130141
if (!tokenCreationSuccess) {
@@ -138,22 +149,15 @@ public Token getToken() {
138149
} else if (!token.isValid() && !Constants.EMPTY.equals(token.getRefreshToken())) {
139150
// if the token is invalid, try to refresh the token
140151
boolean tokenUpdateSuccess = false;
141-
switch (bridgeConfiguration.getRegion()) {
142-
case REGION_CHINA:
143-
tokenUpdateSuccess = getAndUpdateTokenChina();
144-
break;
145-
case REGION_NORTH_AMERICA:
146-
case REGION_ROW:
147-
tokenUpdateSuccess = getUpdatedToken();
148-
break;
149-
default:
150-
logger.warn("Region {} not supported", bridgeConfiguration.getRegion());
151-
break;
152-
}
152+
tokenUpdateSuccess = getUpdatedToken();
153+
153154
if (!tokenUpdateSuccess) {
154155
logger.warn("Authorization failed!");
155156
}
156157
}
158+
159+
logger.trace("getToken, new token {}", token.toString());
160+
157161
return token;
158162
}
159163

@@ -166,6 +170,9 @@ public Token getToken() {
166170
* @return true if the token was successfully updated
167171
*/
168172
private synchronized boolean getInitialToken() {
173+
174+
logger.trace("get initial token");
175+
169176
try {
170177
/*
171178
* Step 1) Get basic values for further queries
@@ -254,6 +261,8 @@ private synchronized boolean getInitialToken() {
254261
AuthResponse ar = JsonStringDeserializer.deserializeString(codeResponse.getContentAsString(),
255262
AuthResponse.class);
256263

264+
logger.trace("Login response: {}", ar.toString());
265+
257266
token.setType(ar.tokenType);
258267
token.setToken(ar.accessToken);
259268
token.setExpiration(ar.expiresIn);
@@ -273,6 +282,9 @@ private synchronized boolean getInitialToken() {
273282
* @return true if token has successfully been refreshed
274283
*/
275284
private synchronized boolean getUpdatedToken() {
285+
286+
logger.trace("getUpdatedToken");
287+
276288
try {
277289
/*
278290
* Step 1) Get basic values for further queries
@@ -303,14 +315,16 @@ private synchronized boolean getUpdatedToken() {
303315
AuthResponse ar = JsonStringDeserializer.deserializeString(codeResponse.getContentAsString(),
304316
AuthResponse.class);
305317

318+
logger.trace("Refresh response: {}", ar.toString());
319+
306320
token.setToken(ar.accessToken);
307321
token.setExpiration(ar.expiresIn);
308322
token.setRefreshToken(ar.refreshToken);
309323
token.setGcid(ar.gcid);
310324

311325
return true;
312326
} catch (Exception e) {
313-
logger.warn("Refresh Exception: {}", e.getMessage());
327+
logger.warn("Refresh Exception: ", e);
314328
}
315329
return false;
316330
}

bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/auth/Token.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,20 @@ public void setGcid(String gcid) {
6767
this.gcid = gcid;
6868
}
6969

70+
/**
71+
* check if the token is valid - for enough buffer it is not valid if it expires in <10s
72+
*
73+
* @return
74+
*/
7075
public boolean isValid() {
7176
return (!token.equals(Constants.EMPTY) && !tokenType.equals(Constants.EMPTY)
72-
&& !refreshToken.equals(Constants.EMPTY) && (this.expiration - System.currentTimeMillis() / 1000) > 1);
77+
&& !refreshToken.equals(Constants.EMPTY) && (this.expiration - System.currentTimeMillis() / 1000) > 10);
7378
}
7479

7580
@Override
7681
public String toString() {
77-
return tokenType + Constants.COLON + token + Constants.COLON + isValid();
82+
return "Token [token=" + token + ", tokenType=" + tokenType + ", refreshToken=" + refreshToken + ", gcid="
83+
+ gcid + ", expiration=" + expiration + "] - is valid " + isValid() + ", will expire in s "
84+
+ (this.expiration - System.currentTimeMillis() / 1000);
7885
}
7986
}

bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/backend/MyBMWHttpProxy.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
*/
1313
package org.openhab.binding.mybmw.internal.handler.backend;
1414

15-
import static org.openhab.binding.mybmw.internal.utils.BimmerConstants.APP_VERSIONS;
16-
1715
import java.nio.charset.Charset;
1816
import java.nio.charset.StandardCharsets;
1917
import java.util.ArrayList;
@@ -178,7 +176,7 @@ public List<VehicleBase> requestVehiclesBase() throws NetworkException {
178176
*/
179177
public byte[] requestImage(String vin, String brand, ImageProperties props) throws NetworkException {
180178
final String localImageUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(bridgeConfiguration.getRegion())
181-
+ "/eadrax-ics/v3/presentation/vehicles/" + vin + "/images?carView=" + props.viewport;
179+
+ BimmerConstants.IMAGE_URL.replace(BimmerConstants.PARAM_VIN, vin) + props.viewport;
182180
return get(localImageUrl, brand, vin, HTTPConstants.CONTENT_TYPE_IMAGE);
183181
}
184182

@@ -232,7 +230,7 @@ public String requestChargeStatisticsJson(String vin, String brand) throws Netwo
232230
chargeStatisticsParams.put("currentDate", Converter.getCurrentISOTime());
233231
String params = UrlEncoded.encode(chargeStatisticsParams, StandardCharsets.UTF_8, false);
234232
String chargeStatisticsUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(bridgeConfiguration.getRegion())
235-
+ "/eadrax-chs/v1/charging-statistics?" + params;
233+
+ BimmerConstants.CHARGING_STATISTICS + params;
236234
byte[] chargeStatisticsResponse = get(chargeStatisticsUrl, brand, vin, HTTPConstants.CONTENT_TYPE_JSON);
237235
String chargeStatisticsResponseString = new String(chargeStatisticsResponse);
238236
return chargeStatisticsResponseString;
@@ -264,7 +262,7 @@ public String requestChargeSessionsJson(String vin, String brand) throws Network
264262
chargeSessionsParams.put("include_date_picker", "true");
265263
String params = UrlEncoded.encode(chargeSessionsParams, StandardCharsets.UTF_8, false);
266264
String chargeSessionsUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(bridgeConfiguration.getRegion())
267-
+ "/eadrax-chs/v1/charging-sessions?" + params;
265+
+ BimmerConstants.CHARGING_SESSIONS + params;
268266
byte[] chargeSessionsResponse = get(chargeSessionsUrl, brand, vin, HTTPConstants.CONTENT_TYPE_JSON);
269267
String chargeSessionsResponseString = new String(chargeSessionsResponse);
270268
return chargeSessionsResponseString;
@@ -369,7 +367,7 @@ private synchronized byte[] call(final String url, final boolean post, final Str
369367

370368
req.header(HttpHeader.AUTHORIZATION, myBMWTokenController.getToken().getBearerToken());
371369
req.header(HTTPConstants.HEADER_X_USER_AGENT, String.format(BimmerConstants.X_USER_AGENT, brand.toLowerCase(),
372-
APP_VERSIONS.get(bridgeConfiguration.getRegion()), bridgeConfiguration.getRegion()));
370+
BimmerConstants.APP_VERSIONS.get(bridgeConfiguration.getRegion()), bridgeConfiguration.getRegion()));
373371
req.header(HttpHeader.ACCEPT_LANGUAGE, bridgeConfiguration.getLanguage());
374372
req.header(HttpHeader.ACCEPT, contentType);
375373
req.header(HTTPConstants.HEADER_BMW_VIN, vin);

bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/utils/BimmerConstants.java

+4
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,8 @@ public interface BimmerConstants {
8282
static final String API_VEHICLES = "/eadrax-vcs/v4/vehicles";
8383
static final String API_REMOTE_SERVICE_BASE_URL = "/eadrax-vrccs/v3/presentation/remote-commands/"; // '/{vin}/{service_type}'
8484
static final String API_POI = "/eadrax-dcs/v1/send-to-car/send-to-car";
85+
static final String CHARGING_STATISTICS = "/eadrax-chs/v2/charging-statistics?";
86+
static final String CHARGING_SESSIONS = "/eadrax-chs/v2/charging-sessions?";
87+
static final String PARAM_VIN = "$vin$";
88+
static final String IMAGE_URL = "/eadrax-ics/v3/presentation/vehicles/" + PARAM_VIN + "/images?carView=";
8589
}

0 commit comments

Comments
 (0)