From 2755e63b878ab152bdb0ddeff29e9863368af750 Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Mon, 22 Nov 2021 10:33:44 +0100 Subject: [PATCH 1/7] added new device "Blind" to "Device" added missing element "Alert" to "Device" Fixed NPE when "switchstate" is null in "Device" --- .../fritzbox/model/homeautomation/Alert.java | 47 +++++++++++++++++++ .../fritzbox/model/homeautomation/Blind.java | 47 +++++++++++++++++++ .../fritzbox/model/homeautomation/Device.java | 21 +++++++-- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java create mode 100644 src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java new file mode 100644 index 0000000..d05feeb --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java @@ -0,0 +1,47 @@ +/** + * A Java API for managing FritzBox HomeAutomation + * Copyright (C) 2017 Christoph Pirkl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.github.kaklakariada.fritzbox.model.homeautomation; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "alert") +public class Alert { + + @Element(name = "state", required = false) + private int state; + + @Element(name = "lastalertchgtimestamp", required = false) + private long lastalertchgtimestamp; + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public long getlastalertchgtimestamp() { + return lastalertchgtimestamp; + } + + public void setlastalertchgtimestamp(long lastalertchgtimestamp) { + this.lastalertchgtimestamp = lastalertchgtimestamp; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java new file mode 100644 index 0000000..6704958 --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java @@ -0,0 +1,47 @@ +/** + * A Java API for managing FritzBox HomeAutomation + * Copyright (C) 2017 Christoph Pirkl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.github.kaklakariada.fritzbox.model.homeautomation; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "blind") +public class Blind { + + @Element(name = "endpositionsset", required = false) + private int endpositionsset; + + @Element(name = "mode", required = false) + private String mode; + + public int getEndpositionsset() { + return endpositionsset; + } + + public void setEndpositionsset(int endpositionsset) { + this.endpositionsset = endpositionsset; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Device.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Device.java index 7b3a145..ea4fde2 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Device.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Device.java @@ -17,11 +17,14 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import org.simpleframework.xml.*; - import java.util.List; import java.util.Optional; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + @Root(name = "device") public class Device { @@ -70,6 +73,10 @@ public class Device { private List + + + + + + 1 + 0 + Arbeitszimmer + 90 + 0 + + 185 + 0 + + + 37 + 38 + 32 + 38 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 90 + + 1637697600 + 32 + + 0 + 0 + + + + 1 + 0 + Waschküche + 80 + 0 + + 155 + 0 + + + 31 + 28 + 28 + 36 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 80 + + 1637740800 + 36 + + 0 + 0 + + + + 1 + 0 + Esszimmer + 70 + 0 + + 220 + 0 + + + 44 + 43 + 32 + 43 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 70 + + 1637701200 + 32 + + 0 + 0 + + + + 1 + 0 + Wohnzimmer + 70 + 0 + + 220 + 0 + + + 39 + 42 + 32 + 42 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 70 + + 1637701200 + 32 + + 0 + 0 + + + + 1 + 0 + Arbeitszimmer + + + 1 + 0 + Arbeitszimmer + + 1 + auto + + + 255 + 100 + + + 406 + 281 + 256,513,516,517 + + + 0 + 1637652112 + + + \ No newline at end of file diff --git a/src/test/resources/FritzOS29/deviceListFritzDectBlind.xml b/src/test/resources/FritzOS29/deviceListFritzDectBlind.xml new file mode 100644 index 0000000..61e5967 --- /dev/null +++ b/src/test/resources/FritzOS29/deviceListFritzDectBlind.xml @@ -0,0 +1,29 @@ + + + 1 + 0 + Arbeitszimmer + + + 1 + 0 + Arbeitszimmer + + 1 + auto + + + 255 + 100 + + + 406 + 281 + 256,513,516,517 + + + 0 + 1637652112 + + + \ No newline at end of file diff --git a/src/test/resources/FritzOS29/devicestatsFritzDect200.xml b/src/test/resources/FritzOS29/devicestatsFritzDect200.xml new file mode 100644 index 0000000..89e3152 --- /dev/null +++ b/src/test/resources/FritzOS29/devicestatsFritzDect200.xml @@ -0,0 +1,15 @@ + + + 185,185,185,185,180,175,175,180,180,185,180,180,180,175,180,180,175,175,175,175,175,175,175,175,175,175,175,175,180,180,180,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195 + + + 237365,237365,237365,237365,237365,237365,237365,237365,237365,237365,237365,237365,238842,238722,238789,238566,238757,238321,238046,238438,238607,238180,237981,238107,238107,238107,238107,238107,238107,238000,238000,238000,238000,238000,238000,238000,238000,238000,238000,238000,238000,238184,238184,238184,238184,238184,238184,238184,238184,238184,238184,238184,238184,238866,238866,238866,238866,238866,238866,238866,238866,238866,238866,238866,238866,238672,238672,238672,238672,238672,238672,238672,238672,238672,238672,238672,238672,238270,238270,238270,238270,238270,238270,238270,238270,238270,238270,238270,238270,239305,239305,239305,239305,239305,239305,239305,239305,239305,239305,239305,239305,238870,238870,238870,238870,238870,238870,238870,238870,238870,238870,238870,238870,239420,239420,239420,239420,239420,239420,239420,239420,239420,239420,239420,239420,239200,239200,239200,239200,239200,239200,239200,239200,239200,239200,239200,239200,238688,238688,238688,238688,238688,238688,238688,238688,238688,238688,238688,238688,238561,238561,238561,238561,238561,238561,238561,238561,238561,238561,238561,238561,238289,238289,238289,238289,238289,238289,238289,238289,238289,238289,238289,238289,238737,238737,238737,238737,238737,238737,238737,238737,238737,238737,238737,238737,238746,238746,238746,238746,238746,238746,238746,238746,238746,238746,238746,238746,238815,238815,238815,238815,238815,238815,238815,238815,238815,238815,238815,238815,238759,238759,238759,238759,238759,238759,238759,238759,238759,238759,238759,238759,238682,238682,238682,238682,238682,238682,238682,238682,238682,238682,238682,238682,238269,238269,238269,238269,238269,238269,238269,238269,238269,238269,238269,238269,237837,237837,237837,237837,237837,237837,237837,237837,237837,237837,237837,237837,238157,238157,238157,238157,238157,238157,238157,238157,238157,238157,238157,238157,238157,238562,238174,238401,238554,238438,238522,238309,238500,238658,238553,238628,238821,238821,238821,238821,238821,238821,238821,238821,238821,238821,238821,238821,237980,237980,237980,237980,237980,237980,237980,237980,237980,237980,237980,237980,237784,237784,237784,237784,237784,237784,237784,237784,237784,237784,237784,237784,237518,237518,237518,237518,237518,237518,237518,237518,237518,237518,237518,237518,237372,237372,237372,237372,237372,237372,237372,237372,237372,237372,237372,237372,237627,237627,237627,237627,237627,237627,237627,237627,237627,237627,237627,237627,237936,237936,237936,237936,237936,237936,237936 + + + 250,250,250,250,250,250,250,250,250,250,250,250,243,250,250,250,250,250,250,250,250,250,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,243,243,243,243,243,243,243,243,243,243,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,243,243,243,243,243,243,243,243,243,243,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,250,250,250,250,243,250,250,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,243,243,243,243,243,243,243,243,243,243,243,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,243,243,243,243,243,243,243 + + + 447,0,0,0,0,0,0,0,0,0,0,0 + 30,307,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + \ No newline at end of file diff --git a/src/test/resources/FritzOS29/devicestatsFritzDect301.xml b/src/test/resources/FritzOS29/devicestatsFritzDect301.xml new file mode 100644 index 0000000..1bed16f --- /dev/null +++ b/src/test/resources/FritzOS29/devicestatsFritzDect301.xml @@ -0,0 +1,5 @@ + + + 190,190,190,190,190,195,190,190,190,190,190,190,190,190,195,190,185,190,190,190,190,190,185,190,190,190,190,190,190,190,190,190,190,185,190,190,190,185,185,190,190,185,185,190,185,185,185,185,180,170,160,160,160,160,160,160,160,165,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- + + \ No newline at end of file diff --git a/src/test/resources/FritzOS29/devicestatsFritzDect440.xml b/src/test/resources/FritzOS29/devicestatsFritzDect440.xml new file mode 100644 index 0000000..e8af7b6 --- /dev/null +++ b/src/test/resources/FritzOS29/devicestatsFritzDect440.xml @@ -0,0 +1,8 @@ + + + 220,220,220,220,220,220,220,215,215,215,215,215,215,215,215,220,220,220,220,220,220,220,220,220,215,215,215,210,215,215,215,215,210,210,210,205,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- + + + 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,40,40,40,40,37,37,37,37,37,35,35,35,34,42,42,42,42,41,41,41,41,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- + + \ No newline at end of file From 6b9735137af41c2a4581a81570458fd200b7f325 Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Fri, 26 Nov 2021 11:45:23 +0100 Subject: [PATCH 3/7] Refactor retrieval and calculation of device statistics. The caller now can get the normalized values, does not need to calculate by itself --- .../kaklakariada/fritzbox/TestDriver.java | 55 ++++++++++------- .../AbstractDeviceStatistics.java | 60 +++++++++++++++++++ .../model/homeautomation/DeviceStats.java | 10 ++-- .../fritzbox/model/homeautomation/Energy.java | 4 +- .../model/homeautomation/Humidity.java | 4 +- .../homeautomation/MEASUREMENT_UNIT.java | 38 ++++++++++-- .../fritzbox/model/homeautomation/Power.java | 4 +- .../model/homeautomation/Statistics.java | 48 +++++++++++++++ .../homeautomation/StatisticsInterface.java | 19 ------ .../model/homeautomation/Temperature.java | 4 +- .../model/homeautomation/Voltage.java | 4 +- 11 files changed, 191 insertions(+), 59 deletions(-) create mode 100644 src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java delete mode 100644 src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsInterface.java diff --git a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java index 049d8a2..190718e 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import com.github.kaklakariada.fritzbox.EnergyStatisticsService.EnergyStatsTimeRange; +import com.github.kaklakariada.fritzbox.model.homeautomation.AbstractDeviceStatistics; import com.github.kaklakariada.fritzbox.model.homeautomation.Device; import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; import com.github.kaklakariada.fritzbox.model.homeautomation.Energy; @@ -71,6 +72,7 @@ public static void main(String[] args) throws InterruptedException { // testEnergyStats(homeAutomation, devices.getDevices().get(0).getId()); testEnergyStatsNew(homeAutomation, ain); + testVoltageStatsNew(homeAutomation, ain); testHomeAutomation(homeAutomation, ain); } @@ -83,42 +85,55 @@ private static void testEnergyStats(HomeAutomation homeAutomation, String device } private static void testEnergyStatsNew(HomeAutomation homeAutomation, String ain) { - final Optional energy = homeAutomation.getBasicStatistics(ain).getEnergy(); + final Optional energy = homeAutomation.getBasicStatistics(ain).getEnergy(); if (energy.isEmpty()) { LOG.error("No Statistics for energy consumption gathered"); return; } - Optional dailyEnergy = energy.get().getStats() - .stream() - .filter(stats -> stats.getGrid() == 86400) - .findAny(); + Optional dailyEnergy = energy.get().getStatisticsByGrid(86400); if (dailyEnergy.isEmpty()) { LOG.error("No Statistics for energy consumption 'per day' gathered"); return; } MEASUREMENT_UNIT measurementUnit = dailyEnergy.get().getMeasurementUnit(); - List dailyConsumption = Arrays.asList(dailyEnergy.get().getCsvValues().split(",")) - .stream() - .map(aDay -> { - if (StringUtils.isNumeric(aDay.trim())) { - Integer intValue = Integer.valueOf(aDay.trim()); - Double doubleValue = Double.valueOf(intValue*measurementUnit.getPrescision()); - return doubleValue; - } - return null; - }) - .collect(Collectors.toList()); + List> dailyConsumption = dailyEnergy.get().getValues(); StringBuffer sb = new StringBuffer(); - for (final Double dailyValue : dailyConsumption) { - if (dailyValue != null) { - sb.append(dailyValue).append(measurementUnit.getUnit()).append(" "); + for (final Optional dailyValue : dailyConsumption) { + if (dailyValue.isPresent()) { + sb.append(dailyValue.get()).append(measurementUnit.getUnit()).append(" "); } else { sb.append("-").append(" "); } } - LOG.debug("Statistics dails energy consumption: {}", sb.toString()); + LOG.debug("Statistics daily energy consumption: {}", sb.toString()); } + + private static void testVoltageStatsNew(HomeAutomation homeAutomation, String ain) { + final Optional power = homeAutomation.getBasicStatistics(ain).getPower(); + if (power.isEmpty()) { + LOG.error("No Statistics for power consumption gathered"); + return; + } + Optional sixMinsVoltage = power.get().getStatisticsByGrid(10); + if (sixMinsVoltage.isEmpty()) { + LOG.error("No Statistics for power consumption 'per 10 seconds interval' gathered"); + return; + } + MEASUREMENT_UNIT measurementUnit = sixMinsVoltage.get().getMeasurementUnit(); + List> sixMinutestConsumption = sixMinsVoltage.get().getValues(); + + StringBuffer sb = new StringBuffer(); + for (final Optional intervalValue : sixMinutestConsumption) { + if (intervalValue.isPresent()) { + sb.append(intervalValue.get()).append(measurementUnit.getUnit()).append(" "); + } else { + sb.append("-").append(" "); + } + } + LOG.debug("Statistics power detetcted: {}", sb.toString()); + } + private static void testHomeAutomation(final HomeAutomation homeAutomation, final String ain) throws InterruptedException { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java new file mode 100644 index 0000000..fcd89cf --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java @@ -0,0 +1,60 @@ +package com.github.kaklakariada.fritzbox.model.homeautomation; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public abstract class AbstractDeviceStatistics { + + /** + * Supply grids used to gather statistics + * @return + */ + public List getGridList() { + final List gridList = getStats() + .stream() + .map(stats -> stats.getGrid()) + .collect(Collectors.toList()); + + return gridList; + }; + + /** + * Supply the Statistics gathered for a chosen grid + * @param grid + * @return + */ + public Optional getStatisticsByGrid(final int grid) { + Optional statisticsByGrid = getStats() + .stream() + .filter(stats -> stats.getGrid() == grid) + .findAny(); + + return statisticsByGrid; + }; + + /** + * Alle classes implementing this abstract class need to provide a "getStats"-method + * @return + */ + public abstract List getStats(); + + /** + * AVM gathers just integer numbers. We know the precision only from documentation, it is never provided + * by returned responses from Fritz!Box. + * So we add this information here to the statistics. + * @param stats + * @param measurementUnit + * @return + */ + protected List getStats(final List stats, final MEASUREMENT_UNIT measurementUnit) { + final List markedStats = stats + .stream() + .map(stat -> { + stat.setMeasurementUnit(measurementUnit); + return stat; + }) + .collect(Collectors.toList()); + return markedStats; + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java index 80a3883..6863065 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java @@ -40,19 +40,19 @@ public class DeviceStats { @Element(name = "humidity", type = Humidity.class, required = false) private Humidity humidity; - public Optional getTemperature() { + public Optional getTemperature() { return Optional.ofNullable(temperature); } - public Optional getVoltage() { + public Optional getVoltage() { return Optional.ofNullable(voltage); } - public Optional getPower() { + public Optional getPower() { return Optional.ofNullable(power); } - public Optional getEnergy() { + public Optional getEnergy() { return Optional.ofNullable(energy); } - public Optional getHumidity() { + public Optional getHumidity() { return Optional.ofNullable(humidity); } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java index b3429a1..37d6ffd 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java @@ -23,12 +23,12 @@ import org.simpleframework.xml.Root; @Root(name = "energy") -public class Energy implements StatisticsInterface { +public class Energy extends AbstractDeviceStatistics { @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, this.getClass()) ; + return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java index 33595eb..52898bd 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java @@ -24,7 +24,7 @@ import org.simpleframework.xml.Root; @Root(name = "humidity") -public class Humidity implements StatisticsInterface { +public class Humidity extends AbstractDeviceStatistics { @Element(name = "rel_humidity", required = false) private int relHumidity; @@ -37,6 +37,6 @@ public int getRelHumidity() { } public List getStats() { - return getStats(stats, this.getClass()) ; + return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java index 9b5549b..a045a9d 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java @@ -1,17 +1,45 @@ +/** + * A Java API for managing FritzBox HomeAutomation + * Copyright (C) 2017 Christoph Pirkl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.github.kaklakariada.fritzbox.model.homeautomation; +/** + * provide the measurement unit to be used with the statistics.

+ * Consists of: + *

  • measurment unit [V, W, Wh, %]
  • + *
  • precision as double to multiply with the gathered Integer
  • + * Sample: The Voltage is measured in 'V' (Volt) and has a precision of '0.001'. The number 237123 provided + * by the statistics must be multiplied by the precision which gives us 237.123 V. + * + * @author Ulrich Schmidt(Gombers) + * + */ public enum MEASUREMENT_UNIT { TEMPERATURE("C", 0.1, Temperature.class), VOLTAGE("V", 0.001, Voltage.class), POWER("W", 0.01, Power.class), - ENERGY("Wh", 1D, Energy.class), - HUMIDITY("%", 1D, Humidity.class); + ENERGY("Wh", 1, Energy.class), + HUMIDITY("%", 1, Humidity.class); private final String unit; - private final Double precision; + private final Number precision; private final Class mapper; - MEASUREMENT_UNIT(String unit, Double precision, Class mapper) { + MEASUREMENT_UNIT(String unit, Number precision, Class mapper) { this.unit = unit; this.precision = precision; this.mapper = mapper; @@ -21,7 +49,7 @@ public String getUnit() { return unit; } - public Double getPrescision() { + public Number getPrescision() { return precision; } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java index 7b817f2..e79da76 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java @@ -23,12 +23,12 @@ import org.simpleframework.xml.Root; @Root(name = "power") -public class Power implements StatisticsInterface { +public class Power extends AbstractDeviceStatistics { @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, this.getClass()) ; + return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java index 117f181..a721548 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java @@ -17,6 +17,12 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Root; import org.simpleframework.xml.Text; @@ -43,10 +49,36 @@ public int getGrid() { return grid; } + /** + * provide the gathered data as provided by Fritz!Box + * @return + */ public String getCsvValues() { return csvValues; } + /** + * provide the gathered data as computed as meant to be used by AVM + * @return + */ + public List> getValues() { + List> valueComputed = Arrays.asList(getCsvValues().split(",")) + .stream() + .map(aValue -> Optional.ofNullable(computeValue(aValue))) + .collect(Collectors.toList()); + return valueComputed; + } + + /** + * provide the measurement unit to be used with the statistics.

    + * Consists of: + *

  • measurment unit [V, W, Wh, %]
  • + *
  • precision as double to multiply with the gathered Integer
  • + * Sample: The Voltage is measured in 'V' (Volt) and has a precision of '0.001'. The number 237123 provided + * by the statistics must be multiplied by the precision which gives us 237.123 V. + * + * @return + */ public MEASUREMENT_UNIT getMeasurementUnit() { return measurementUnit; } @@ -54,4 +86,20 @@ public MEASUREMENT_UNIT getMeasurementUnit() { public void setMeasurementUnit(final MEASUREMENT_UNIT measurementUnit) { this.measurementUnit = measurementUnit; } + + private Number computeValue(String aValue) { + Number numberValue = null; + if (StringUtils.isNumeric(aValue.trim())) { + Integer intValue = Integer.valueOf(aValue.trim()); + if (measurementUnit.getPrescision() instanceof Double) { + numberValue = Double.valueOf(intValue*(Double)measurementUnit.getPrescision()); + } else { + numberValue = Integer.valueOf(intValue*(Integer)measurementUnit.getPrescision()); + } + return numberValue; + } + return null; + } + + } \ No newline at end of file diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsInterface.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsInterface.java deleted file mode 100644 index a2def4d..0000000 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsInterface.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.github.kaklakariada.fritzbox.model.homeautomation; - -import java.util.List; -import java.util.stream.Collectors; - -public interface StatisticsInterface { - default List getStats(List stats, Class caller) { - - final List markedStats = stats - .stream() - .map(stat -> { - stat.setMeasurementUnit(MEASUREMENT_UNIT.getMatchingMeasurementUnit(caller)); - return stat; - }) - .collect(Collectors.toList()); - return markedStats; - } - -} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java index 4d9800e..cda26a6 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java @@ -24,7 +24,7 @@ import org.simpleframework.xml.Root; @Root(name = "temperature") -public class Temperature implements StatisticsInterface { +public class Temperature extends AbstractDeviceStatistics { @Element(name = "celsius", required = false) private int deciCelsius; @@ -40,7 +40,7 @@ public float getCelsius() { } public List getStats() { - return getStats(stats, this.getClass()) ; + return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; } @Override diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java index 620ff76..7fc66c1 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java @@ -23,12 +23,12 @@ import org.simpleframework.xml.Root; @Root(name = "voltage") -public class Voltage implements StatisticsInterface { +public class Voltage extends AbstractDeviceStatistics { @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, this.getClass()) ; + return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; } } From c8b446e9964080b4e11ffca191b6b957f579d6ae Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Fri, 26 Nov 2021 17:08:29 +0100 Subject: [PATCH 4/7] Remove erroneously add class 'GatherStatisticsMain.java' --- .../fritzbox/main/GatherStatisticsMain.java | 107 ------------------ 1 file changed, 107 deletions(-) delete mode 100644 src/main/java/de/gombers/smarthome/fritzbox/main/GatherStatisticsMain.java diff --git a/src/main/java/de/gombers/smarthome/fritzbox/main/GatherStatisticsMain.java b/src/main/java/de/gombers/smarthome/fritzbox/main/GatherStatisticsMain.java deleted file mode 100644 index 484a4bf..0000000 --- a/src/main/java/de/gombers/smarthome/fritzbox/main/GatherStatisticsMain.java +++ /dev/null @@ -1,107 +0,0 @@ -package de.gombers.smarthome.fritzbox.main; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.github.kaklakariada.fritzbox.EnergyStatisticsService; -import com.github.kaklakariada.fritzbox.FritzBoxException; -import com.github.kaklakariada.fritzbox.HomeAutomation; -import com.github.kaklakariada.fritzbox.TestDriver; -import com.github.kaklakariada.fritzbox.EnergyStatisticsService.EnergyStatsTimeRange; -import com.github.kaklakariada.fritzbox.model.homeautomation.Device; -import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; -import com.github.kaklakariada.fritzbox.model.homeautomation.PowerMeter; - -public class GatherStatisticsMain { - private static final Logger LOG = LoggerFactory.getLogger(GatherStatisticsMain.class); - - public void process() { - - } - - public static void main(String[] args) throws InterruptedException { - final Properties config = readConfig(Paths.get("application.properties")); - final String url = config.getProperty("fritzbox.url"); - final String username = config.getProperty("fritzbox.username", null); - final String password = config.getProperty("fritzbox.password"); - - LOG.info("Logging in to '{}' with username '{}'", url, username); - final HomeAutomation homeAutomation = HomeAutomation.connect(url, username, password); - - final DeviceList devices = homeAutomation.getDeviceListInfos(); - LOG.info("Found {} devices", devices.getDevices().size()); - for (final Device device : devices.getDevices()) { - LOG.info("\t{}", device); - } - - final List ids = homeAutomation.getSwitchList(); - LOG.info("Found {} device ids: {}", ids.size(), ids); - - final String ain = devices.getDevices().get(7).getIdentifier(); -// testEnergyStats(homeAutomation, devices.getDevices().get(2).getId()); - testHomeAutomation(homeAutomation, ain); - } - - private static void testEnergyStats(HomeAutomation homeAutomation, String deviceId) { - final EnergyStatisticsService service = homeAutomation.getEnergyStatistics(); - for (final EnergyStatsTimeRange timeRange : EnergyStatsTimeRange.values()) { - final String energyStatistics = service.getEnergyStatistics(deviceId, timeRange); - LOG.debug("Statistics {}: {}", timeRange, energyStatistics); - } - } - - private static void testHomeAutomation(final HomeAutomation homeAutomation, final String ain) - throws InterruptedException { -// homeAutomation.switchPowerState(ain, false); -// homeAutomation.togglePowerState(ain); -// LOG.info("Switch {} has present state '{}'", ain, homeAutomation.getSwitchPresent(ain)); -// LOG.info("Switch {} has state '{}'", ain, homeAutomation.getSwitchState(ain)); -// LOG.info("Switch {} uses {}W", ain, homeAutomation.getSwitchPowerWatt(ain)); -// LOG.info("Switch {} has used {}Wh", ain, homeAutomation.getSwitchEnergyWattHour(ain)); -// LOG.info("Switch {} has name '{}'", ain, homeAutomation.getSwitchName(ain)); -// LOG.info("Switch {} has temperature {}°C", ain, homeAutomation.getTemperature(ain)); - LOG.info("Switch {} statistics '{}'", ain, homeAutomation.getBasicStatistics(ain)); - - while (true) { - final List devices = homeAutomation.getDeviceListInfos().getDevices(); - if (devices.isEmpty()) { - LOG.warn("No devices found"); - return; - } - devices.forEach(GatherStatisticsMain::logDeviceDetails); - Thread.sleep(1000); - } - } - - private static void logDeviceDetails(final Device device) { - final PowerMeter powerMeter = device.getPowerMeter(); - if (device.getSwitchState() == null) { - return; - } - final Object switchState = device.getSwitchState().isOn() ? "on" : "off"; - LOG.debug("State: {}, temp: {}°C, voltage: {}V, power: {}W, energy: {}Wh", - switchState, device.getTemperature().getCelsius(), powerMeter.getVoltageVolt(), - powerMeter.getPowerWatt(), powerMeter.getEnergyWattHours()); - } - - private static Properties readConfig(Path path) { - final Properties config = new Properties(); - final Path absolutePath = path.toAbsolutePath(); - LOG.debug("Reading config from file {}", absolutePath); - try (InputStream in = Files.newInputStream(absolutePath)) { - config.load(in); - } catch (final IOException e) { - throw new FritzBoxException("Error loading configuration from " + absolutePath, e); - } - return config; - } - -} From aef6d2aa0bf60113150e4448f8e7681c4a5e30f4 Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Tue, 30 Nov 2021 17:51:49 +0100 Subject: [PATCH 5/7] Fixing review findings as send per mail to me at Nov 30, 2021 from kaklakariada --- .../kaklakariada/fritzbox/HomeAutomation.java | 3 +- .../fritzbox/MissingClassException.java | 31 +++++++++++++ .../kaklakariada/fritzbox/TestDriver.java | 12 ++---- .../AbstractDeviceStatistics.java | 43 +++++++++++++++---- .../fritzbox/model/homeautomation/Alert.java | 10 ++--- .../fritzbox/model/homeautomation/Blind.java | 10 ++--- .../model/homeautomation/DeviceStats.java | 40 ++++++++++------- .../fritzbox/model/homeautomation/Energy.java | 9 +++- .../model/homeautomation/Humidity.java | 10 ++++- ...UREMENT_UNIT.java => MeasurementUnit.java} | 19 ++++---- .../fritzbox/model/homeautomation/Power.java | 10 ++++- .../model/homeautomation/Statistics.java | 15 +++---- .../model/homeautomation/Temperature.java | 14 ++++-- .../model/homeautomation/Voltage.java | 9 +++- 14 files changed, 161 insertions(+), 74 deletions(-) create mode 100644 src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java rename src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/{MEASUREMENT_UNIT.java => MeasurementUnit.java} (81%) diff --git a/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java b/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java index bf81c26..897f0c5 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java @@ -99,8 +99,7 @@ public Float getTemperature(String deviceAin) { } public DeviceStats getBasicStatistics(String deviceAin) { - final DeviceStats statsXml = executeDeviceCommand(deviceAin, "getbasicdevicestats", null, DeviceStats.class); - return statsXml; + return executeDeviceCommand(deviceAin, "getbasicdevicestats", null, DeviceStats.class); } public Float getSwitchPowerWatt(String deviceAin) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java b/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java new file mode 100644 index 0000000..ca21271 --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java @@ -0,0 +1,31 @@ +/** + * A Java API for managing FritzBox HomeAutomation + * Copyright (C) 2017 Christoph Pirkl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.github.kaklakariada.fritzbox; + +public class MissingClassException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public MissingClassException(String message, Throwable cause) { + super(message, cause); + } + + public MissingClassException(String message) { + super(message); + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java index 190718e..ca0fb2b 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java @@ -22,14 +22,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Properties; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +32,7 @@ import com.github.kaklakariada.fritzbox.model.homeautomation.AbstractDeviceStatistics; import com.github.kaklakariada.fritzbox.model.homeautomation.Device; import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; -import com.github.kaklakariada.fritzbox.model.homeautomation.Energy; -import com.github.kaklakariada.fritzbox.model.homeautomation.MEASUREMENT_UNIT; +import com.github.kaklakariada.fritzbox.model.homeautomation.MeasurementUnit; import com.github.kaklakariada.fritzbox.model.homeautomation.PowerMeter; import com.github.kaklakariada.fritzbox.model.homeautomation.Statistics; @@ -95,7 +89,7 @@ private static void testEnergyStatsNew(HomeAutomation homeAutomation, String ain LOG.error("No Statistics for energy consumption 'per day' gathered"); return; } - MEASUREMENT_UNIT measurementUnit = dailyEnergy.get().getMeasurementUnit(); + MeasurementUnit measurementUnit = dailyEnergy.get().getMeasurementUnit(); List> dailyConsumption = dailyEnergy.get().getValues(); StringBuffer sb = new StringBuffer(); @@ -120,7 +114,7 @@ private static void testVoltageStatsNew(HomeAutomation homeAutomation, String ai LOG.error("No Statistics for power consumption 'per 10 seconds interval' gathered"); return; } - MEASUREMENT_UNIT measurementUnit = sixMinsVoltage.get().getMeasurementUnit(); + MeasurementUnit measurementUnit = sixMinsVoltage.get().getMeasurementUnit(); List> sixMinutestConsumption = sixMinsVoltage.get().getValues(); StringBuffer sb = new StringBuffer(); diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java index fcd89cf..0c5fc4e 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java @@ -8,7 +8,7 @@ public abstract class AbstractDeviceStatistics { /** * Supply grids used to gather statistics - * @return + * @return List */ public List getGridList() { final List gridList = getStats() @@ -21,8 +21,8 @@ public List getGridList() { /** * Supply the Statistics gathered for a chosen grid - * @param grid - * @return + * @param int grid + * @return Optional - avoid NPE is no statistics present */ public Optional getStatisticsByGrid(final int grid) { Optional statisticsByGrid = getStats() @@ -34,8 +34,8 @@ public Optional getStatisticsByGrid(final int grid) { }; /** - * Alle classes implementing this abstract class need to provide a "getStats"-method - * @return + * All classes implementing this abstract class need to provide a "getStats"-method + * @return List */ public abstract List getStats(); @@ -45,16 +45,41 @@ public Optional getStatisticsByGrid(final int grid) { * So we add this information here to the statistics. * @param stats * @param measurementUnit - * @return + * @return List */ - protected List getStats(final List stats, final MEASUREMENT_UNIT measurementUnit) { - final List markedStats = stats + protected List getStats(final List stats, final MeasurementUnit measurementUnit) { + return stats .stream() .map(stat -> { stat.setMeasurementUnit(measurementUnit); return stat; }) .collect(Collectors.toList()); - return markedStats; + } + + /** + * All classes implementing this abstract class need to provide a "statisticsToString"-method + * @return List + */ + abstract protected List statisticsToString(); + + /** + * @return statistics as one line per grid + */ + protected List statisticsToString(final String type) { + return getStats() + .stream() + .map(stats -> statisticsToString(type, stats)) + .collect(Collectors.toList()); + } + + /** + * form a line from a single statistic + * @param type + * @param statistics + * @return statistic as a line + */ + protected String statisticsToString(final String type, final Statistics statistics) { + return String.format("[%s] count=%s,grid=%s values=[%s]", type, statistics.getCount(), statistics.getGrid(), statistics.getCsvValues()); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java index d05feeb..58fa446 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java @@ -27,7 +27,7 @@ public class Alert { private int state; @Element(name = "lastalertchgtimestamp", required = false) - private long lastalertchgtimestamp; + private long lastAlertChgTimestamp; public int getState() { return state; @@ -37,11 +37,11 @@ public void setState(int state) { this.state = state; } - public long getlastalertchgtimestamp() { - return lastalertchgtimestamp; + public long getLastAlertChgTimestamp() { + return lastAlertChgTimestamp; } - public void setlastalertchgtimestamp(long lastalertchgtimestamp) { - this.lastalertchgtimestamp = lastalertchgtimestamp; + public void setLastAlertChgTimestamp(long lastAlertChgTimestamp) { + this.lastAlertChgTimestamp = lastAlertChgTimestamp; } } \ No newline at end of file diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java index 6704958..03e3df6 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java @@ -24,17 +24,17 @@ public class Blind { @Element(name = "endpositionsset", required = false) - private int endpositionsset; + private int endPositionsSet; @Element(name = "mode", required = false) private String mode; - public int getEndpositionsset() { - return endpositionsset; + public int getEndPositionsSet() { + return endPositionsSet; } - public void setEndpositionsset(int endpositionsset) { - this.endpositionsset = endpositionsset; + public void setEndPositionsSet(int endPositionsSet) { + this.endPositionsSet = endPositionsSet; } public String getMode() { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java index 6863065..5728a36 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceStats.java @@ -17,6 +17,8 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import org.simpleframework.xml.Element; @@ -57,19 +59,27 @@ public Optional getHumidity() { } - // @Override - // public String toString() { - // final StringBuffer sb = new StringBuffer(); - // sb.append(String.format("Temperature %s values", - // temperature != null ? temperature.getStats().getCount() : "none")); - // sb.append(", "); - // sb.append(String.format("Voltage %s values", voltage != null ? voltage.getStats().getCount() : "none")); - // sb.append(", "); - // sb.append(String.format("Power %s values", power != null ? power.getStats().getCount() : "none")); - // sb.append(", "); - // sb.append(String.format("Energy %s values", energy != null ? energy.getStats().get(0).getCount() : "none")); - // sb.append(", "); - // sb.append(String.format("Humidity %s values", humidity != null ? humidity.getStats().getCount() : "none")); - // return "Basic Device Statistcs [" + sb.toString() + "]"; - // } + @Override + public String toString() { + List allStatistics = new ArrayList<>(); + if (getTemperature().isPresent()) { + allStatistics.addAll(getTemperature().get().statisticsToString()); + } + if (getVoltage().isPresent()) { + allStatistics.addAll(getVoltage().get().statisticsToString()); + } + if (getPower().isPresent()) { + allStatistics.addAll(getPower().get().statisticsToString()); + } + if (getEnergy().isPresent()) { + allStatistics.addAll(getEnergy().get().statisticsToString()); + } + if (getHumidity().isPresent()) { + allStatistics.addAll(getHumidity().get().statisticsToString()); + } + final StringBuffer sb = new StringBuffer(); + sb.append(" ---> ").append("\n\n\tStatistics").append("\n\t==========\n"); + allStatistics.forEach(stats -> sb.append("\t").append(stats).append("\n")); + return sb.toString(); + } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java index 37d6ffd..ef8e38a 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Energy.java @@ -24,11 +24,16 @@ @Root(name = "energy") public class Energy extends AbstractDeviceStatistics { - + @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; + } + + @Override + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java index 52898bd..c33f1ad 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Humidity.java @@ -25,7 +25,7 @@ @Root(name = "humidity") public class Humidity extends AbstractDeviceStatistics { - + @Element(name = "rel_humidity", required = false) private int relHumidity; @@ -37,6 +37,12 @@ public int getRelHumidity() { } public List getStats() { - return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; + } + + @Override + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); } + } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java similarity index 81% rename from src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java rename to src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java index a045a9d..2c08ea7 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MEASUREMENT_UNIT.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java @@ -17,18 +17,22 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; +import com.github.kaklakariada.fritzbox.MissingClassException; + /** * provide the measurement unit to be used with the statistics.

    * Consists of: + *

      *
    • measurment unit [V, W, Wh, %]
    • - *
    • precision as double to multiply with the gathered Integer
    • + *
    • precision as double to multiply with the gathered Integerv + *
    * Sample: The Voltage is measured in 'V' (Volt) and has a precision of '0.001'. The number 237123 provided * by the statistics must be multiplied by the precision which gives us 237.123 V. * * @author Ulrich Schmidt(Gombers) * */ -public enum MEASUREMENT_UNIT { +public enum MeasurementUnit { TEMPERATURE("C", 0.1, Temperature.class), VOLTAGE("V", 0.001, Voltage.class), POWER("W", 0.01, Power.class), @@ -39,7 +43,7 @@ public enum MEASUREMENT_UNIT { private final Number precision; private final Class mapper; - MEASUREMENT_UNIT(String unit, Number precision, Class mapper) { + MeasurementUnit(String unit, Number precision, Class mapper) { this.unit = unit; this.precision = precision; this.mapper = mapper; @@ -57,15 +61,12 @@ public Class getMapper() { return mapper; } - public static MEASUREMENT_UNIT getMatchingMeasurementUnit(Class caller) { - for (MEASUREMENT_UNIT iterator : MEASUREMENT_UNIT.values()) { + public static MeasurementUnit getMatchingMeasurementUnit(Class caller) { + for (MeasurementUnit iterator : MeasurementUnit.values()) { if (caller.getSimpleName().equals(iterator.getMapper().getSimpleName())) { return iterator; } } - return null; - + throw new MissingClassException(String.format("Could not detect enum of type 'MeasurementUnit' associated to class '%s'", caller.toString())); } - - } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java index e79da76..2b81520 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Power.java @@ -24,11 +24,17 @@ @Root(name = "power") public class Power extends AbstractDeviceStatistics { - + @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; + } + + @Override + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); } + } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java index a721548..235865e 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java @@ -30,7 +30,7 @@ @Root(name = "stats") public class Statistics { - private MEASUREMENT_UNIT measurementUnit; + private MeasurementUnit measurementUnit; @Attribute(name = "count", required = false) private int count; @@ -50,7 +50,7 @@ public int getGrid() { } /** - * provide the gathered data as provided by Fritz!Box + * Provide the gathered data as provided by Fritz!Box * @return */ public String getCsvValues() { @@ -58,19 +58,18 @@ public String getCsvValues() { } /** - * provide the gathered data as computed as meant to be used by AVM + * Provide the gathered data as computed as meant to be used by AVM * @return */ public List> getValues() { - List> valueComputed = Arrays.asList(getCsvValues().split(",")) + return Arrays.asList(getCsvValues().split(",")) .stream() .map(aValue -> Optional.ofNullable(computeValue(aValue))) .collect(Collectors.toList()); - return valueComputed; } /** - * provide the measurement unit to be used with the statistics.

    + * Provide the measurement unit to be used with the statistics.

    * Consists of: *

  • measurment unit [V, W, Wh, %]
  • *
  • precision as double to multiply with the gathered Integer
  • @@ -79,11 +78,11 @@ public List> getValues() { * * @return */ - public MEASUREMENT_UNIT getMeasurementUnit() { + public MeasurementUnit getMeasurementUnit() { return measurementUnit; } - public void setMeasurementUnit(final MEASUREMENT_UNIT measurementUnit) { + public void setMeasurementUnit(final MeasurementUnit measurementUnit) { this.measurementUnit = measurementUnit; } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java index cda26a6..97a49d2 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Temperature.java @@ -18,14 +18,13 @@ package com.github.kaklakariada.fritzbox.model.homeautomation; import java.util.List; - import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root(name = "temperature") public class Temperature extends AbstractDeviceStatistics { - + @Element(name = "celsius", required = false) private int deciCelsius; @@ -40,11 +39,18 @@ public float getCelsius() { } public List getStats() { - return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; } @Override public String toString() { - return "Temperatur [celsius=" + getCelsius() + "]"; + return "Temperature [celsius=" + getCelsius() + "]"; } + + @Override + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); + } + + } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java index 7fc66c1..96b500e 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Voltage.java @@ -24,11 +24,16 @@ @Root(name = "voltage") public class Voltage extends AbstractDeviceStatistics { - + @ElementList(name = "stats", required = false, inline = true) private List stats; public List getStats() { - return getStats(stats, MEASUREMENT_UNIT.getMatchingMeasurementUnit(this.getClass())) ; + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; + } + + @Override + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); } } From de8cea4ac187fd050e42fe2ea928202609293ad6 Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Thu, 2 Dec 2021 22:23:25 +0100 Subject: [PATCH 6/7] Remove apache.commons-lang3 from dependencies. Add Junit-Test for Statistics.java --- build.gradle | 2 +- .../model/homeautomation/Statistics.java | 34 ++++++++++-- .../model/homeautomation/StatisticsTest.java | 53 +++++++++++++++++++ 3 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java diff --git a/build.gradle b/build.gradle index a8a2a65..3a315d1 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,6 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.1' implementation 'com.subshell.simpleframework:simple-xml:2.9.0' implementation 'org.slf4j:slf4j-api:1.7.32' - implementation 'org.apache.commons:commons-lang3:3.12.0' runtimeOnly 'ch.qos.logback:logback-classic:1.2.5' @@ -120,6 +119,7 @@ publishing { } } + signing { sign publishing.publications.mavenJava } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java index 235865e..831da6c 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java @@ -17,12 +17,12 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Root; import org.simpleframework.xml.Text; @@ -56,12 +56,24 @@ public int getGrid() { public String getCsvValues() { return csvValues; } + + /** + * Just for unit test provided. + * Therefore it is set to protected + * @return + */ + protected void setCsvValues(String csvValues) { + this.csvValues = csvValues; + } /** * Provide the gathered data as computed as meant to be used by AVM * @return */ public List> getValues() { + if (getCsvValues() == null) { + return new ArrayList<>(); + } return Arrays.asList(getCsvValues().split(",")) .stream() .map(aValue -> Optional.ofNullable(computeValue(aValue))) @@ -71,8 +83,10 @@ public List> getValues() { /** * Provide the measurement unit to be used with the statistics.

    * Consists of: + *

      *
    • measurment unit [V, W, Wh, %]
    • *
    • precision as double to multiply with the gathered Integer
    • + *
    * Sample: The Voltage is measured in 'V' (Volt) and has a precision of '0.001'. The number 237123 provided * by the statistics must be multiplied by the precision which gives us 237.123 V. * @@ -86,19 +100,31 @@ public void setMeasurementUnit(final MeasurementUnit measurementUnit) { this.measurementUnit = measurementUnit; } - private Number computeValue(String aValue) { + protected Number computeValue(String aValue) { Number numberValue = null; - if (StringUtils.isNumeric(aValue.trim())) { + if (isIntegerNumber(aValue)) { Integer intValue = Integer.valueOf(aValue.trim()); if (measurementUnit.getPrescision() instanceof Double) { numberValue = Double.valueOf(intValue*(Double)measurementUnit.getPrescision()); } else { - numberValue = Integer.valueOf(intValue*(Integer)measurementUnit.getPrescision()); + numberValue = Integer.valueOf(intValue * (Integer)measurementUnit.getPrescision()); } return numberValue; } return null; } + + protected boolean isIntegerNumber(String aValue) { + if (aValue == null) { + return false; + } + try { + Integer.parseInt(aValue.trim()); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } } \ No newline at end of file diff --git a/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java b/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java new file mode 100644 index 0000000..a509c8a --- /dev/null +++ b/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java @@ -0,0 +1,53 @@ +package com.github.kaklakariada.fritzbox.model.homeautomation; + +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Optional; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class StatisticsTest { + + private static Statistics statistics; + + @BeforeClass + public static void setupStatistics() { + statistics = new Statistics(); + statistics.setMeasurementUnit(MeasurementUnit.POWER); + } + + @Test + public void isIntegerNumberTest() { + assertEquals("Test null", false, statistics.isIntegerNumber(null)); + assertEquals("Test Integer", true, statistics.isIntegerNumber("1")); + assertEquals("Test Double", false, statistics.isIntegerNumber("1.1")); + assertEquals("Test Double", false, statistics.isIntegerNumber("1.1D")); + } + + @Test + public void computeValueTest() { + assertEquals("Test null", null, statistics.computeValue(null)); + assertEquals("Test Integer", Double.valueOf(0.02), statistics.computeValue("2")); + assertEquals("Test Double", null, statistics.computeValue("1.1")); + assertEquals("Test Double", null, statistics.computeValue("1.1D")); + } + + @Test + public void getCsvValuesTest() { + statistics.setCsvValues(null); + List> result = statistics.getValues(); + assertEquals("Number of entries", 0, result.size()); + + statistics.setCsvValues(""); + result = statistics.getValues(); + assertEquals("Number of entries", 1, result.size()); + assertEquals("First number", Optional.empty(), result.get(0)); + + statistics.setCsvValues("1111, 22222"); + result = statistics.getValues(); + assertEquals("Number of entries", 2, result.size()); + assertEquals("First number", Double.valueOf(11.11), result.get(0).get()); + } +} From 34d21e38196590cf9b080cdbb5d560d9558434c3 Mon Sep 17 00:00:00 2001 From: JunkerMartin Date: Fri, 3 Dec 2021 11:06:04 +0100 Subject: [PATCH 7/7] Refactor JUnit-Tests and move the helper method 'isIntegerNumber' off from a dto-class to a helper-class --- .../fritzbox/helper/StringHelper.java | 123 ++++++++++++++++++ .../model/homeautomation/Statistics.java | 18 +-- .../fritzbox/helper/StringHelperTest.java | 34 +++++ .../fritzbox/mapping/DeserializerTest.java | 9 ++ .../model/homeautomation/StatisticsTest.java | 33 +++-- ...xml => deviceListAllTogetherWithBlind.xml} | 0 6 files changed, 189 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java create mode 100644 src/test/java/com/github/kaklakariada/fritzbox/helper/StringHelperTest.java rename src/test/resources/FritzOS29/{deviceList.xml => deviceListAllTogetherWithBlind.xml} (100%) diff --git a/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java b/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java new file mode 100644 index 0000000..631d5cd --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java @@ -0,0 +1,123 @@ +/** + * A Java API for managing FritzBox HomeAutomation + * Copyright (C) 2017 Christoph Pirkl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.github.kaklakariada.fritzbox.helper; + +public class StringHelper { + + /** + *

    Note that the method does not allow for a leading sign, either positive or negative.

    + * + *
    +     * StringUtils.isIntegerNumber(null)  = false
    +     * StringHelper.isIntegerNumber(""))  = false
    +     * StringHelper.isIntegerNumber(" ")  = false
    +     * StringHelper.isIntegerNumber(" 1 ") = true
    +     * StringHelper.isIntegerNumber("123")  = true
    +     * StringUtils.isIntegerNumber("\u0967\u0968\u0969")  = true
    +     * StringHelper.isIntegerNumber("1.1") = false
    +     * StringHelper.isIntegerNumber("1.1D") = false
    +     * 
    + * + * + * @param cs the String to check, may be null + * @return {@code true} if only contains digits or is enclosed by blanks, and is non-null + */ + public static boolean isIntegerNumber(final String cs) { + if (isEmpty(cs) || !isNumeric(cs.trim())) { + return false; + } + try { + Integer.parseInt(cs.trim()); + } catch (NumberFormatException nfe) { + return false; + } + return true; + } + + /** + *

    Code copied 'as is' from apache-commons-lang3, class StringUtils.isNumeric()

    + * + *

    Checks if the CharSequence contains only Unicode digits. + * A decimal point is not a Unicode digit and returns false.

    + * + *

    {@code null} will return {@code false}. + * An empty CharSequence (length()=0) will return {@code false}.

    + * + *

    Note that the method does not allow for a leading sign, either positive or negative. + * Also, if a String passes the numeric test, it may still generate a NumberFormatException + * when parsed by Integer.parseInt or Long.parseLong, e.g. if the value is outside the range + * for int or long respectively.

    + * + *
    +     * StringUtils.isNumeric(null)   = false
    +     * StringUtils.isNumeric("")     = false
    +     * StringUtils.isNumeric("  ")   = false
    +     * StringUtils.isNumeric("123")  = true
    +     * StringUtils.isNumeric("\u0967\u0968\u0969")  = true
    +     * StringUtils.isNumeric("12 3") = false
    +     * StringUtils.isNumeric("ab2c") = false
    +     * StringUtils.isNumeric("12-3") = false
    +     * StringUtils.isNumeric("12.3") = false
    +     * StringUtils.isNumeric("-123") = false
    +     * StringUtils.isNumeric("+123") = false
    +     * 
    + * + * @param cs the CharSequence to check, may be null + * @return {@code true} if only contains digits, and is non-null + * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence) + * @since 3.0 Changed "" to return false and not true + */ + public static boolean isNumeric(final CharSequence cs) { + if (isEmpty(cs)) { + return false; + } + final int sz = cs.length(); + for (int i = 0; i < sz; i++) { + if (!Character.isDigit(cs.charAt(i))) { + return false; + } + } + return true; + } + + + /** + *

    Code copied 'as is' from apache-commons-lang3, class StringUtils.isEmpty()

    + * + *

    Checks if a CharSequence is empty ("") or null.

    + * + *
    +     * StringUtils.isEmpty(null)      = true
    +     * StringUtils.isEmpty("")        = true
    +     * StringUtils.isEmpty(" ")       = false
    +     * StringUtils.isEmpty("bob")     = false
    +     * StringUtils.isEmpty("  bob  ") = false
    +     * 
    + * + *

    NOTE: This method changed in Lang version 2.0. + * It no longer trims the CharSequence. + * That functionality is available in isBlank().

    + * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is empty or null + * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) + */ + public static boolean isEmpty(final CharSequence cs) { + return cs == null || cs.length() == 0; + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java index 831da6c..ab6b713 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Statistics.java @@ -27,6 +27,8 @@ import org.simpleframework.xml.Root; import org.simpleframework.xml.Text; +import com.github.kaklakariada.fritzbox.helper.StringHelper; + @Root(name = "stats") public class Statistics { @@ -102,7 +104,7 @@ public void setMeasurementUnit(final MeasurementUnit measurementUnit) { protected Number computeValue(String aValue) { Number numberValue = null; - if (isIntegerNumber(aValue)) { + if (StringHelper.isIntegerNumber(aValue)) { Integer intValue = Integer.valueOf(aValue.trim()); if (measurementUnit.getPrescision() instanceof Double) { numberValue = Double.valueOf(intValue*(Double)measurementUnit.getPrescision()); @@ -113,18 +115,4 @@ protected Number computeValue(String aValue) { } return null; } - - protected boolean isIntegerNumber(String aValue) { - if (aValue == null) { - return false; - } - try { - Integer.parseInt(aValue.trim()); - } catch (NumberFormatException nfe) { - return false; - } - return true; - } - - } \ No newline at end of file diff --git a/src/test/java/com/github/kaklakariada/fritzbox/helper/StringHelperTest.java b/src/test/java/com/github/kaklakariada/fritzbox/helper/StringHelperTest.java new file mode 100644 index 0000000..48cebe2 --- /dev/null +++ b/src/test/java/com/github/kaklakariada/fritzbox/helper/StringHelperTest.java @@ -0,0 +1,34 @@ +package com.github.kaklakariada.fritzbox.helper; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class StringHelperTest { + + @Test + public void isIntegerNumberTest() { + assertEquals("Test null", false, StringHelper.isIntegerNumber(null)); + assertEquals("Test empty", false, StringHelper.isIntegerNumber("")); + assertEquals("Test blank", false, StringHelper.isIntegerNumber(" ")); + assertEquals("Test numeric enclosed by blank", true, StringHelper.isIntegerNumber(" 1 ")); + assertEquals("Test numeric enclosing blank", false, StringHelper.isIntegerNumber("1 1")); + assertEquals("Test Unicode", true, StringHelper.isIntegerNumber("\u0967\u0968\u0969")); + assertEquals("Test Integer", true, StringHelper.isIntegerNumber("1")); + assertEquals("Test Double", false, StringHelper.isIntegerNumber("1.1")); + assertEquals("Test Double", false, StringHelper.isIntegerNumber("1.1D")); + } + + @Test + public void isNumericTest() { + assertEquals("Test null", false, StringHelper.isNumeric(null)); + assertEquals("Test empty", true, StringHelper.isNumeric("")); + assertEquals("Test blank", true, StringHelper.isNumeric("")); + assertEquals("Test numeric blank", true, StringHelper.isNumeric(" 1 ")); + assertEquals("Test Unicode", true, StringHelper.isNumeric("\u0967\u0968\u0969")); + assertEquals("Test empty", true, StringHelper.isNumeric("1")); + assertEquals("Test Double", false, StringHelper.isNumeric("1.1")); + assertEquals("Test Double", false, StringHelper.isNumeric("1.1D")); + } + +} diff --git a/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java b/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java index b06f510..857aa4a 100644 --- a/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java +++ b/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java @@ -112,6 +112,15 @@ public void parseDeviceList() throws IOException { .collect(joining("\n")); new Deserializer().parse(fileContent, DeviceList.class); } + + + @Test + public void parseDeviceListAllTogetherWithBlind() throws IOException { + final String fileContent = Files.readAllLines(Paths.get("src/test/resources/FritzOS29/deviceListAllTogetherWithBlind.xml")) + .stream() + .collect(joining("\n")); + new Deserializer().parse(fileContent, DeviceList.class); + } @Test public void parseDeviceStatsFritzDect200() throws IOException { diff --git a/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java b/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java index a509c8a..fb1a836 100644 --- a/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java +++ b/src/test/java/com/github/kaklakariada/fritzbox/model/homeautomation/StatisticsTest.java @@ -18,14 +18,6 @@ public static void setupStatistics() { statistics.setMeasurementUnit(MeasurementUnit.POWER); } - @Test - public void isIntegerNumberTest() { - assertEquals("Test null", false, statistics.isIntegerNumber(null)); - assertEquals("Test Integer", true, statistics.isIntegerNumber("1")); - assertEquals("Test Double", false, statistics.isIntegerNumber("1.1")); - assertEquals("Test Double", false, statistics.isIntegerNumber("1.1D")); - } - @Test public void computeValueTest() { assertEquals("Test null", null, statistics.computeValue(null)); @@ -38,16 +30,31 @@ public void computeValueTest() { public void getCsvValuesTest() { statistics.setCsvValues(null); List> result = statistics.getValues(); - assertEquals("Number of entries", 0, result.size()); + assertEquals("(1) Number of entries", 0, result.size()); statistics.setCsvValues(""); result = statistics.getValues(); - assertEquals("Number of entries", 1, result.size()); - assertEquals("First number", Optional.empty(), result.get(0)); + assertEquals("(2) Number of entries", 1, result.size()); + assertEquals("(2) First number", Optional.empty(), result.get(0)); statistics.setCsvValues("1111, 22222"); result = statistics.getValues(); - assertEquals("Number of entries", 2, result.size()); - assertEquals("First number", Double.valueOf(11.11), result.get(0).get()); + assertEquals("(3) Number of entries", 2, result.size()); + assertEquals("(3) First number", Double.valueOf(11.11), result.get(0).get()); + + statistics.setCsvValues("1111,,22222,-"); + result = statistics.getValues(); + assertEquals("(4) Number of entries", 4, result.size()); + assertEquals("(4) First number", Double.valueOf(11.11), result.get(0).get()); + assertEquals("(4) Second number is empty", true, result.get(1).isEmpty()); + assertEquals("(4) Third number", Double.valueOf(222.22), result.get(2).get()); + assertEquals("(4) Fourth number is empty", true, result.get(3).isEmpty()); + + statistics.setCsvValues(",1111,-"); + result = statistics.getValues(); + assertEquals("(5) Number of entries", 3, result.size()); + assertEquals("(5) First number is empty", true, result.get(0).isEmpty()); + assertEquals("(5) Second number", Double.valueOf(11.11), result.get(1).get()); + assertEquals("(5) Third number is empty", true, result.get(2).isEmpty()); } } diff --git a/src/test/resources/FritzOS29/deviceList.xml b/src/test/resources/FritzOS29/deviceListAllTogetherWithBlind.xml similarity index 100% rename from src/test/resources/FritzOS29/deviceList.xml rename to src/test/resources/FritzOS29/deviceListAllTogetherWithBlind.xml