From 7e54ac2ca1d7f4a80967830b24df806247b48ab4 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Fri, 18 Dec 2020 08:49:38 +0100 Subject: [PATCH 01/13] [linky] Handle case when data from yesterday is still NaN Fix #9386 Signed-off-by: Laurent Garnier --- .../linky/internal/api/EnedisHttpApi.java | 7 + .../console/LinkyCommandExtension.java | 12 +- .../linky/internal/dto/ConsumptionReport.java | 30 ++++ .../linky/internal/handler/LinkyHandler.java | 148 ++++++++++-------- 4 files changed, 130 insertions(+), 67 deletions(-) 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 50581eabf2d5b..e040d6f46129f 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 @@ -256,8 +256,15 @@ private Consumption getMeasures(String userId, String prmId, LocalDate from, Loc if (data.isEmpty()) { throw new LinkyException(String.format("Requesting '%s' returned an empty response", url)); } + logger.trace("getData returned {}", data); try { ConsumptionReport report = gson.fromJson(data, ConsumptionReport.class); + try { + report.checkData(); + } catch (LinkyException e) { + throw new LinkyException( + String.format("Requesting '%s' returned an invalid response: %s", url, e.getMessage())); + } return report.firstLevel.consumptions; } catch (JsonSyntaxException e) { logger.debug("invalid JSON response not matching ConsumptionReport.class: {}", data); diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/console/LinkyCommandExtension.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/console/LinkyCommandExtension.java index 36a8ec9ab27e1..e0bd586d62c85 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/console/LinkyCommandExtension.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/console/LinkyCommandExtension.java @@ -80,9 +80,9 @@ public void execute(String[] args, Console console) { console.println(String.format("'%s' is not a Linky thing id", args[0])); printUsage(console); } else if (REPORT.equals(args[1])) { - LocalDate now = LocalDate.now(); - LocalDate start = now.minusDays(7); - LocalDate end = now.minusDays(1); + LocalDate yesterday = LocalDate.now().minusDays(1); + LocalDate start = yesterday.minusDays(6); + LocalDate end = yesterday; String separator = " "; if (args.length >= 3) { try { @@ -104,13 +104,13 @@ public void execute(String[] args, Console console) { return; } } - if (!start.isBefore(now) || start.isAfter(end)) { + if (start.isAfter(yesterday) || start.isAfter(end)) { console.println("Start day must be in the past and before the end day"); printUsage(console); return; } - if (end.isAfter(now.minusDays(1))) { - end = now.minusDays(1); + if (end.isAfter(yesterday)) { + end = yesterday; } if (args.length >= 5) { separator = args[4]; diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java index 488ed24c54014..7b13534d933b3 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java @@ -15,6 +15,8 @@ import java.time.ZonedDateTime; import java.util.List; +import org.openhab.binding.linky.internal.LinkyException; + import com.google.gson.annotations.SerializedName; /** @@ -61,4 +63,32 @@ public class FirstLevel { @SerializedName("1") public FirstLevel firstLevel; + + public void checkData() throws LinkyException { + Consumption cons = firstLevel.consumptions; + if (cons.aggregats.days.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no day period"); + } + if (cons.aggregats.days.periodes.size() != cons.aggregats.days.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each day period"); + } + if (cons.aggregats.weeks.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no week period"); + } + if (cons.aggregats.weeks.periodes.size() != cons.aggregats.weeks.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each week period"); + } + if (cons.aggregats.months.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no month period"); + } + if (cons.aggregats.months.periodes.size() != cons.aggregats.months.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each month period"); + } + if (cons.aggregats.years.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no year period"); + } + if (cons.aggregats.years.periodes.size() != cons.aggregats.years.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each year period"); + } + } } 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 2da73b75370aa..b446c69207d2c 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 @@ -65,8 +65,8 @@ public class LinkyHandler extends BaseThingHandler { private final Logger logger = LoggerFactory.getLogger(LinkyHandler.class); - private static final int REFRESH_FIRST_HOUR_OF_DAY = 5; - private static final int REFRESH_INTERVAL_IN_MIN = 360; + private static final int REFRESH_FIRST_HOUR_OF_DAY = 2; + private static final int REFRESH_INTERVAL_IN_MIN = 180; private final HttpClient httpClient; private final Gson gson; @@ -91,7 +91,30 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC this.cachedDailyData = new ExpiringDayCache<>("daily cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { LocalDate today = LocalDate.now(); - return getConsumptionData(today.minusDays(15), today); + Consumption consumption = getConsumptionData(today.minusDays(15), today); + if (consumption != null) { + Aggregate days = consumption.aggregats.days; + Aggregate weeks = consumption.aggregats.weeks; + if (logger.isDebugEnabled()) { + for (int i = 0; i < days.datas.size(); i++) { + logger.debug("Day {} {} value {}", + days.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.datas.get(i)); + } + for (int i = 0; i < weeks.datas.size(); i++) { + logger.debug("Weeek {} {} value {}", + weeks.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + weeks.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + weeks.datas.get(i)); + } + } + if (days.datas.get(days.datas.size() - 1).isNaN()) { + logger.debug("Dayly data including yesterday are not yet available"); + consumption = null; + } + } + return consumption; }); this.cachedPowerData = new ExpiringDayCache<>("power cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { @@ -102,12 +125,46 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC this.cachedMonthlyData = new ExpiringDayCache<>("monthly cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { LocalDate today = LocalDate.now(); - return getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); + Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); + if (consumption != null) { + Aggregate days = consumption.aggregats.days; + Aggregate months = consumption.aggregats.months; + if (logger.isDebugEnabled()) { + for (int i = 0; i < months.datas.size(); i++) { + logger.debug("Month {} {} value {}", + months.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + months.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + months.datas.get(i)); + } + } + if (days.datas.get(days.datas.size() - 1).isNaN()) { + logger.debug("Monthly data including yesterday are not yet available"); + consumption = null; + } + } + return consumption; }); this.cachedYearlyData = new ExpiringDayCache<>("yearly cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { LocalDate today = LocalDate.now(); - return getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); + Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); + if (consumption != null) { + Aggregate days = consumption.aggregats.days; + Aggregate years = consumption.aggregats.years; + if (logger.isDebugEnabled()) { + for (int i = 0; i < years.datas.size(); i++) { + logger.debug("Year {} {} value {}", + years.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + years.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + years.datas.get(i)); + } + } + if (days.datas.get(days.datas.size() - 1).isNaN()) { + logger.debug("Yearly data including yesterday are not yet available"); + consumption = null; + } + } + return consumption; }); } @@ -178,12 +235,8 @@ private synchronized void updatePowerData() { if (isLinked(PEAK_POWER) || isLinked(PEAK_TIMESTAMP)) { cachedPowerData.getValue().ifPresent(values -> { Aggregate days = values.aggregats.days; - if (days.datas.size() == 0 || days.periodes.size() == 0) { - logger.debug("Daily power data are without any period/data"); - } else { - updateVAChannel(PEAK_POWER, days.datas.get(0)); - updateState(PEAK_TIMESTAMP, new DateTimeType(days.periodes.get(0).dateDebut)); - } + updateVAChannel(PEAK_POWER, days.datas.get(0)); + updateState(PEAK_TIMESTAMP, new DateTimeType(days.periodes.get(0).dateDebut)); }); } } @@ -192,30 +245,10 @@ private synchronized void updatePowerData() { * Request new dayly/weekly data and updates channels */ private synchronized void updateDailyData() { - if (isLinked(YESTERDAY) || isLinked(THIS_WEEK)) { + if (isLinked(YESTERDAY)) { cachedDailyData.getValue().ifPresent(values -> { Aggregate days = values.aggregats.days; - if (days.periodes.size() > days.datas.size()) { - logger.debug("Daily data are invalid: not a data for each period"); - return; - } - int maxValue = days.periodes.size() - 1; - int thisWeekNumber = days.periodes.get(maxValue).dateDebut.get(weekFields.weekOfWeekBasedYear()); - double yesterday = days.datas.get(maxValue); - double thisWeek = 0.00; - - for (int i = maxValue; i >= 0; i--) { - int weekNumber = days.periodes.get(i).dateDebut.get(weekFields.weekOfWeekBasedYear()); - if (weekNumber == thisWeekNumber) { - Double value = days.datas.get(i); - thisWeek += !value.isNaN() ? value : 0; - } else { - break; - } - } - - updateKwhChannel(YESTERDAY, yesterday); - updateKwhChannel(THIS_WEEK, thisWeek); + updateKwhChannel(YESTERDAY, days.datas.get(days.datas.size() - 1)); }); } } @@ -224,15 +257,22 @@ private synchronized void updateDailyData() { * Request new weekly data and updates channels */ private synchronized void updateWeeklyData() { - if (isLinked(LAST_WEEK)) { + if (isLinked(LAST_WEEK) || isLinked(THIS_WEEK)) { cachedDailyData.getValue().ifPresent(values -> { + Aggregate days = values.aggregats.days; + int idxLast = days.periodes.get(days.periodes.size() - 1).dateDebut.get(weekFields.dayOfWeek()) == 7 ? 2 + : 1; Aggregate weeks = values.aggregats.weeks; - if (weeks.datas.size() > 1) { - updateKwhChannel(LAST_WEEK, weeks.datas.get(1)); + if (weeks.datas.size() > idxLast) { + updateKwhChannel(LAST_WEEK, weeks.datas.get(idxLast)); } else { - logger.debug("Weekly data are without last week data"); updateKwhChannel(LAST_WEEK, Double.NaN); } + if (weeks.datas.size() > (idxLast + 1)) { + updateKwhChannel(THIS_WEEK, weeks.datas.get(idxLast + 1)); + } else { + updateKwhChannel(THIS_WEEK, Double.NaN); + } }); } } @@ -244,18 +284,11 @@ private synchronized void updateMonthlyData() { if (isLinked(LAST_MONTH) || isLinked(THIS_MONTH)) { cachedMonthlyData.getValue().ifPresent(values -> { Aggregate months = values.aggregats.months; - if (months.datas.size() == 0) { - logger.debug("Monthly data are without any data"); - updateKwhChannel(LAST_MONTH, Double.NaN); - updateKwhChannel(THIS_MONTH, Double.NaN); + updateKwhChannel(LAST_MONTH, months.datas.get(0)); + if (months.datas.size() > 1) { + updateKwhChannel(THIS_MONTH, months.datas.get(1)); } else { - updateKwhChannel(LAST_MONTH, months.datas.get(0)); - if (months.datas.size() > 1) { - updateKwhChannel(THIS_MONTH, months.datas.get(1)); - } else { - logger.debug("Monthly data are without current month data"); - updateKwhChannel(THIS_MONTH, Double.NaN); - } + updateKwhChannel(THIS_MONTH, Double.NaN); } }); } @@ -268,18 +301,11 @@ private synchronized void updateYearlyData() { if (isLinked(LAST_YEAR) || isLinked(THIS_YEAR)) { cachedYearlyData.getValue().ifPresent(values -> { Aggregate years = values.aggregats.years; - if (years.datas.size() == 0) { - logger.debug("Yearly data are without any data"); - updateKwhChannel(LAST_YEAR, Double.NaN); - updateKwhChannel(THIS_YEAR, Double.NaN); + updateKwhChannel(LAST_YEAR, years.datas.get(0)); + if (years.datas.size() > 1) { + updateKwhChannel(THIS_YEAR, years.datas.get(1)); } else { - updateKwhChannel(LAST_YEAR, years.datas.get(0)); - if (years.datas.size() > 1) { - updateKwhChannel(THIS_YEAR, years.datas.get(1)); - } else { - logger.debug("Yearly data are without current year data"); - updateKwhChannel(THIS_YEAR, Double.NaN); - } + updateKwhChannel(THIS_YEAR, Double.NaN); } }); } @@ -315,7 +341,7 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable List report = new ArrayList<>(); if (startDay.getYear() == endDay.getYear() && startDay.getMonthValue() == endDay.getMonthValue()) { // All values in the same month - Consumption result = getConsumptionData(startDay, endDay); + Consumption result = getConsumptionData(startDay, endDay.plusDays(1)); if (result != null) { Aggregate days = result.aggregats.days; for (int i = 0; i < days.datas.size(); i++) { @@ -410,10 +436,10 @@ public synchronized void handleCommand(ChannelUID channelUID, Command command) { boolean connectedBefore = isConnected(); switch (channelUID.getId()) { case YESTERDAY: - case THIS_WEEK: updateDailyData(); break; case LAST_WEEK: + case THIS_WEEK: updateWeeklyData(); break; case LAST_MONTH: From 09327b67c0454dd290656a33cf0605d4bea3bbd9 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 27 Dec 2020 11:13:11 +0100 Subject: [PATCH 02/13] Refresh every 2 hours until data from yesterday are available Signed-off-by: Laurent Garnier --- .../binding/linky/internal/handler/LinkyHandler.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 b446c69207d2c..d321d32b6027e 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 @@ -65,8 +65,8 @@ public class LinkyHandler extends BaseThingHandler { private final Logger logger = LoggerFactory.getLogger(LinkyHandler.class); - private static final int REFRESH_FIRST_HOUR_OF_DAY = 2; - private static final int REFRESH_INTERVAL_IN_MIN = 180; + private static final int REFRESH_FIRST_HOUR_OF_DAY = 1; + private static final int REFRESH_INTERVAL_IN_MIN = 120; private final HttpClient httpClient; private final Gson gson; @@ -265,13 +265,11 @@ private synchronized void updateWeeklyData() { Aggregate weeks = values.aggregats.weeks; if (weeks.datas.size() > idxLast) { updateKwhChannel(LAST_WEEK, weeks.datas.get(idxLast)); - } else { - updateKwhChannel(LAST_WEEK, Double.NaN); } if (weeks.datas.size() > (idxLast + 1)) { updateKwhChannel(THIS_WEEK, weeks.datas.get(idxLast + 1)); } else { - updateKwhChannel(THIS_WEEK, Double.NaN); + updateKwhChannel(THIS_WEEK, 0.0); } }); } @@ -288,7 +286,7 @@ private synchronized void updateMonthlyData() { if (months.datas.size() > 1) { updateKwhChannel(THIS_MONTH, months.datas.get(1)); } else { - updateKwhChannel(THIS_MONTH, Double.NaN); + updateKwhChannel(THIS_MONTH, 0.0); } }); } @@ -305,7 +303,7 @@ private synchronized void updateYearlyData() { if (years.datas.size() > 1) { updateKwhChannel(THIS_YEAR, years.datas.get(1)); } else { - updateKwhChannel(THIS_YEAR, Double.NaN); + updateKwhChannel(THIS_YEAR, 0.0); } }); } From 3e9362c415584d43310646f53c30435f1d30db09 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 27 Dec 2020 11:33:19 +0100 Subject: [PATCH 03/13] Log yesterday even for month and year requests Signed-off-by: Laurent Garnier --- .../binding/linky/internal/handler/LinkyHandler.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 d321d32b6027e..122879e700a42 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 @@ -130,6 +130,12 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Aggregate days = consumption.aggregats.days; Aggregate months = consumption.aggregats.months; if (logger.isDebugEnabled()) { + logger.debug("Day {} {} value {}", + days.periodes.get(days.datas.size() - 1).dateDebut + .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.periodes.get(days.datas.size() - 1).dateFin.format( + DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.datas.get(days.datas.size() - 1)); for (int i = 0; i < months.datas.size(); i++) { logger.debug("Month {} {} value {}", months.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), @@ -152,6 +158,12 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Aggregate days = consumption.aggregats.days; Aggregate years = consumption.aggregats.years; if (logger.isDebugEnabled()) { + logger.debug("Day {} {} value {}", + days.periodes.get(days.datas.size() - 1).dateDebut + .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.periodes.get(days.datas.size() - 1).dateFin.format( + DateTimeFormatter.ISO_LOCAL_DATE_TIME), + days.datas.get(days.datas.size() - 1)); for (int i = 0; i < years.datas.size(); i++) { logger.debug("Year {} {} value {}", years.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), From acbd751aab89f9f87c693fbf0c86b206ae2e891d Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 27 Dec 2020 11:45:24 +0100 Subject: [PATCH 04/13] Update log for day data Signed-off-by: Laurent Garnier --- .../linky/internal/handler/LinkyHandler.java | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) 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 122879e700a42..6c6c1deb5658a 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 @@ -97,9 +97,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Aggregate weeks = consumption.aggregats.weeks; if (logger.isDebugEnabled()) { for (int i = 0; i < days.datas.size(); i++) { - logger.debug("Day {} {} value {}", - days.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - days.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), + logger.debug("Day {} value {}", + days.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE), days.datas.get(i)); } for (int i = 0; i < weeks.datas.size(); i++) { @@ -130,12 +129,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Aggregate days = consumption.aggregats.days; Aggregate months = consumption.aggregats.months; if (logger.isDebugEnabled()) { - logger.debug("Day {} {} value {}", - days.periodes.get(days.datas.size() - 1).dateDebut - .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - days.periodes.get(days.datas.size() - 1).dateFin.format( - DateTimeFormatter.ISO_LOCAL_DATE_TIME), - days.datas.get(days.datas.size() - 1)); + logger.debug("Day {} value {}", days.periodes.get(days.periodes.size() - 1).dateDebut + .format(DateTimeFormatter.ISO_LOCAL_DATE), days.datas.get(days.datas.size() - 1)); for (int i = 0; i < months.datas.size(); i++) { logger.debug("Month {} {} value {}", months.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), @@ -158,12 +153,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Aggregate days = consumption.aggregats.days; Aggregate years = consumption.aggregats.years; if (logger.isDebugEnabled()) { - logger.debug("Day {} {} value {}", - days.periodes.get(days.datas.size() - 1).dateDebut - .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - days.periodes.get(days.datas.size() - 1).dateFin.format( - DateTimeFormatter.ISO_LOCAL_DATE_TIME), - days.datas.get(days.datas.size() - 1)); + logger.debug("Day {} value {}", days.periodes.get(days.periodes.size() - 1).dateDebut + .format(DateTimeFormatter.ISO_LOCAL_DATE), days.datas.get(days.datas.size() - 1)); for (int i = 0; i < years.datas.size(); i++) { logger.debug("Year {} {} value {}", years.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), From 55403908e7534c7c193587d02abab81169d780f3 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 14:24:43 +0100 Subject: [PATCH 05/13] Consider review comments Signed-off-by: Laurent Garnier --- .../linky/internal/dto/ConsumptionReport.java | 31 ++++++++++++ .../linky/internal/handler/LinkyHandler.java | 48 ++++--------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java index 7b13534d933b3..30a96596ff9e1 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java @@ -13,9 +13,12 @@ package org.openhab.binding.linky.internal.dto; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import org.openhab.binding.linky.internal.LinkyException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.annotations.SerializedName; @@ -26,6 +29,8 @@ * @author Gaël L'hopital - Initial contribution */ public class ConsumptionReport { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsumptionReport.class); + public class Period { public String grandeurPhysiqueEnum; public ZonedDateTime dateDebut; @@ -36,6 +41,32 @@ public class Aggregate { public List labels; public List periodes; public List datas; + + public void log(String title, boolean withDateFin, DateTimeFormatter dateTimeFormatter, boolean onlyLast) { + if (LOGGER.isDebugEnabled()) { + int size = (datas == null || periodes == null) ? 0 + : (datas.size() <= periodes.size() ? datas.size() : periodes.size()); + if (onlyLast) { + if (size > 0) { + log(size - 1, title, withDateFin, dateTimeFormatter); + } + } else { + for (int i = 0; i < size; i++) { + log(i, title, withDateFin, dateTimeFormatter); + } + } + } + } + + private void log(int index, String title, boolean withDateFin, DateTimeFormatter dateTimeFormatter) { + if (withDateFin) { + LOGGER.debug("{} {} {} value {}", title, periodes.get(index).dateDebut.format(dateTimeFormatter), + periodes.get(index).dateFin.format(dateTimeFormatter), datas.get(index)); + } else { + LOGGER.debug("{} {} value {}", title, periodes.get(index).dateDebut.format(dateTimeFormatter), + datas.get(index)); + } + } } public class ChronoData { 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 6c6c1deb5658a..e74a995e389f2 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 @@ -94,21 +94,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Consumption consumption = getConsumptionData(today.minusDays(15), today); if (consumption != null) { Aggregate days = consumption.aggregats.days; - Aggregate weeks = consumption.aggregats.weeks; - if (logger.isDebugEnabled()) { - for (int i = 0; i < days.datas.size(); i++) { - logger.debug("Day {} value {}", - days.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE), - days.datas.get(i)); - } - for (int i = 0; i < weeks.datas.size(); i++) { - logger.debug("Weeek {} {} value {}", - weeks.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - weeks.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - weeks.datas.get(i)); - } - } - if (days.datas.get(days.datas.size() - 1).isNaN()) { + days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); + consumption.aggregats.weeks.log("Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { logger.debug("Dayly data including yesterday are not yet available"); consumption = null; } @@ -127,18 +115,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { Aggregate days = consumption.aggregats.days; - Aggregate months = consumption.aggregats.months; - if (logger.isDebugEnabled()) { - logger.debug("Day {} value {}", days.periodes.get(days.periodes.size() - 1).dateDebut - .format(DateTimeFormatter.ISO_LOCAL_DATE), days.datas.get(days.datas.size() - 1)); - for (int i = 0; i < months.datas.size(); i++) { - logger.debug("Month {} {} value {}", - months.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - months.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - months.datas.get(i)); - } - } - if (days.datas.get(days.datas.size() - 1).isNaN()) { + days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + consumption.aggregats.months.log("Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { logger.debug("Monthly data including yesterday are not yet available"); consumption = null; } @@ -151,18 +130,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { Aggregate days = consumption.aggregats.days; - Aggregate years = consumption.aggregats.years; - if (logger.isDebugEnabled()) { - logger.debug("Day {} value {}", days.periodes.get(days.periodes.size() - 1).dateDebut - .format(DateTimeFormatter.ISO_LOCAL_DATE), days.datas.get(days.datas.size() - 1)); - for (int i = 0; i < years.datas.size(); i++) { - logger.debug("Year {} {} value {}", - years.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - years.periodes.get(i).dateFin.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), - years.datas.get(i)); - } - } - if (days.datas.get(days.datas.size() - 1).isNaN()) { + days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + consumption.aggregats.years.log("Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { logger.debug("Yearly data including yesterday are not yet available"); consumption = null; } From f267d83089bda4ff63b25104f40fb5f7b4257e6f Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 14:40:02 +0100 Subject: [PATCH 06/13] Set thing status to ONLINE when data are correctly retrieved Signed-off-by: Laurent Garnier --- .../binding/linky/internal/handler/LinkyHandler.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 e74a995e389f2..c111b9c0dbc74 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 @@ -351,7 +351,9 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable EnedisHttpApi api = this.enedisApi; if (api != null) { try { - return api.getEnergyData(userId, prmId, from, to); + Consumption consumption = api.getEnergyData(userId, prmId, from, to); + updateStatus(ThingStatus.ONLINE); + return consumption; } catch (LinkyException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.getMessage()); } @@ -365,7 +367,9 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable EnedisHttpApi api = this.enedisApi; if (api != null) { try { - return api.getPowerData(userId, prmId, from, to); + Consumption consumption = api.getPowerData(userId, prmId, from, to); + updateStatus(ThingStatus.ONLINE); + return consumption; } catch (LinkyException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.getMessage()); } From a02ad714b79f18252ceefab5ffa0f3a5cce902cc Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 15:20:34 +0100 Subject: [PATCH 07/13] Review comment: method for common code Signed-off-by: Laurent Garnier --- .../linky/internal/handler/LinkyHandler.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) 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 c111b9c0dbc74..901acf39f2efb 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 @@ -93,10 +93,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.minusDays(15), today); if (consumption != null) { - Aggregate days = consumption.aggregats.days; - days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); + consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); consumption.aggregats.weeks.log("Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { + if (!isDataLastDayAvailable(consumption)) { logger.debug("Dayly data including yesterday are not yet available"); consumption = null; } @@ -114,10 +113,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { - Aggregate days = consumption.aggregats.days; - days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); consumption.aggregats.months.log("Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { + if (!isDataLastDayAvailable(consumption)) { logger.debug("Monthly data including yesterday are not yet available"); consumption = null; } @@ -129,10 +127,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { - Aggregate days = consumption.aggregats.days; - days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); consumption.aggregats.years.log("Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (days.datas == null || days.datas.size() == 0 || days.datas.get(days.datas.size() - 1).isNaN()) { + if (!isDataLastDayAvailable(consumption)) { logger.debug("Yearly data including yesterday are not yet available"); consumption = null; } @@ -141,6 +138,11 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC }); } + private boolean isDataLastDayAvailable(Consumption consumption) { + Aggregate days = consumption.aggregats.days; + return days.datas != null && days.datas.size() > 0 && !days.datas.get(days.datas.size() - 1).isNaN(); + } + @Override public void initialize() { logger.debug("Initializing Linky handler."); From a3a1d8b2180934cd8d02696b57ba853ce8c5c023 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 19:28:58 +0100 Subject: [PATCH 08/13] Review comment: move logging logic to LinkyHandler Signed-off-by: Laurent Garnier --- .../linky/internal/dto/ConsumptionReport.java | 30 ----------- .../linky/internal/handler/LinkyHandler.java | 51 +++++++++++++++---- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java index 30a96596ff9e1..8fe7e1abd10d1 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java @@ -13,12 +13,9 @@ package org.openhab.binding.linky.internal.dto; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import java.util.List; import org.openhab.binding.linky.internal.LinkyException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.gson.annotations.SerializedName; @@ -29,7 +26,6 @@ * @author Gaël L'hopital - Initial contribution */ public class ConsumptionReport { - private static final Logger LOGGER = LoggerFactory.getLogger(ConsumptionReport.class); public class Period { public String grandeurPhysiqueEnum; @@ -41,32 +37,6 @@ public class Aggregate { public List labels; public List periodes; public List datas; - - public void log(String title, boolean withDateFin, DateTimeFormatter dateTimeFormatter, boolean onlyLast) { - if (LOGGER.isDebugEnabled()) { - int size = (datas == null || periodes == null) ? 0 - : (datas.size() <= periodes.size() ? datas.size() : periodes.size()); - if (onlyLast) { - if (size > 0) { - log(size - 1, title, withDateFin, dateTimeFormatter); - } - } else { - for (int i = 0; i < size; i++) { - log(i, title, withDateFin, dateTimeFormatter); - } - } - } - } - - private void log(int index, String title, boolean withDateFin, DateTimeFormatter dateTimeFormatter) { - if (withDateFin) { - LOGGER.debug("{} {} {} value {}", title, periodes.get(index).dateDebut.format(dateTimeFormatter), - periodes.get(index).dateFin.format(dateTimeFormatter), datas.get(index)); - } else { - LOGGER.debug("{} {} value {}", title, periodes.get(index).dateDebut.format(dateTimeFormatter), - datas.get(index)); - } - } } public class ChronoData { 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 901acf39f2efb..fe5b3095d3138 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 @@ -93,8 +93,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.minusDays(15), today); if (consumption != null) { - consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); - consumption.aggregats.weeks.log("Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); + logData(consumption.aggregats.weeks, "Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { logger.debug("Dayly data including yesterday are not yet available"); consumption = null; @@ -113,8 +113,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { - consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); - consumption.aggregats.months.log("Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + logData(consumption.aggregats.months, "Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { logger.debug("Monthly data including yesterday are not yet available"); consumption = null; @@ -127,8 +127,8 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { - consumption.aggregats.days.log("Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); - consumption.aggregats.years.log("Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); + logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); + logData(consumption.aggregats.years, "Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { logger.debug("Yearly data including yesterday are not yet available"); consumption = null; @@ -138,11 +138,6 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC }); } - private boolean isDataLastDayAvailable(Consumption consumption) { - Aggregate days = consumption.aggregats.days; - return days.datas != null && days.datas.size() > 0 && !days.datas.get(days.datas.size() - 1).isNaN(); - } - @Override public void initialize() { logger.debug("Initializing Linky handler."); @@ -441,4 +436,38 @@ public synchronized void handleCommand(ChannelUID channelUID, Command command) { logger.debug("The Linky binding is read-only and can not handle command {}", command); } } + + private boolean isDataLastDayAvailable(Consumption consumption) { + Aggregate days = consumption.aggregats.days; + return days.datas != null && days.datas.size() > 0 && !days.datas.get(days.datas.size() - 1).isNaN(); + } + + private void logData(Aggregate aggregate, String title, boolean withDateFin, DateTimeFormatter dateTimeFormatter, + boolean onlyLast) { + if (logger.isDebugEnabled()) { + int size = (aggregate.datas == null || aggregate.periodes == null) ? 0 + : (aggregate.datas.size() <= aggregate.periodes.size() ? aggregate.datas.size() + : aggregate.periodes.size()); + if (onlyLast) { + if (size > 0) { + logData(aggregate, size - 1, title, withDateFin, dateTimeFormatter); + } + } else { + for (int i = 0; i < size; i++) { + logData(aggregate, i, title, withDateFin, dateTimeFormatter); + } + } + } + } + + private void logData(Aggregate aggregate, int index, String title, boolean withDateFin, + DateTimeFormatter dateTimeFormatter) { + if (withDateFin) { + logger.debug("{} {} {} value {}", title, aggregate.periodes.get(index).dateDebut.format(dateTimeFormatter), + aggregate.periodes.get(index).dateFin.format(dateTimeFormatter), aggregate.datas.get(index)); + } else { + logger.debug("{} {} value {}", title, aggregate.periodes.get(index).dateDebut.format(dateTimeFormatter), + aggregate.datas.get(index)); + } + } } From e85e31f86330531090f98e0b43672d98e8ce9042 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 19:57:27 +0100 Subject: [PATCH 09/13] Move checkData to LinkyHandler Signed-off-by: Laurent Garnier --- .../linky/internal/api/EnedisHttpApi.java | 9 +----- .../linky/internal/dto/ConsumptionReport.java | 30 ------------------- .../linky/internal/handler/LinkyHandler.java | 29 ++++++++++++++++++ 3 files changed, 30 insertions(+), 38 deletions(-) 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 e040d6f46129f..0a4739d912741 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 @@ -258,14 +258,7 @@ private Consumption getMeasures(String userId, String prmId, LocalDate from, Loc } logger.trace("getData returned {}", data); try { - ConsumptionReport report = gson.fromJson(data, ConsumptionReport.class); - try { - report.checkData(); - } catch (LinkyException e) { - throw new LinkyException( - String.format("Requesting '%s' returned an invalid response: %s", url, e.getMessage())); - } - return report.firstLevel.consumptions; + return gson.fromJson(data, ConsumptionReport.class).firstLevel.consumptions; } catch (JsonSyntaxException e) { logger.debug("invalid JSON response not matching ConsumptionReport.class: {}", data); throw new LinkyException( diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java index 8fe7e1abd10d1..0063547f50464 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java @@ -15,8 +15,6 @@ import java.time.ZonedDateTime; import java.util.List; -import org.openhab.binding.linky.internal.LinkyException; - import com.google.gson.annotations.SerializedName; /** @@ -64,32 +62,4 @@ public class FirstLevel { @SerializedName("1") public FirstLevel firstLevel; - - public void checkData() throws LinkyException { - Consumption cons = firstLevel.consumptions; - if (cons.aggregats.days.periodes.size() == 0) { - throw new LinkyException("invalid consumptions data: no day period"); - } - if (cons.aggregats.days.periodes.size() != cons.aggregats.days.datas.size()) { - throw new LinkyException("invalid consumptions data: not one data for each day period"); - } - if (cons.aggregats.weeks.periodes.size() == 0) { - throw new LinkyException("invalid consumptions data: no week period"); - } - if (cons.aggregats.weeks.periodes.size() != cons.aggregats.weeks.datas.size()) { - throw new LinkyException("invalid consumptions data: not one data for each week period"); - } - if (cons.aggregats.months.periodes.size() == 0) { - throw new LinkyException("invalid consumptions data: no month period"); - } - if (cons.aggregats.months.periodes.size() != cons.aggregats.months.datas.size()) { - throw new LinkyException("invalid consumptions data: not one data for each month period"); - } - if (cons.aggregats.years.periodes.size() == 0) { - throw new LinkyException("invalid consumptions data: no year period"); - } - if (cons.aggregats.years.periodes.size() != cons.aggregats.years.datas.size()) { - throw new LinkyException("invalid consumptions data: not one data for each year period"); - } - } } 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 fe5b3095d3138..fc3c5e909b0e4 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 @@ -349,6 +349,7 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable if (api != null) { try { Consumption consumption = api.getEnergyData(userId, prmId, from, to); + checkData(consumption); updateStatus(ThingStatus.ONLINE); return consumption; } catch (LinkyException e) { @@ -365,6 +366,7 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable if (api != null) { try { Consumption consumption = api.getPowerData(userId, prmId, from, to); + checkData(consumption); updateStatus(ThingStatus.ONLINE); return consumption; } catch (LinkyException e) { @@ -437,6 +439,33 @@ public synchronized void handleCommand(ChannelUID channelUID, Command command) { } } + public void checkData(Consumption consumption) throws LinkyException { + if (consumption.aggregats.days.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no day period"); + } + if (consumption.aggregats.days.periodes.size() != consumption.aggregats.days.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each day period"); + } + if (consumption.aggregats.weeks.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no week period"); + } + if (consumption.aggregats.weeks.periodes.size() != consumption.aggregats.weeks.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each week period"); + } + if (consumption.aggregats.months.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no month period"); + } + if (consumption.aggregats.months.periodes.size() != consumption.aggregats.months.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each month period"); + } + if (consumption.aggregats.years.periodes.size() == 0) { + throw new LinkyException("invalid consumptions data: no year period"); + } + if (consumption.aggregats.years.periodes.size() != consumption.aggregats.years.datas.size()) { + throw new LinkyException("invalid consumptions data: not one data for each year period"); + } + } + private boolean isDataLastDayAvailable(Consumption consumption) { Aggregate days = consumption.aggregats.days; return days.datas != null && days.datas.size() > 0 && !days.datas.get(days.datas.size() - 1).isNaN(); From 0f2703ec2388e7e73fc4c870d506625b7fec073b Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 20:02:28 +0100 Subject: [PATCH 10/13] Minor changes to restore initial code Signed-off-by: Laurent Garnier --- .../org/openhab/binding/linky/internal/api/EnedisHttpApi.java | 3 ++- .../openhab/binding/linky/internal/dto/ConsumptionReport.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) 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 0a4739d912741..2f9a706ce6358 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 @@ -258,7 +258,8 @@ private Consumption getMeasures(String userId, String prmId, LocalDate from, Loc } logger.trace("getData returned {}", data); try { - return gson.fromJson(data, ConsumptionReport.class).firstLevel.consumptions; + ConsumptionReport report = gson.fromJson(data, ConsumptionReport.class); + return report.firstLevel.consumptions; } catch (JsonSyntaxException e) { logger.debug("invalid JSON response not matching ConsumptionReport.class: {}", data); throw new LinkyException( diff --git a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java index 0063547f50464..488ed24c54014 100644 --- a/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java +++ b/bundles/org.openhab.binding.linky/src/main/java/org/openhab/binding/linky/internal/dto/ConsumptionReport.java @@ -24,7 +24,6 @@ * @author Gaël L'hopital - Initial contribution */ public class ConsumptionReport { - public class Period { public String grandeurPhysiqueEnum; public ZonedDateTime dateDebut; From 96349ffc979fa7d6e3a14716ab46721e6c09a3e2 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 20:29:32 +0100 Subject: [PATCH 11/13] Minor change Signed-off-by: Laurent Garnier --- .../linky/internal/handler/LinkyHandler.java | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) 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 fc3c5e909b0e4..269f38e3f4747 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 @@ -93,11 +93,17 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.minusDays(15), today); if (consumption != null) { + try { + checkData(consumption); + } catch (LinkyException e) { + logger.debug("Daily data: {}", e.getMessage()); + return null; + } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); logData(consumption.aggregats.weeks, "Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { - logger.debug("Dayly data including yesterday are not yet available"); - consumption = null; + logger.debug("Daily data including yesterday are not yet available"); + return null; } } return consumption; @@ -106,18 +112,33 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC this.cachedPowerData = new ExpiringDayCache<>("power cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { LocalDate to = LocalDate.now().plusDays(1); LocalDate from = to.minusDays(2); - return getPowerData(from, to); + Consumption consumption = getPowerData(from, to); + if (consumption != null) { + try { + checkData(consumption); + } catch (LinkyException e) { + logger.debug("Power data: {}", e.getMessage()); + return null; + } + } + return consumption; }); this.cachedMonthlyData = new ExpiringDayCache<>("monthly cache", REFRESH_FIRST_HOUR_OF_DAY, () -> { LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { + try { + checkData(consumption); + } catch (LinkyException e) { + logger.debug("Monthly data: {}", e.getMessage()); + return null; + } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.months, "Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { logger.debug("Monthly data including yesterday are not yet available"); - consumption = null; + return null; } } return consumption; @@ -127,11 +148,17 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { + try { + checkData(consumption); + } catch (LinkyException e) { + logger.debug("Yearly data: {}", e.getMessage()); + return null; + } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.years, "Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); if (!isDataLastDayAvailable(consumption)) { logger.debug("Yearly data including yesterday are not yet available"); - consumption = null; + return null; } } return consumption; @@ -312,7 +339,9 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable Consumption result = getConsumptionData(startDay, endDay.plusDays(1)); if (result != null) { Aggregate days = result.aggregats.days; - for (int i = 0; i < days.datas.size(); i++) { + int size = (days.datas == null || days.periodes == null) ? 0 + : (days.datas.size() <= days.periodes.size() ? days.datas.size() : days.periodes.size()); + for (int i = 0; i < size; i++) { double consumption = days.datas.get(i); String line = days.periodes.get(i).dateDebut.format(DateTimeFormatter.ISO_LOCAL_DATE) + separator; if (consumption >= 0) { @@ -349,7 +378,6 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable if (api != null) { try { Consumption consumption = api.getEnergyData(userId, prmId, from, to); - checkData(consumption); updateStatus(ThingStatus.ONLINE); return consumption; } catch (LinkyException e) { @@ -366,7 +394,6 @@ private List buildReport(LocalDate startDay, LocalDate endDay, @Nullable if (api != null) { try { Consumption consumption = api.getPowerData(userId, prmId, from, to); - checkData(consumption); updateStatus(ThingStatus.ONLINE); return consumption; } catch (LinkyException e) { From 1d69d80105c38f5bfe695473fb708c0cb07da40f Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 20:54:11 +0100 Subject: [PATCH 12/13] New method for common code Signed-off-by: Laurent Garnier --- .../linky/internal/handler/LinkyHandler.java | 47 +++++++------------ 1 file changed, 17 insertions(+), 30 deletions(-) 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 269f38e3f4747..7b08d4e58edad 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 @@ -93,18 +93,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.minusDays(15), today); if (consumption != null) { - try { - checkData(consumption); - } catch (LinkyException e) { - logger.debug("Daily data: {}", e.getMessage()); - return null; - } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, false); logData(consumption.aggregats.weeks, "Week", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (!isDataLastDayAvailable(consumption)) { - logger.debug("Daily data including yesterday are not yet available"); - return null; - } + consumption = getConsumptionAfterChecks(consumption); } return consumption; }); @@ -128,18 +119,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { - try { - checkData(consumption); - } catch (LinkyException e) { - logger.debug("Monthly data: {}", e.getMessage()); - return null; - } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.months, "Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (!isDataLastDayAvailable(consumption)) { - logger.debug("Monthly data including yesterday are not yet available"); - return null; - } + consumption = getConsumptionAfterChecks(consumption); } return consumption; }); @@ -148,18 +130,9 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { - try { - checkData(consumption); - } catch (LinkyException e) { - logger.debug("Yearly data: {}", e.getMessage()); - return null; - } logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.years, "Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); - if (!isDataLastDayAvailable(consumption)) { - logger.debug("Yearly data including yesterday are not yet available"); - return null; - } + consumption = getConsumptionAfterChecks(consumption); } return consumption; }); @@ -466,6 +439,20 @@ public synchronized void handleCommand(ChannelUID channelUID, Command command) { } } + private @Nullable Consumption getConsumptionAfterChecks(Consumption consumption) { + try { + checkData(consumption); + } catch (LinkyException e) { + logger.debug("Consumption data: {}", e.getMessage()); + return null; + } + if (!isDataLastDayAvailable(consumption)) { + logger.debug("Data including yesterday are not yet available"); + return null; + } + return consumption; + } + public void checkData(Consumption consumption) throws LinkyException { if (consumption.aggregats.days.periodes.size() == 0) { throw new LinkyException("invalid consumptions data: no day period"); From 96f594020ddd1a88c65ec90e49abf0db6c0e4cc0 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Mon, 28 Dec 2020 21:10:43 +0100 Subject: [PATCH 13/13] Log last day at the right place Signed-off-by: Laurent Garnier --- .../openhab/binding/linky/internal/handler/LinkyHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 7b08d4e58edad..f2badd66e6f3f 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 @@ -119,7 +119,6 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(today.withDayOfMonth(1).minusMonths(1), today); if (consumption != null) { - logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.months, "Month", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); consumption = getConsumptionAfterChecks(consumption); } @@ -130,7 +129,6 @@ public LinkyHandler(Thing thing, LocaleProvider localeProvider, Gson gson, HttpC LocalDate today = LocalDate.now(); Consumption consumption = getConsumptionData(LocalDate.of(today.getYear() - 1, 1, 1), today); if (consumption != null) { - logData(consumption.aggregats.days, "Day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); logData(consumption.aggregats.years, "Year", true, DateTimeFormatter.ISO_LOCAL_DATE_TIME, false); consumption = getConsumptionAfterChecks(consumption); } @@ -482,6 +480,7 @@ public void checkData(Consumption consumption) throws LinkyException { private boolean isDataLastDayAvailable(Consumption consumption) { Aggregate days = consumption.aggregats.days; + logData(days, "Last day", false, DateTimeFormatter.ISO_LOCAL_DATE, true); return days.datas != null && days.datas.size() > 0 && !days.datas.get(days.datas.size() - 1).isNaN(); }