review consent / authorisation flow to be compatible with both MyElectricalData and Enedis

Signed-off-by: Laurent ARNAL <laurent@clae.net>
This commit is contained in:
Laurent ARNAL 2024-06-04 15:51:56 +02:00
parent fe75abe979
commit d1920f21db
8 changed files with 161 additions and 68 deletions

View File

@ -69,6 +69,7 @@ public class LinkyAuthServlet extends HttpServlet {
public LinkyAuthServlet(ApiBridgeHandler apiBridgeHandler, String indexTemplate) { public LinkyAuthServlet(ApiBridgeHandler apiBridgeHandler, String indexTemplate) {
this.indexTemplate = indexTemplate; this.indexTemplate = indexTemplate;
this.apiBridgeHandler = apiBridgeHandler;
} }
@Override @Override

View File

@ -106,18 +106,20 @@ public class LinkyBindingConstants {
// "r:locations:*", "w:locations:*", "x:locations:*", "r:scenes:*", "x:scenes:*", "r:rules:*", "w:rules:*", // "r:locations:*", "w:locations:*", "x:locations:*", "r:scenes:*", "x:scenes:*", "r:rules:*", "w:rules:*",
// "r:installedapps", "w:installedapps" // "r:installedapps", "w:installedapps"
// List of Linky services related urls, information
public static final String LINKY_MYELECTRICALDATA_ACCOUNT_URL = "https://www.myelectricaldata.fr/";
public static final String LINKY_MYELECTRICALDATA_AUTHORIZE_URL = LINKY_MYELECTRICALDATA_ACCOUNT_URL
+ "v1/oauth2/authorize";
public static final String LINKY_MYELECTRICALDATA_API_TOKEN_URL = LINKY_MYELECTRICALDATA_ACCOUNT_URL + "token";
public static final String ENEDIS_ACCOUNT_URL_PROD = "https://mon-compte-particulier.enedis.fr/"; public static final String ENEDIS_ACCOUNT_URL_PROD = "https://mon-compte-particulier.enedis.fr/";
public static final String ENEDIS_AUTHORIZE_URL_PROD = ENEDIS_ACCOUNT_URL_PROD + "dataconnect/v1/oauth2/authorize"; public static final String ENEDIS_AUTHORIZE_URL_PROD = ENEDIS_ACCOUNT_URL_PROD + "dataconnect/v1/oauth2/authorize";
public static final String ENEDIS_API_TOKEN_URL_PROD = ENEDIS_ACCOUNT_URL_PROD + "oauth2/v3/token"; public static final String ENEDIS_API_TOKEN_URL_PROD = ENEDIS_ACCOUNT_URL_PROD + "oauth2/v3/token";
public static final String ENEDIS_ACCOUNT_URL_PREPROD = "https://ext.prod-sandbox.api.enedis.fr/"; public static final String ENEDIS_ACCOUNT_URL_PREPROD = "https://ext.prod-sandbox.api.enedis.fr/";
public static final String ENEDIS_AUTHORIZE_URL_PREPROD = ENEDIS_ACCOUNT_URL_PREPROD public static final String ENEDIS_AUTHORIZE_URL_PREPROD = ENEDIS_ACCOUNT_URL_PROD
+ "dataconnect/v1/oauth2/authorize"; + "dataconnect/v1/oauth2/authorize";
public static final String ENEDIS_API_TOKEN_URL_PREPROD = ENEDIS_ACCOUNT_URL_PREPROD + "oauth2/v3/token"; public static final String ENEDIS_API_TOKEN_URL_PREPROD = ENEDIS_ACCOUNT_URL_PREPROD + "oauth2/v3/token";
// List of Linky services related urls, information
public static final String LINKY_MYELECTRICALDATA_ACCOUNT_URL = "https://www.myelectricaldata.fr/";
// public static final String LINKY_MYELECTRICALDATA_AUTHORIZE_URL = LINKY_MYELECTRICALDATA_ACCOUNT_URL
// + "v1/oauth2/authorize?usage_points_id=21454992660003&user_type=aa&person_id=-1";
public static final String LINKY_MYELECTRICALDATA_AUTHORIZE_URL = ENEDIS_AUTHORIZE_URL_PROD;
public static final String LINKY_MYELECTRICALDATA_API_TOKEN_URL = LINKY_MYELECTRICALDATA_ACCOUNT_URL
+ "v1/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=na&user_type=na&state=na&person_id=-1&usage_points_id=%s";
} }

View File

