From 6e40ddfcf40a41313613958d550c3aa4a9729ac7 Mon Sep 17 00:00:00 2001
From: Laurent ARNAL
Date: Thu, 1 Feb 2024 18:54:21 +0100
Subject: [PATCH] some fixes on connectlinky page tempo day support, WIP
Signed-off-by: Laurent ARNAL
---
.../linky/internal/LinkyAccountHandler.java | 2 +
.../linky/internal/LinkyAuthServlet.java | 17 +-
.../linky/internal/LinkyBindingConstants.java | 2 +
.../linky/internal/LinkyHandlerFactory.java | 63 ++++--
.../linky/internal/api/EnedisHttpApi.java | 41 +++-
.../linky/internal/dto/TempoDayInfo.java | 27 +++
.../linky/internal/dto/TempoResponse.java | 28 +++
.../linky/internal/handler/LinkyHandler.java | 76 +++++++-
.../resources/OH-INF/thing/thing-types.xml | 24 +++
.../src/main/resources/templates/enedis.png | Bin 0 -> 1699 bytes
.../main/resources/templates/enedisSmall.png | Bin 0 -> 2241 bytes
.../src/main/resources/templates/index.html | 182 +++++++++++++++---
12 files changed, 400 insertions(+), 62 deletions(-)
create mode 100644 bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoDayInfo.java
create mode 100644 bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoResponse.java
create mode 100644 bundles/org.openhab.binding.linky/src/main/resources/templates/enedis.png
create mode 100644 bundles/org.openhab.binding.linky/src/main/resources/templates/enedisSmall.png
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAccountHandler.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAccountHandler.java
index 1cebc3e7b5e..17cfb65c510 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAccountHandler.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAccountHandler.java
@@ -42,4 +42,6 @@ public interface LinkyAccountHandler {
* @return the formatted url that should be used to call Smartthings Web Api with
*/
String formatAuthorizationUrl(String redirectUri);
+
+ String[] getAllPrmId();
}
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAuthServlet.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAuthServlet.java
index 2d9986d457c..e98c810eb56 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAuthServlet.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyAuthServlet.java
@@ -48,7 +48,7 @@ public class LinkyAuthServlet extends HttpServlet {
private static final String CONTENT_TYPE = "text/html;charset=UTF-8";
- private static final String HTML_USER_AUTHORIZED = "Addon authorized for user %s.
";
+ private static final String HTML_USER_AUTHORIZED = "Addon authorized for %s.
";
private static final String HTML_ERROR = "Call to Enedis failed with error: %s
";
private static final String HTML_META_REFRESH_CONTENT = "";
@@ -57,6 +57,7 @@ public class LinkyAuthServlet extends HttpServlet {
private static final String KEY_AUTHORIZE_URI = "authorize.uri";
private static final String KEY_RETRIEVE_TOKEN_URI = "retrieveToken.uri";
private static final String KEY_REDIRECT_URI = "redirectUri";
+ private static final String KEY_PRMID_OPTION = "prmId.Option";
private static final String KEY_AUTHORIZED_USER = "authorizedUser";
private static final String KEY_ERROR = "error";
private static final String KEY_PAGE_REFRESH = "pageRefresh";
@@ -81,15 +82,23 @@ public class LinkyAuthServlet extends HttpServlet {
String servletBaseURLSecure = servletBaseURL;
// .replace("http://", "https://");
// .replace("8080", "8443");
- servletBaseURLSecure = servletBaseURLSecure + "?state=OK";
handleLinkyRedirect(replaceMap, servletBaseURLSecure, req.getQueryString());
LinkyAccountHandler accountHandler = linkyAuthService.getLinkyAccountHandler();
resp.setContentType(CONTENT_TYPE);
+
+ StringBuffer optionBuffer = new StringBuffer();
+
+ String[] prmIds = accountHandler.getAllPrmId();
+ for (String prmId : prmIds) {
+ optionBuffer.append("");
+ }
+
+ replaceMap.put(KEY_PRMID_OPTION, optionBuffer.toString());
replaceMap.put(KEY_REDIRECT_URI, servletBaseURLSecure);
- replaceMap.put(KEY_RETRIEVE_TOKEN_URI, servletBaseURLSecure);
+ replaceMap.put(KEY_RETRIEVE_TOKEN_URI, servletBaseURLSecure + "?state=OK");
replaceMap.put(KEY_AUTHORIZE_URI, accountHandler.formatAuthorizationUrl(servletBaseURLSecure));
resp.getWriter().append(replaceKeysFromMap(indexTemplate, replaceMap));
resp.getWriter().close();
@@ -128,7 +137,7 @@ public class LinkyAuthServlet extends HttpServlet {
} else if (!StringUtil.isBlank(reqState)) {
try {
replaceMap.put(KEY_AUTHORIZED_USER, String.format(HTML_USER_AUTHORIZED,
- linkyAuthService.authorize(servletBaseURL, reqState, reqCode)));
+ reqCode + " / " + linkyAuthService.authorize(servletBaseURL, reqState, reqCode)));
} catch (RuntimeException e) {
logger.debug("Exception during authorizaton: ", e);
replaceMap.put(KEY_ERROR, String.format(HTML_ERROR, e.getMessage()));
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyBindingConstants.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyBindingConstants.java
index 7846f53f37b..4b7289f374c 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyBindingConstants.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyBindingConstants.java
@@ -60,6 +60,8 @@ public class LinkyBindingConstants {
public static final String YEAR_MINUS_1 = "yearly#year-1";
public static final String YEAR_MINUS_2 = "yearly#year-2";
+ public static final String TEST_SELECT = "main#linkyTestSelect";
+
// Authorization related Servlet and resources aliases.
public static final String LINKY_ALIAS = "/connectlinky";
public static final String LINKY_IMG_ALIAS = "/img";
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyHandlerFactory.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyHandlerFactory.java
index 940d4238493..bdf8bb1bd17 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyHandlerFactory.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/LinkyHandlerFactory.java
@@ -19,7 +19,9 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
@@ -28,6 +30,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.openhab.binding.linky.internal.api.EnedisHttpApi;
import org.openhab.binding.linky.internal.handler.LinkyHandler;
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
import org.openhab.core.auth.client.oauth2.OAuthClientService;
@@ -217,15 +220,27 @@ public class LinkyHandlerFactory extends BaseThingHandlerFactory implements Link
}
// Fallback for MyElectricalData
else {
- String token = "";
- /*
- * String token = enedisApi.getToken(clientId, config.prmId);
- * config.token = token;
- *
- * Configuration configuration = getConfig();
- * configuration.put("token", token);
- * updateConfiguration(configuration);
- */
+ String token = EnedisHttpApi.getToken(httpClient, clientId, reqCode);
+
+ logger.debug("token:" + token);
+
+ Collection 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();
+ handler.saveConfiguration(config);
+ }
+ }
+
return token;
}
}
@@ -266,18 +281,6 @@ public class LinkyHandlerFactory extends BaseThingHandlerFactory implements Link
}
// Fallback for MyElectricalData
else {
- Collection 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");
- prmId = prmId + "";
-
- }
- }
-
String uri = LinkyBindingConstants.ENEDIS_AUTHORIZE_URL;
uri = uri + "?";
uri = uri + "&client_id=" + clientId;
@@ -288,4 +291,22 @@ public class LinkyHandlerFactory extends BaseThingHandlerFactory implements Link
}
+ @Override
+ public String[] getAllPrmId() {
+ Collection col = this.thingRegistry.getAll();
+ List result = new ArrayList();
+ for (Thing thing : col) {
+ if (LinkyBindingConstants.THING_TYPE_LINKY.equals(thing.getThingTypeUID())) {
+
+ Configuration config = thing.getConfiguration();
+
+ String prmId = (String) config.get("prmId");
+ result.add(prmId);
+
+ }
+ }
+
+ return result.toArray(new String[0]);
+ }
+
}
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/api/EnedisHttpApi.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/api/EnedisHttpApi.java
index 7ecaedd4529..3cc4ec6ae95 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/api/EnedisHttpApi.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/api/EnedisHttpApi.java
@@ -48,6 +48,7 @@ import org.openhab.binding.linky.internal.dto.IdentityInfo;
import org.openhab.binding.linky.internal.dto.MeterReading;
import org.openhab.binding.linky.internal.dto.MeterResponse;
import org.openhab.binding.linky.internal.dto.PrmInfo;
+import org.openhab.binding.linky.internal.dto.TempoResponse;
import org.openhab.binding.linky.internal.dto.UsagePoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,6 +72,7 @@ public class EnedisHttpApi {
private static final String CONTACT_URL = BASE_URL + "contact";
private static final String ADDRESS_URL = BASE_URL + "addresses";
private static final String MEASURE_URL = BASE_URL + "%s/%s/start/%s/end/%s/cache";
+ 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";
@@ -111,10 +113,16 @@ public class EnedisHttpApi {
}
private String getData(String url) throws LinkyException {
+ return getData(url, httpClient, config.token);
+ }
+
+ private static String getData(String url, HttpClient httpClient, String token) throws LinkyException {
try {
Request request = httpClient.newRequest(url);
request = request.method(HttpMethod.GET);
- request = request.header("Authorization", config.token);
+ if (!("".equals(token))) {
+ request = request.header("Authorization", token);
+ }
ContentResponse result = request.send();
if (result.getStatus() == 307) {
@@ -272,10 +280,37 @@ public class EnedisHttpApi {
return getMeasures(userId, prmId, from, to, "daily_consumption_max_power");
}
- public String getToken(String clientId, String prmId) {
+ public String getTempoData() throws LinkyException {
+ String url = String.format(TEMPO_URL, "2024-01-01", "2024-01-31");
+ if (!connected) {
+ initialize();
+ }
+ String data = getData(url);
+ if (data.isEmpty()) {
+ throw new LinkyException("Requesting '%s' returned an empty response", url);
+ }
+ logger.trace("getData returned {}", data);
+
+ try {
+ TempoResponse tempResponse = gson.fromJson(data, TempoResponse.class);
+ if (tempResponse == null) {
+ throw new LinkyException("No report data received");
+ }
+
+ return "{\"2024-01-20\":\"WHITE\",\"2024-01-21\":\"RED\",\"array\":[\"2024-01-20\",\"2024-01-21\"]}";
+ // return tempResponse.tempoDayInfo;
+ } catch (JsonSyntaxException e) {
+ logger.debug("invalid JSON response not matching ConsumptionReport.class: {}", data);
+ throw new LinkyException(e, "Requesting '%s' returned an invalid JSON response", url);
+ }
+
+ // return data;
+ }
+
+ public static String getToken(HttpClient httpClient, String clientId, String prmId) {
try {
String url = String.format(TOKEN_URL, clientId, prmId);
- String token = getData(url);
+ String token = getData(url, httpClient, "");
return token;
} catch (LinkyException e) {
return "";
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoDayInfo.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoDayInfo.java
new file mode 100644
index 00000000000..b5ba925c7d1
--- /dev/null
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoDayInfo.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.linky.internal.dto;
+
+import org.eclipse.jetty.jaas.spi.UserInfo;
+
+/**
+ * The {@link UserInfo} holds informations about energy delivery point
+ *
+ * @author Gaël L'hopital - Initial contribution
+ * @author Laurent Arnal - Rewrite addon to use official dataconect API
+ */
+
+public class TempoDayInfo {
+ public String tempoDay;
+ public String tempoVal;
+}
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoResponse.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoResponse.java
new file mode 100644
index 00000000000..509772ddacf
--- /dev/null
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/TempoResponse.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.linky.internal.dto;
+
+import java.util.HashMap;
+
+import org.eclipse.jetty.jaas.spi.UserInfo;
+
+/**
+ * The {@link UserInfo} holds informations about energy delivery point
+ *
+ * @author Gaël L'hopital - Initial contribution
+ * @author Laurent Arnal - Rewrite addon to use official dataconect API
+ */
+
+public class TempoResponse extends HashMap {
+
+}
diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/handler/LinkyHandler.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/handler/LinkyHandler.java
index 56001489b79..03d63b3d4c9 100644
--- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/handler/LinkyHandler.java
+++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/handler/LinkyHandler.java
@@ -36,9 +36,14 @@ import org.openhab.binding.linky.internal.dto.IntervalReading;
import org.openhab.binding.linky.internal.dto.MeterReading;
import org.openhab.binding.linky.internal.dto.PrmInfo;
import org.openhab.core.auth.client.oauth2.OAuthFactory;
+import org.openhab.core.config.core.Configuration;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.library.types.QuantityType;
+<<<<<<< HEAD
import org.openhab.core.library.unit.MetricPrefix;
+=======
+import org.openhab.core.library.types.StringType;
+>>>>>>> 8179e0592f (some fixes on connectlinky page)
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@@ -160,13 +165,13 @@ public class LinkyHandler extends BaseThingHandler {
config = getConfigAs(LinkyConfiguration.class);
if (config.seemsValid()) {
enedisApi = new EnedisHttpApi(config, gson, httpClient);
+
scheduler.submit(() -> {
try {
- EnedisHttpApi api = this.enedisApi;
- api.initialize();
+ enedisApi.initialize();
updateStatus(ThingStatus.ONLINE);
- PrmInfo prmInfo = api.getPrmInfo();
+ PrmInfo prmInfo = enedisApi.getPrmInfo();
updateProperties(Map.of(USER_ID, prmInfo.customerId, PUISSANCE,
prmInfo.contractInfo.subscribedPower, PRM_ID, prmInfo.prmId));
@@ -206,6 +211,24 @@ public class LinkyHandler extends BaseThingHandler {
// updateMonthlyData();
// updateYearlyData();
+ String tempoData = getTempoData();
+
+ // LinkedTreeMap obj = gson.fromJson(tempoData, LinkedTreeMap.class);
+
+ /*
+ *
+ *
+ * ArrayList
+
+
- Connect to Enedis:
-
-
-
-
-
+
Connect to Enedis:
+
+
+
+
+ Please select your prmId :
+
+
+
+
+