@ -43,6 +43,7 @@ import org.openhab.binding.linky.internal.dto.TempoResponse;
import org.openhab.binding.linky.internal.dto.UsagePoint; import org.openhab.binding.linky.internal.dto.UsagePoint;
import org.openhab.binding.linky.internal.dto.UsagePointDetails; import org.openhab.binding.linky.internal.dto.UsagePointDetails;
import org.openhab.binding.linky.internal.handler.ApiBridgeHandler; import org.openhab.binding.linky.internal.handler.ApiBridgeHandler;
import org.openhab.binding.linky.internal.handler.LinkyHandler;
import org.openhab.binding.linky.internal.handler.MyElectricalDataBridgeHandler; import org.openhab.binding.linky.internal.handler.MyElectricalDataBridgeHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -92,8 +93,12 @@ public class EnedisHttpApi {
disconnect(); disconnect();
} }
private String getData(String url) throws LinkyException { public String getData(LinkyHandler handler, String url) throws LinkyException {
return getData(apiBridgeHandler, url, httpClient, apiBridgeHandler.getToken()); return getData(apiBridgeHandler, url, httpClient, apiBridgeHandler.getToken(handler));
}
public String getData(String url) throws LinkyException {
return getData(apiBridgeHandler, url, httpClient, "");
} }
private static String getData(ApiBridgeHandler apiBridgeHandler, String url, HttpClient httpClient, String token) private static String getData(ApiBridgeHandler apiBridgeHandler, String url, HttpClient httpClient, String token)
@ -131,7 +136,7 @@ public class EnedisHttpApi {
} }
} }
public PrmInfo getPrmInfo(String prmId) throws LinkyException { public PrmInfo getPrmInfo(LinkyHandler handler, String prmId) throws LinkyException {
PrmInfo result = new PrmInfo(); PrmInfo result = new PrmInfo();
if (apiBridgeHandler instanceof MyElectricalDataBridgeHandler) { if (apiBridgeHandler instanceof MyElectricalDataBridgeHandler) {
@ -170,14 +175,14 @@ public class EnedisHttpApi {
result.customerId = "xxxxxxxxxx"; result.customerId = "xxxxxxxxxx";
} else { } else {
Customer customer = getCustomer(prmId); Customer customer = getCustomer(handler, prmId);
UsagePoint usagePoint = customer.usagePoints[0]; UsagePoint usagePoint = customer.usagePoints[0];
result.contractInfo = usagePoint.contracts; result.contractInfo = usagePoint.contracts;
result.usagePointInfo = usagePoint.usagePoint; result.usagePointInfo = usagePoint.usagePoint;
result.identityInfo = getIdentity(prmId); result.identityInfo = getIdentity(handler, prmId);
result.addressInfo = getAddress(prmId); result.addressInfo = getAddress(handler, prmId);
result.contactInfo = getContact(prmId); result.contactInfo = getContact(handler, prmId);
result.prmId = result.usagePointInfo.usagePointId; result.prmId = result.usagePointInfo.usagePointId;
result.customerId = customer.customerId; result.customerId = customer.customerId;
@ -190,12 +195,12 @@ public class EnedisHttpApi {
return apiUrl.formatted(prmId); return apiUrl.formatted(prmId);
} }
public Customer getCustomer(String prmId) throws LinkyException { public Customer getCustomer(LinkyHandler handler, String prmId) throws LinkyException {
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String contractUrl = apiBridgeHandler.getContractUrl(); String contractUrl = apiBridgeHandler.getContractUrl();
String data = getData(formatUrl(contractUrl, prmId)); String data = getData(handler, formatUrl(contractUrl, prmId));
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", contractUrl); throw new LinkyException("Requesting '%s' returned an empty response", contractUrl);
} }
@ -211,12 +216,12 @@ public class EnedisHttpApi {
} }
} }
public AddressInfo getAddress(String prmId) throws LinkyException { public AddressInfo getAddress(LinkyHandler handler, String prmId) throws LinkyException {
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String addressUrl = apiBridgeHandler.getAddressUrl(); String addressUrl = apiBridgeHandler.getAddressUrl();
String data = getData(formatUrl(addressUrl, prmId)); String data = getData(handler, formatUrl(addressUrl, prmId));
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", addressUrl); throw new LinkyException("Requesting '%s' returned an empty response", addressUrl);
} }
@ -232,12 +237,12 @@ public class EnedisHttpApi {
} }
} }
public IdentityInfo getIdentity(String prmId) throws LinkyException { public IdentityInfo getIdentity(LinkyHandler handler, String prmId) throws LinkyException {
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String identityUrl = apiBridgeHandler.getIdentityUrl(); String identityUrl = apiBridgeHandler.getIdentityUrl();
String data = getData(formatUrl(identityUrl, prmId)); String data = getData(handler, formatUrl(identityUrl, prmId));
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", identityUrl); throw new LinkyException("Requesting '%s' returned an empty response", identityUrl);
} }
@ -253,12 +258,12 @@ public class EnedisHttpApi {
} }
} }
public ContactInfo getContact(String prmId) throws LinkyException { public ContactInfo getContact(LinkyHandler handler, String prmId) throws LinkyException {
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String contactUrl = apiBridgeHandler.getContactUrl(); String contactUrl = apiBridgeHandler.getContactUrl();
String data = getData(formatUrl(contactUrl, prmId)); String data = getData(handler, formatUrl(contactUrl, prmId));
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", contactUrl); throw new LinkyException("Requesting '%s' returned an empty response", contactUrl);
@ -275,7 +280,8 @@ public class EnedisHttpApi {
} }
} }
private MeterReading getMeasures(String apiUrl, String prmId, LocalDate from, LocalDate to) throws LinkyException { private MeterReading getMeasures(LinkyHandler handler, String apiUrl, String prmId, LocalDate from, LocalDate to)
throws LinkyException {
String dtStart = from.format(API_DATE_FORMAT); String dtStart = from.format(API_DATE_FORMAT);
String dtEnd = to.format(API_DATE_FORMAT); String dtEnd = to.format(API_DATE_FORMAT);
@ -283,7 +289,7 @@ public class EnedisHttpApi {
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String data = getData(url); String data = getData(handler, url);
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", url); throw new LinkyException("Requesting '%s' returned an empty response", url);
} }
@ -300,20 +306,22 @@ public class EnedisHttpApi {
} }
} }
public MeterReading getEnergyData(String prmId, LocalDate from, LocalDate to) throws LinkyException { public MeterReading getEnergyData(LinkyHandler handler, String prmId, LocalDate from, LocalDate to)
return getMeasures(apiBridgeHandler.getDailyConsumptionUrl(), prmId, from, to); throws LinkyException {
return getMeasures(handler, apiBridgeHandler.getDailyConsumptionUrl(), prmId, from, to);
} }
public MeterReading getPowerData(String prmId, LocalDate from, LocalDate to) throws LinkyException { public MeterReading getPowerData(LinkyHandler handler, String prmId, LocalDate from, LocalDate to)
return getMeasures(apiBridgeHandler.getMaxPowerUrl(), prmId, from, to); throws LinkyException {
return getMeasures(handler, apiBridgeHandler.getMaxPowerUrl(), prmId, from, to);
} }
public String getTempoData() throws LinkyException { public String getTempoData(LinkyHandler handler) throws LinkyException {
String url = String.format(apiBridgeHandler.getTempoUrl(), "2024-01-01", "2024-01-31"); String url = String.format(apiBridgeHandler.getTempoUrl(), "2024-01-01", "2024-01-31");
if (!connected) { if (!connected) {
initialize(); initialize();
} }
String data = getData(url); String data = getData(handler, url);
if (data.isEmpty()) { if (data.isEmpty()) {
throw new LinkyException("Requesting '%s' returned an empty response", url); throw new LinkyException("Requesting '%s' returned an empty response", url);
} }
@ -334,5 +342,4 @@ public class EnedisHttpApi {
// return data; // return data;
} }
} }

View File

@ -82,7 +82,7 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
private @Nullable EnedisHttpApi enedisApi; private @Nullable EnedisHttpApi enedisApi;
private final Gson gson; private final Gson gson;
private OAuthClientService oAuthService; private OAuthClientService oAuthService;
private final ThingRegistry thingRegistry; protected final ThingRegistry thingRegistry;
private static @Nullable HttpServlet servlet; private static @Nullable HttpServlet servlet;
protected @Nullable LinkyConfiguration config; protected @Nullable LinkyConfiguration config;
@ -125,9 +125,19 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
config = getConfigAs(LinkyConfiguration.class); config = getConfigAs(LinkyConfiguration.class);
this.oAuthService = oAuthFactory.createOAuthClientService(LinkyBindingConstants.BINDING_ID, String tokenUrl = "";
LinkyBindingConstants.ENEDIS_API_TOKEN_URL_PREPROD, LinkyBindingConstants.ENEDIS_AUTHORIZE_URL_PREPROD, String authorizeUrl = "";
config.clientId, config.clientSecret, LinkyBindingConstants.LINKY_SCOPES, true); if (this instanceof MyElectricalDataBridgeHandler) {
tokenUrl = LinkyBindingConstants.LINKY_MYELECTRICALDATA_API_TOKEN_URL;
authorizeUrl = LinkyBindingConstants.LINKY_MYELECTRICALDATA_AUTHORIZE_URL;
} else if (this instanceof EnedisBridgeHandler) {
tokenUrl = LinkyBindingConstants.ENEDIS_API_TOKEN_URL_PREPROD;
authorizeUrl = LinkyBindingConstants.ENEDIS_AUTHORIZE_URL_PREPROD;
}
this.oAuthService = oAuthFactory.createOAuthClientService(LinkyBindingConstants.BINDING_ID, tokenUrl,
authorizeUrl, config.clientId, config.clientSecret, LinkyBindingConstants.LINKY_SCOPES, true);
registerServlet(); registerServlet();
@ -138,6 +148,10 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
return enedisApi; return enedisApi;
} }
public abstract String getClientId();
public abstract String getClientSecret();
@Override @Override
public void initialize() { public void initialize() {
logger.debug("Initializing Netatmo API bridge handler."); logger.debug("Initializing Netatmo API bridge handler.");
@ -260,21 +274,9 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
&& accessTokenResponse.getRefreshToken() != null; && accessTokenResponse.getRefreshToken() != null;
} }
public String getToken() throws LinkyException { public abstract String getToken(LinkyHandler handler) throws LinkyException;
AccessTokenResponse accesToken = getAccessTokenResponse(); protected @Nullable AccessTokenResponse getAccessTokenByClientCredentials() {
if (accesToken == null) {
accesToken = getAccessTokenByClientCredentials();
}
if (accesToken == null) {
throw new LinkyException("no token");
}
return "Bearer " + accesToken.getAccessToken();
}
private @Nullable AccessTokenResponse getAccessTokenByClientCredentials() {
try { try {
return oAuthService.getAccessTokenByClientCredentials(LinkyBindingConstants.LINKY_SCOPES); return oAuthService.getAccessTokenByClientCredentials(LinkyBindingConstants.LINKY_SCOPES);
} catch (OAuthException | IOException | OAuthResponseException | RuntimeException e) { } catch (OAuthException | IOException | OAuthResponseException | RuntimeException e) {
@ -283,7 +285,7 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
} }
} }
private @Nullable AccessTokenResponse getAccessTokenResponse() { protected @Nullable AccessTokenResponse getAccessTokenResponse() {
try { try {
return oAuthService.getAccessTokenResponse(); return oAuthService.getAccessTokenResponse();
} catch (OAuthException | IOException | OAuthResponseException | RuntimeException e) { } catch (OAuthException | IOException | OAuthResponseException | RuntimeException e) {
@ -293,8 +295,6 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
} }
public String formatAuthorizationUrl(String redirectUri) { public String formatAuthorizationUrl(String redirectUri) {
// Will work only in case of direct oAuth2 authentification to enedis
// this is not the case in v1 as we go trough MyElectricalData
try { try {
String uri = this.oAuthService.getAuthorizationUrl(redirectUri, LinkyBindingConstants.LINKY_SCOPES, String uri = this.oAuthService.getAuthorizationUrl(redirectUri, LinkyBindingConstants.LINKY_SCOPES,
LinkyBindingConstants.BINDING_ID); LinkyBindingConstants.BINDING_ID);
@ -337,5 +337,4 @@ public abstract class ApiBridgeHandler extends BaseBridgeHandler {
public abstract String getMaxPowerUrl(); public abstract String getMaxPowerUrl();
public abstract String getTempoUrl(); public abstract String getTempoUrl();
} }

View File

@ -13,6 +13,8 @@
package org.openhab.binding.linky.internal.handler; package org.openhab.binding.linky.internal.handler;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.linky.internal.LinkyException;
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
import org.openhab.core.auth.client.oauth2.OAuthFactory; import org.openhab.core.auth.client.oauth2.OAuthFactory;
import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
@ -47,10 +49,6 @@ public class EnedisBridgeHandler extends ApiBridgeHandler {
private static final String TEMPO_URL = BASE_URL + "rte/tempo/%s/%s"; private static final String TEMPO_URL = BASE_URL + "rte/tempo/%s/%s";
// private static final String TOKEN_URL = BASE_URL
// +
// "v1/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=na&user_type=na&state=na&person_id=-1&usage_points_id=%s";
public EnedisBridgeHandler(Bridge bridge, final @Reference HttpClientFactory httpClientFactory, public EnedisBridgeHandler(Bridge bridge, final @Reference HttpClientFactory httpClientFactory,
final @Reference OAuthFactory oAuthFactory, final @Reference HttpService httpService, final @Reference OAuthFactory oAuthFactory, final @Reference HttpService httpService,
final @Reference ThingRegistry thingRegistry, ComponentContext componentContext, Gson gson) { final @Reference ThingRegistry thingRegistry, ComponentContext componentContext, Gson gson) {
@ -62,6 +60,16 @@ public class EnedisBridgeHandler extends ApiBridgeHandler {
super.initialize(); super.initialize();
} }
@Override
public String getClientId() {
return config.clientId;
}
@Override
public String getClientSecret() {
return config.clientSecret;
}
@Override @Override
public void dispose() { public void dispose() {
logger.debug("Shutting down Netatmo API bridge handler."); logger.debug("Shutting down Netatmo API bridge handler.");
@ -69,6 +77,21 @@ public class EnedisBridgeHandler extends ApiBridgeHandler {
super.dispose(); super.dispose();
} }
@Override
public String getToken(LinkyHandler handler) throws LinkyException {
AccessTokenResponse accesToken = getAccessTokenResponse();
if (accesToken == null) {
accesToken = getAccessTokenByClientCredentials();
}
if (accesToken == null) {
throw new LinkyException("no token");
}
return "Bearer " + accesToken.getAccessToken();
}
@Override @Override
public String getBaseUrl() { public String getBaseUrl() {
return BASE_URL; return BASE_URL;

View File

@ -161,7 +161,7 @@ public class LinkyHandler extends BaseThingHandler {
LinkyConfiguration config = this.config; LinkyConfiguration config = this.config;
if (api != null && config != null) { if (api != null && config != null) {
PrmInfo prmInfo = api.getPrmInfo(config.prmId); PrmInfo prmInfo = api.getPrmInfo(this, config.prmId);
updateProperties(Map.of(USER_ID, prmInfo.customerId, PUISSANCE, updateProperties(Map.of(USER_ID, prmInfo.customerId, PUISSANCE,
prmInfo.contractInfo.subscribedPower, PRM_ID, prmInfo.prmId)); prmInfo.contractInfo.subscribedPower, PRM_ID, prmInfo.prmId));
@ -198,7 +198,7 @@ public class LinkyHandler extends BaseThingHandler {
if (api != null && config != null) { if (api != null && config != null) {
try { try {
PrmInfo info = api.getPrmInfo(config.prmId); PrmInfo info = api.getPrmInfo(this, config.prmId);
String title = info.identityInfo.title; String title = info.identityInfo.title;
String firstName = info.identityInfo.firstname; String firstName = info.identityInfo.firstname;
String lastName = info.identityInfo.lastname; String lastName = info.identityInfo.lastname;
@ -466,7 +466,7 @@ public class LinkyHandler extends BaseThingHandler {
EnedisHttpApi api = this.enedisApi; EnedisHttpApi api = this.enedisApi;
if (api != null) { if (api != null) {
try { try {
MeterReading meterReading = api.getEnergyData(config.prmId, from, to); MeterReading meterReading = api.getEnergyData(this, config.prmId, from, to);
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);
return meterReading; return meterReading;
} catch (LinkyException e) { } catch (LinkyException e) {
@ -484,7 +484,7 @@ public class LinkyHandler extends BaseThingHandler {
EnedisHttpApi api = this.enedisApi; EnedisHttpApi api = this.enedisApi;
if (api != null) { if (api != null) {
try { try {
MeterReading meterReading = api.getPowerData(config.prmId, from, to); MeterReading meterReading = api.getPowerData(this, config.prmId, from, to);
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);
return meterReading; return meterReading;
} catch (LinkyException e) { } catch (LinkyException e) {

View File

@ -12,11 +12,18 @@
*/ */
package org.openhab.binding.linky.internal.handler; package org.openhab.binding.linky.internal.handler;
import java.util.Collection;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.linky.internal.LinkyBindingConstants;
import org.openhab.binding.linky.internal.LinkyConfiguration;
import org.openhab.binding.linky.internal.LinkyException; import org.openhab.binding.linky.internal.LinkyException;
import org.openhab.binding.linky.internal.api.EnedisHttpApi;
import org.openhab.core.auth.client.oauth2.OAuthFactory; import org.openhab.core.auth.client.oauth2.OAuthFactory;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingRegistry; import org.openhab.core.thing.ThingRegistry;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.Reference;
@ -46,6 +53,8 @@ public class MyElectricalDataBridgeHandler extends ApiBridgeHandler {
private static final String TEMPO_URL = BASE_URL + "rte/tempo/%s/%s"; private static final String TEMPO_URL = BASE_URL + "rte/tempo/%s/%s";
// https://www.myelectricaldata.fr/v1/oauth2/authorize?response_type=code&client_id=&state=linky&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fconnectlinky&scope=am_application_scope+default&user_type=aa&person_id=-1&usage_points_id=aa
public MyElectricalDataBridgeHandler(Bridge bridge, final @Reference HttpClientFactory httpClientFactory, public MyElectricalDataBridgeHandler(Bridge bridge, final @Reference HttpClientFactory httpClientFactory,
final @Reference OAuthFactory oAuthFactory, final @Reference HttpService httpService, final @Reference OAuthFactory oAuthFactory, final @Reference HttpService httpService,
final @Reference ThingRegistry thingRegistry, ComponentContext componentContext, Gson gson) { final @Reference ThingRegistry thingRegistry, ComponentContext componentContext, Gson gson) {
@ -57,6 +66,54 @@ public class MyElectricalDataBridgeHandler extends ApiBridgeHandler {
super.initialize(); super.initialize();
} }
@Override
public String getClientId() {
return "e551937c-5250-48bc-b4a6-2323af68db92";
}
@Override
public String getClientSecret() {
return "";
}
@Override
public String formatAuthorizationUrl(String redirectUri) {
return super.formatAuthorizationUrl("");
}
@Override
public String authorize(String redirectUri, String reqState, String reqCode) throws LinkyException {
String url = String.format(LinkyBindingConstants.LINKY_MYELECTRICALDATA_API_TOKEN_URL, getClientId(), reqCode);
EnedisHttpApi enedisApi = getEnedisApi();
if (enedisApi == null) {
return "";
}
String token = enedisApi.getData(url);
logger.debug("token: {}", token);
Collection<Thing> col = this.thingRegistry.getAll();
for (Thing thing : col) {
if (LinkyBindingConstants.THING_TYPE_LINKY.equals(thing.getThingTypeUID())) {
Configuration config = thing.getConfiguration();
String prmId = (String) config.get("prmId");
if (!prmId.equals(reqCode)) {
continue;
}
config.put("token", token);
LinkyHandler handler = (LinkyHandler) thing.getHandler();
if (handler != null) {
handler.saveConfiguration(config);
}
}
}
return token;
}
@Override @Override
public void dispose() { public void dispose() {
logger.debug("Shutting down Netatmo API bridge handler."); logger.debug("Shutting down Netatmo API bridge handler.");
@ -65,7 +122,11 @@ public class MyElectricalDataBridgeHandler extends ApiBridgeHandler {
} }
@Override @Override
public String getToken() throws LinkyException { public String getToken(LinkyHandler handler) throws LinkyException {
LinkyConfiguration config = handler.getLinkyConfig();
if (config == null) {
return "";
}
return config.token; return config.token;
} }

View File

@ -26,7 +26,7 @@
</bridge-type> </bridge-type>
<bridge-type id="MyElectricalDataBridge"> <bridge-type id="MyElectricalDataBridge">
<label>EnedisBridge</label> <label>MyElectricalDataBridge</label>
<description> <description>
Provides your energy consumption data. Provides your energy consumption data.
In order to receive the data, you must activate your account at In order to receive the data, you must activate your account at
@ -34,11 +34,6 @@
</description> </description>
<config-description> <config-description>
<parameter name="token" type="text" required="false">
<label>Token</label>
<description>Your Enedis token (can be left empty, use the connection page to automatically fill it
http://youopenhab/connectlinky)</description>
</parameter>
</config-description> </config-description>
</bridge-type> </bridge-type>
@ -74,6 +69,11 @@
<label>PrmId</label> <label>PrmId</label>
<description>Your PrmId</description> <description>Your PrmId</description>
</parameter> </parameter>
<parameter name="token" type="text" required="false">
<label>Token</label>
<description>Your Enedis token (can be left empty, use the connection page to automatically fill it
http://youopenhab/connectlinky)</description>
</parameter>
</config-description> </config-description>