diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bf15386..5ad242a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: 11 + java-version: 21 - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 548c2a4..3ac3162 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -17,11 +17,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: 17 + java-version: 21 - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - name: Setup Pages diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 887685e..4e779f9 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [11, 17, 21, 23] + java: [21, 23] env: - DEFAULT_JAVA: 11 + DEFAULT_JAVA: 21 steps: - uses: actions/checkout@v4 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index e399cb1..d562092 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -11,9 +11,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable.secondary= org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -113,7 +113,7 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fb9e45..653a554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.8.0] - unreleased +- [#66](https://github.com/kaklakariada/fritzbox-java-api/pull/66) Add support for FritzBox 6690 (contributed by Manfred) - [#65](https://github.com/kaklakariada/fritzbox-java-api/pull/65) Upgrade dependencies ## [1.7.0] - 2023-10-07 ### Added -- [#29](https://github.com/kaklakariada/fritzbox-java-api/issues/29) Add support for login via Pbkdf2 challenge-response (propsed by [@linnex81](https://github.com/linnex81)) +- [#29](https://github.com/kaklakariada/fritzbox-java-api/issues/29) Add support for login via Pbkdf2 challenge-response (proposed by [@linnex81](https://github.com/linnex81)) - [#58](https://github.com/kaklakariada/fritzbox-java-api/pull/58) Datatime attribute added in devicestats XML response since Fritz OS 7.50 (thanks to [@LutzHelling](https://github.com/LutzHelling)) ### Fixed diff --git a/build.gradle b/build.gradle index 6394b3f..7aa6d66 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ version = '1.7.0' java { toolchain { - def javaVersion = project.hasProperty('javaVersion') ? project.getProperty('javaVersion') : 11 + def javaVersion = project.hasProperty('javaVersion') ? project.getProperty('javaVersion') : 21 languageVersion = JavaLanguageVersion.of(javaVersion) } withJavadocJar() @@ -56,6 +56,7 @@ license { exclude('**/deviceList*Payload.xml') exclude('devicelist6840.xml') exclude('**/FritzOS29/*.xml') + exclude('**/FritzBox6690/*.xml') } jacocoTestReport { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/Config.java b/src/main/java/com/github/kaklakariada/fritzbox/Config.java index 93db8ff..ee8ff24 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/Config.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/Config.java @@ -17,12 +17,8 @@ */ package com.github.kaklakariada.fritzbox; -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.io.*; +import java.nio.file.*; import java.util.Optional; import java.util.Properties; @@ -39,11 +35,7 @@ private Config(final Properties properties) { } public static Config read() { - return read(DEFAULT_CONFIG); - } - - private static Config read(final Path configFile) { - final Path file = configFile.normalize(); + final Path file = DEFAULT_CONFIG.normalize(); return new Config(loadProperties(file)); } @@ -74,8 +66,9 @@ public String getPassword() { } private String getMandatoryValue(final String param) { - return getOptionalValue(param).orElseThrow( - () -> new IllegalStateException("Property '" + param + "' not found in config file")); + return getOptionalValue(param) + .orElseThrow( + () -> new IllegalStateException("Property '" + param + "' not found in config file")); } private Optional getOptionalValue(final String param) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/EnergyStatisticsService.java b/src/main/java/com/github/kaklakariada/fritzbox/EnergyStatisticsService.java index 1d2a80b..7d37441 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/EnergyStatisticsService.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/EnergyStatisticsService.java @@ -40,7 +40,7 @@ public enum EnergyStatsTimeRange { private final String command; - private EnergyStatsTimeRange(String command) { + EnergyStatsTimeRange(String command) { this.command = command; } } @@ -58,7 +58,7 @@ public String getEnergyStatistics(String deviceId, EnergyStatsTimeRange timeRang private String executeDeviceCommand(String deviceId, String command) { final QueryParameters parameters = QueryParameters.builder().add("command", command).add("id", deviceId) .add("xhr", "1").build(); - final String statisticsJson = session.getAutenticated(QUERY_PATH, parameters, String.class); + final String statisticsJson = session.getAuthenticated(QUERY_PATH, parameters, String.class); LOG.trace("Got statistics json for command '{}': {}", command, statisticsJson); return statisticsJson; } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxException.java b/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxException.java index 406a9ab..9ac8e56 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxException.java @@ -17,8 +17,11 @@ */ package com.github.kaklakariada.fritzbox; +import java.io.Serial; + public class FritzBoxException extends RuntimeException { + @Serial private static final long serialVersionUID = 1L; public FritzBoxException(String message, Throwable cause) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxSession.java b/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxSession.java index b7067f2..63c0fe1 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxSession.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/FritzBoxSession.java @@ -32,7 +32,7 @@ public class FritzBoxSession { private static final Logger LOG = LoggerFactory.getLogger(FritzBoxSession.class); private static final String LOGIN_PATH = "/login_sid.lua"; - private static final String WEBCM_PATH = "/home/home.lua"; + private static final String WEB_CM_PATH = "/home/home.lua"; private static final String EMPTY_SESSION_ID = "0000000000000000"; private String sid; @@ -81,7 +81,7 @@ private String createResponse(final String challenge, final String password) { return ChallengeResponse.getAlgorithm(challenge).calculateResponse(challenge, password); } - public T getAutenticated(final String path, final QueryParameters parameters, final Class resultType) { + public T getAuthenticated(final String path, final QueryParameters parameters, final Class resultType) { if (sid == null) { throw new FritzBoxException("Not logged in, session id is null"); } @@ -90,8 +90,11 @@ public T getAutenticated(final String path, final QueryParameters parameters } public void logout() { - httpTemplate.get(WEBCM_PATH, QueryParameters.builder().add("sid", sid).add("logout", "1").build(), - String.class); + final QueryParameters q = QueryParameters.builder() + .add("sid", sid) + .add("logout", "1") + .build(); + httpTemplate.get(WEB_CM_PATH, q, String.class); LOG.debug("Logged out, invalidate sid"); sid = null; } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java b/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java index a423bf6..db2f5fe 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/HomeAutomation.java @@ -18,6 +18,7 @@ package com.github.kaklakariada.fritzbox; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.slf4j.Logger; @@ -37,7 +38,8 @@ public class HomeAutomation { private final FritzBoxSession session; private enum Param { - PARAM("param"), LEVEL("level"), TARGET("target"); + PARAM("param"), LEVEL("level"), TARGET("target"), + ; private final String name; @@ -63,7 +65,7 @@ public static HomeAutomation connect(final String baseUrl, final String username public DeviceList getDeviceListInfos() { final DeviceList deviceList = executeCommand("getdevicelistinfos", DeviceList.class); - LOG.trace("Found {} devices, devicelist version: {}", deviceList.getDevices().size(), + LOG.trace("Found {} devices, device list version: {}", deviceList.getDevices().size(), deviceList.getApiVersion()); return deviceList; } @@ -74,7 +76,7 @@ public Device getDeviceInfos(final String deviceAin) { private T executeCommand(final String command, final Class resultType) { final QueryParameters parameters = QueryParameters.builder().add("switchcmd", command).build(); - return session.getAutenticated(HOME_AUTOMATION_PATH, parameters, resultType); + return session.getAuthenticated(HOME_AUTOMATION_PATH, parameters, resultType); } private T executeParamCommand(final String deviceAin, final String command, final String parameter, @@ -99,11 +101,14 @@ private T executeDeviceCommand(final String deviceAin, final String command, if (parameter != null) { paramBuilder.add(paramName.name, parameter); } - return session.getAutenticated(HOME_AUTOMATION_PATH, paramBuilder.build(), responseType); + return session.getAuthenticated(HOME_AUTOMATION_PATH, paramBuilder.build(), responseType); } public List getSwitchList() { final String switches = executeCommand("getswitchlist", String.class); + if (switches == null) { + return Collections.emptyList(); + } final List idList = Arrays.asList(switches.split(",")); LOG.trace("Got switch list string '{}': {}", switches, idList); return idList; diff --git a/src/main/java/com/github/kaklakariada/fritzbox/LoginFailedException.java b/src/main/java/com/github/kaklakariada/fritzbox/LoginFailedException.java index 617de77..a1c7729 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/LoginFailedException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/LoginFailedException.java @@ -17,13 +17,16 @@ */ package com.github.kaklakariada.fritzbox; +import java.io.Serial; + import com.github.kaklakariada.fritzbox.model.SessionInfo; public class LoginFailedException extends FritzBoxException { + @Serial private static final long serialVersionUID = 1L; public LoginFailedException(SessionInfo session) { - super("Login failed, blocked for " + session.getBlockTime() + " min"); + super("Login failed, blocked for " + session.getBlockTime() + " minutes."); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java b/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java index ca21271..ebbecd0 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/MissingClassException.java @@ -17,8 +17,11 @@ */ package com.github.kaklakariada.fritzbox; +import java.io.Serial; + public class MissingClassException extends RuntimeException { + @Serial private static final long serialVersionUID = 1L; public MissingClassException(String message, Throwable cause) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/TestBlind.java b/src/main/java/com/github/kaklakariada/fritzbox/TestBlind.java index f674a1f..375fcbf 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/TestBlind.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/TestBlind.java @@ -48,7 +48,7 @@ public TestBlind() throws InterruptedException { LOG.warn("No blind devices found"); return; } - final int wasPercenClosed = blindDevices.get(0).getLevelControl().getLevelpercentage(); + final int wasPercenClosed = blindDevices.get(0).getLevelControl().getLevelPercentage(); toggleBlindOpenClose(); @@ -108,7 +108,7 @@ private void togglePercentOpen() throws InterruptedException { return; } showStatus(blindDevices); - final int wasPercenClosed = blindDevices.get(0).getLevelControl().getLevelpercentage(); + final int wasPercenClosed = blindDevices.get(0).getLevelControl().getLevelPercentage(); final int newPercenClosed = wasPercenClosed == 0 ? 50 : wasPercenClosed / 2; setPercentOpen(blindDevices.get(0), newPercenClosed); @@ -150,7 +150,7 @@ private void showStatus(final List blindDevices) { final String message = String.format("%-15s Mode: %s Percent-Closed: %s%%", blind.getName(), blind.getBlind().getMode(), - blind.getLevelControl().getLevelpercentage()); + blind.getLevelControl().getLevelPercentage()); LOG.info(message); }); } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java index 5d30e44..dea9d03 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/TestDriver.java @@ -21,20 +21,13 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.List; -import java.util.Optional; -import java.util.Properties; +import java.util.*; import org.slf4j.Logger; 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.MeasurementUnit; -import com.github.kaklakariada.fritzbox.model.homeautomation.PowerMeter; -import com.github.kaklakariada.fritzbox.model.homeautomation.Statistics; +import com.github.kaklakariada.fritzbox.model.homeautomation.*; public class TestDriver { private static final Logger LOG = LoggerFactory.getLogger(TestDriver.class); @@ -74,7 +67,7 @@ private static void testEnergyStats(final HomeAutomation homeAutomation, final S } private static void testEnergyStatsNew(final HomeAutomation homeAutomation, final 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; @@ -99,7 +92,7 @@ private static void testEnergyStatsNew(final HomeAutomation homeAutomation, fina } private static void testVoltageStatsNew(final HomeAutomation homeAutomation, final String ain) { - final Optional power = homeAutomation.getBasicStatistics(ain).getPower(); + final Optional power = homeAutomation.getBasicStatistics(ain).getPower(); if (power.isEmpty()) { LOG.error("No Statistics for power consumption gathered"); return; diff --git a/src/main/java/com/github/kaklakariada/fritzbox/TestHkrDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/TestHkrDriver.java index 00ad4de..b45b750 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/TestHkrDriver.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/TestHkrDriver.java @@ -52,7 +52,7 @@ public TestHkrDriver() { showTemperatures(hkrDevices); final String ain = hkrDevices.get(0).getIdentifier().replaceAll("\\s*", ""); - final double wasTemperature = getCelsius(hkrDevices.get(0).getHkr().getTsoll()); + final double wasTemperature = getCelsius(hkrDevices.get(0).getHkr().getTSoll()); final double newTsoll = 25D; LOG.info(""); LOG.info("Changing temperature of {} (ain='{}')to {} degrees", hkrDevices.get(0).getName(), ain, @@ -87,8 +87,8 @@ private void showTemperatures(final List hkrDevices) { hkrDevices.forEach(hkr -> { final String message = String.format("%-15s tist: %s(%s\u00B0), tsoll: %s(%s\u00B0)", hkr.getName(), - hkr.getHkr().getTist(), getCelsius(hkr.getHkr().getTist()), - hkr.getHkr().getTsoll(), getCelsius(hkr.getHkr().getTsoll())); + hkr.getHkr().getTIst(), getCelsius(hkr.getHkr().getTIst()), + hkr.getHkr().getTSoll(), getCelsius(hkr.getHkr().getTSoll())); LOG.info(message); }); } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/app/TestBlind.java b/src/main/java/com/github/kaklakariada/fritzbox/app/TestBlind.java new file mode 100644 index 0000000..aa1ca60 --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/app/TestBlind.java @@ -0,0 +1,163 @@ +/** + * 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.app; + +import java.util.List; + +import com.github.kaklakariada.fritzbox.AbstractTestHelper; +import com.github.kaklakariada.fritzbox.Config; +import com.github.kaklakariada.fritzbox.HomeAutomation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.kaklakariada.fritzbox.model.homeautomation.Device; +import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; + +/** + * Sample driver for Blind + * + * @author Junker Martin + * + */ +public class TestBlind extends AbstractTestHelper { + + private static final Logger LOG = LoggerFactory.getLogger(TestBlind.class); + private static final int WAIT_SECONDS = 20; + public static final String STATUS_AFTER_CHANGE = "Status after change"; + public static final String INITIAL_SETTING = "Initial setting"; + public static final String CHANGING_STATUS_OF_BLIND_AIN_TO = "Changing status of blind {} (ain='{}') to {}"; + + private final HomeAutomation homeAutomation; + + public TestBlind() throws InterruptedException { + this.homeAutomation = HomeAutomation.connect(Config.read()); + + // make sure to set back blind to original state + final List blindDevices = getBlindDevices(); + if (blindDevices.isEmpty()) { + LOG.warn("No blind devices found"); + return; + } + final int wasPercentClosed = blindDevices.getFirst().getLevelControl().getLevelPercentage(); + + toggleBlindOpenClose(); + + togglePercentOpen(); + + setPercentOpen(blindDevices.getFirst(), wasPercentClosed); + } + + private void toggleBlindOpenClose() throws InterruptedException { + // Start first move + LOG.info(""); + LOG.info(INITIAL_SETTING); + List blindDevices = getBlindDevices(); + if (blindDevices.isEmpty()) { + return; + } + showStatus(blindDevices); + toggleBlindOpenClose(blindDevices.getFirst()); + + // Start move back + sleep(); + LOG.info(""); + LOG.info(STATUS_AFTER_CHANGE); + blindDevices = getBlindDevices(); + showStatus(blindDevices); + toggleBlindOpenClose(blindDevices.getFirst()); + + // Show status at end of test + LOG.info(""); + sleep(); + blindDevices = getBlindDevices(); + showStatus(blindDevices); + } + + private void sleep() throws InterruptedException { + LOG.info("Wait {} seconds", WAIT_SECONDS); + Thread.sleep(WAIT_SECONDS * 1000L); + } + + private void toggleBlindOpenClose(final Device blind) { + final String ain = getAin(blind.getIdentifier()); + final boolean wasOpen = blind.getLevelControl().getLevel() == 0; + final String newStatus = wasOpen ? "close" : "open"; + + LOG.info(""); + LOG.info(CHANGING_STATUS_OF_BLIND_AIN_TO, blind.getName(), ain, newStatus); + homeAutomation.setBlind(ain, newStatus); + } + + private void togglePercentOpen() throws InterruptedException { + // Start first move + LOG.info(""); + LOG.info(INITIAL_SETTING); + List blindDevices = getBlindDevices(); + if (blindDevices.isEmpty()) { + return; + } + showStatus(blindDevices); + final int wasPercentClosed = blindDevices.getFirst().getLevelControl().getLevelPercentage(); + final int newPercentClosed = wasPercentClosed == 0 ? 50 : wasPercentClosed / 2; + + setPercentOpen(blindDevices.getFirst(), newPercentClosed); + + sleep(); + LOG.info(""); + LOG.info(STATUS_AFTER_CHANGE); + blindDevices = getBlindDevices(); + showStatus(blindDevices); + setPercentOpen(blindDevices.getFirst(), wasPercentClosed); + + // Show status at end of test + LOG.info(""); + sleep(); + blindDevices = getBlindDevices(); + showStatus(blindDevices); + } + + private void setPercentOpen(final Device blind, final int percent) { + final String ain = getAin(blind.getIdentifier()); + final String newLevel = String.valueOf(percent); + + LOG.info(""); + LOG.info(CHANGING_STATUS_OF_BLIND_AIN_TO, blind.getName(), ain, newLevel); + homeAutomation.setLevelPercentage(ain, newLevel); + } + + private List getBlindDevices() { + final DeviceList devices = homeAutomation.getDeviceListInfos(); + return devices.getDevices() + .stream() + .filter(device -> device.getBlind() != null).toList(); + } + + private void showStatus(final List blindDevices) { + blindDevices.forEach(blind -> { + final String message = String.format("%-15s Mode: %s Percent-Closed: %s%%", + blind.getName(), + blind.getBlind().getMode(), + blind.getLevelControl().getLevelPercentage()); + LOG.info(message); + }); + } + + public static void main(final String[] args) throws InterruptedException { + new TestBlind(); + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/app/TestDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/app/TestDriver.java new file mode 100644 index 0000000..2630445 --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/app/TestDriver.java @@ -0,0 +1,153 @@ +/** + * 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.app; + +import java.util.List; +import java.util.Optional; + +import com.github.kaklakariada.fritzbox.Config; +import com.github.kaklakariada.fritzbox.EnergyStatisticsService; +import com.github.kaklakariada.fritzbox.HomeAutomation; +import com.github.kaklakariada.fritzbox.model.homeautomation.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.kaklakariada.fritzbox.EnergyStatisticsService.EnergyStatsTimeRange; + +public class TestDriver { + private static final Logger LOG = LoggerFactory.getLogger(TestDriver.class); + + public static void main(final String[] args) throws InterruptedException { + final Config config = Config.read(); + final HomeAutomation homeAutomation = HomeAutomation.connect(config); + + 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); + + if (devices.getDevices().isEmpty()) { + homeAutomation.logout(); + return; + } + + testEnergyStats(homeAutomation, devices.getDevices().getFirst().getId()); + if (!ids.isEmpty()) { + final String ain = ids.getFirst(); + testEnergyStatsNew(homeAutomation, ain); + testVoltageStatsNew(homeAutomation, ain); + testHomeAutomation(homeAutomation, ain); + } + } + + private static void testEnergyStats(final HomeAutomation homeAutomation, final 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 testEnergyStatsNew(final HomeAutomation homeAutomation, final String ain) { + final Optional energy = homeAutomation.getBasicStatistics(ain).getEnergy(); + if (energy.isEmpty()) { + LOG.error("No Statistics for energy consumption gathered"); + return; + } + final Optional dailyEnergy = energy.get().getStatisticsByGrid(86400); + if (dailyEnergy.isEmpty()) { + LOG.error("No Statistics for energy consumption 'per day' gathered"); + return; + } + final MeasurementUnit measurementUnit = dailyEnergy.get().getMeasurementUnit(); + final List> dailyConsumption = dailyEnergy.get().getValues(); + + final StringBuilder sb = new StringBuilder(); + for (final Optional dailyValue : dailyConsumption) { + if (dailyValue.isPresent()) { + sb.append(dailyValue.get()).append(measurementUnit.getUnit()).append(" "); + } else { + sb.append("-").append(" "); + } + } + LOG.debug("Statistics daily energy consumption: {}", sb); + } + + private static void testVoltageStatsNew(final HomeAutomation homeAutomation, final String ain) { + final Optional power = homeAutomation.getBasicStatistics(ain).getPower(); + if (power.isEmpty()) { + LOG.error("No Statistics for power consumption gathered"); + return; + } + final Optional sixMinutesVoltage = power.get().getStatisticsByGrid(10); + if (sixMinutesVoltage.isEmpty()) { + LOG.error("No Statistics for power consumption 'per 10 seconds interval' gathered"); + return; + } + final MeasurementUnit measurementUnit = sixMinutesVoltage.get().getMeasurementUnit(); + final List> sixMinutesConsumption = sixMinutesVoltage.get().getValues(); + + final StringBuilder sb = new StringBuilder(); + for (final Optional intervalValue : sixMinutesConsumption) { + if (intervalValue.isPresent()) { + sb.append(intervalValue.get()).append(measurementUnit.getUnit()).append(" "); + } else { + sb.append("-").append(" "); + } + } + LOG.debug("Statistics power detected: {}", sb); + } + + private static void testHomeAutomation(final HomeAutomation homeAutomation, final String ain) + throws InterruptedException { + 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)); + if (LOG.isInfoEnabled()) { + 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(TestDriver::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()); + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/app/TestHkrDriver.java b/src/main/java/com/github/kaklakariada/fritzbox/app/TestHkrDriver.java new file mode 100644 index 0000000..4acc771 --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/app/TestHkrDriver.java @@ -0,0 +1,99 @@ +/** + * 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.app; + +import java.util.List; + +import com.github.kaklakariada.fritzbox.AbstractTestHelper; +import com.github.kaklakariada.fritzbox.Config; +import com.github.kaklakariada.fritzbox.HomeAutomation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.kaklakariada.fritzbox.model.homeautomation.Device; +import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; + +/** + * Sample driver for Hkr "Heizkörperregler(DE), Radiator regulator(EN)" + * + * @author Junker Martin + * + */ +public class TestHkrDriver extends AbstractTestHelper { + + private static final Logger LOG = LoggerFactory.getLogger(TestHkrDriver.class); + + public static void main(final String[] args) { + new TestHkrDriver(); + } + + private final HomeAutomation homeAutomation; + + public TestHkrDriver() { + this.homeAutomation = HomeAutomation.connect(Config.read()); + + LOG.info(""); + LOG.info("Initial temperature"); + List hkrDevices = getHkrDevices(); + + if (hkrDevices.isEmpty()) { + LOG.warn("No HKR devices found"); + return; + } + showTemperatures(hkrDevices); + + final String ain = hkrDevices.getFirst().getIdentifier().replaceAll("\\s*", ""); + final double wasTemperature = getCelsius(hkrDevices.getFirst().getHkr().getTSoll()); + final double newTsoll = 25D; + LOG.info(""); + LOG.info("Changing temperature of {} (ain='{}')to {} degrees", hkrDevices.getFirst().getName(), ain, + newTsoll); + homeAutomation.setHkrTsoll(ain, String.valueOf(getDegreeCode(newTsoll))); + + LOG.info(""); + LOG.info("Temperature after change"); + hkrDevices = getHkrDevices(); + showTemperatures(hkrDevices); + + homeAutomation.setHkrTsoll(ain, String.valueOf(getDegreeCode(wasTemperature))); + LOG.info(""); + LOG.info("Changing back temperature of {} (ain='{}')to {} degrees", hkrDevices.getFirst().getName(), ain, + wasTemperature); + LOG.info(""); + LOG.info("Temperature after changing back"); + hkrDevices = getHkrDevices(); + showTemperatures(hkrDevices); + } + + private List getHkrDevices() { + final DeviceList devices = homeAutomation.getDeviceListInfos(); + return devices.getDevices() + .stream() + .filter(device -> device.getHkr() != null).toList(); + } + + private void showTemperatures(final List hkrDevices) { + hkrDevices.forEach(hkr -> { + final String message = String.format("%-15s t ist: %s(%s°), t soll: %s(%s°)", + hkr.getName(), + hkr.getHkr().getTIst(), getCelsius(hkr.getHkr().getTIst()), + hkr.getHkr().getTSoll(), getCelsius(hkr.getHkr().getTSoll())); + LOG.info(message); + }); + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/app/TestTemperature.java b/src/main/java/com/github/kaklakariada/fritzbox/app/TestTemperature.java new file mode 100644 index 0000000..b09926b --- /dev/null +++ b/src/main/java/com/github/kaklakariada/fritzbox/app/TestTemperature.java @@ -0,0 +1,83 @@ +/** + * 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.app; + +import java.util.List; + +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.kaklakariada.fritzbox.Config; +import com.github.kaklakariada.fritzbox.HomeAutomation; +import com.github.kaklakariada.fritzbox.model.homeautomation.*; + +public class TestTemperature { + private static final Logger LOG = LoggerFactory.getLogger(TestTemperature.class); + + public static void main(final String[] args) { + final HomeAutomation homeAutomation = HomeAutomation.connect(Config.read()); + + getCurrentTemperature(homeAutomation); + getTemperatureStatistics(homeAutomation); + + homeAutomation.logout(); + } + + private static void getCurrentTemperature(final HomeAutomation homeAutomation) { + final DeviceList devices = homeAutomation.getDeviceListInfos(); + LOG.info("Found {} devices", devices.getDevices().size()); + for (final Device d : devices.getDevices()) { + final Temperature t = d.getTemperature(); + if (t != null) { + final Humidity h = d.getHumidity(); + LOG.info("{}: {}°C {}%rH", d.getName(), t.getCelsius(), h != null ? h.getRelHumidity() : null); + } + } + } + + private static void getTemperatureStatistics(final HomeAutomation homeAutomation) { + final DeviceList l = homeAutomation.getDeviceListInfos(); + for (final Device d : l.getDevices()) { + LOG.info("d {} : ain {}", d.getName(), d.getIdentifier()); + final DeviceStats s = homeAutomation.getBasicStatistics(d.getIdentifier()); + s.getTemperature().ifPresent(TestTemperature::temperature); + s.getHumidity().ifPresent(TestTemperature::humidity); + } + } + + private static void temperature(final @NotNull AbstractDeviceStatistics t) { + final List ts = t.getStats(); + if (ts != null) { + for (int i = 0; i < ts.size(); i++) { + final Statistics tsi = ts.get(i); + LOG.info("ts {}: {} // {}", i, tsi.getDataTime(), tsi.getCsvValues()); + } + } + } + + private static void humidity(final @NotNull AbstractDeviceStatistics h) { + final List hs = h.getStats(); + if (hs != null) { + for (int i = 0; i < hs.size(); i++) { + final Statistics hsi = hs.get(i); + LOG.info("hs {}: {} // {}", i, hsi.getDataTime(), hsi.getCsvValues()); + } + } + } +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java b/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java index 57c6e4f..6e60422 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/helper/StringHelper.java @@ -34,14 +34,14 @@ private StringHelper() { * StringHelper.isIntegerNumber(" ") = false * StringHelper.isIntegerNumber(" 1 ") = true * StringHelper.isIntegerNumber("123") = true - * StringUtils.isIntegerNumber("\u0967\u0968\u0969") = true + * StringUtils.isIntegerNumber("१२३") = true * StringHelper.isIntegerNumber("1.1") = false * StringHelper.isIntegerNumber("1.1D") = false * * * * @param cs - * the String to check, may be null + * 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) { @@ -50,7 +50,7 @@ public static boolean isIntegerNumber(final String cs) { } try { Integer.parseInt(cs.trim()); - } catch (NumberFormatException nfe) { + } catch (final NumberFormatException nfe) { return false; } return true; @@ -79,7 +79,7 @@ public static boolean isIntegerNumber(final String cs) { * StringUtils.isNumeric("") = false * StringUtils.isNumeric(" ") = false * StringUtils.isNumeric("123") = true - * StringUtils.isNumeric("\u0967\u0968\u0969") = true + * StringUtils.isNumeric("१२३") = true * StringUtils.isNumeric("12 3") = false * StringUtils.isNumeric("ab2c") = false * StringUtils.isNumeric("12-3") = false @@ -89,7 +89,7 @@ public static boolean isIntegerNumber(final String cs) { * * * @param cs - * the CharSequence to check, may be null + * the CharSequence to check, may be null * @return {@code true} if only contains digits, and is non-null */ public static boolean isNumeric(final CharSequence cs) { @@ -122,10 +122,10 @@ public static boolean isNumeric(final CharSequence cs) { * * * @param cs - * the CharSequence to check, may be null + * the CharSequence to check, may be null * @return {@code true} if the CharSequence is empty or null */ public static boolean isEmpty(final CharSequence cs) { - return cs == null || cs.length() == 0; + return cs == null || cs.isEmpty(); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/AccessForbiddenException.java b/src/main/java/com/github/kaklakariada/fritzbox/http/AccessForbiddenException.java index f64ce4b..f57d59c 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/AccessForbiddenException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/AccessForbiddenException.java @@ -17,15 +17,18 @@ */ package com.github.kaklakariada.fritzbox.http; +import java.io.Serial; + public class AccessForbiddenException extends HttpException { + @Serial private static final long serialVersionUID = 1L; - public AccessForbiddenException(String message, Throwable cause) { + public AccessForbiddenException(final String message, final Throwable cause) { super(message, cause); } - public AccessForbiddenException(String message) { + public AccessForbiddenException(final String message) { super(message); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/HttpException.java b/src/main/java/com/github/kaklakariada/fritzbox/http/HttpException.java index 08c637d..4c32bca 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/HttpException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/HttpException.java @@ -19,15 +19,18 @@ import com.github.kaklakariada.fritzbox.FritzBoxException; +import java.io.Serial; + public class HttpException extends FritzBoxException { + @Serial private static final long serialVersionUID = 1L; - public HttpException(String message, Throwable cause) { + public HttpException(final String message, final Throwable cause) { super(message, cause); } - public HttpException(String message) { + public HttpException(final String message) { super(message); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/HttpTemplate.java b/src/main/java/com/github/kaklakariada/fritzbox/http/HttpTemplate.java index 58ab2bf..9e53487 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/HttpTemplate.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/HttpTemplate.java @@ -1,23 +1,25 @@ /** * 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * You should have received a copy of the GNU General Public License + * 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.http; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.Map.Entry; import org.slf4j.Logger; @@ -94,12 +96,30 @@ private T parse(final Response response, Class resultType) { if (!response.isSuccessful()) { throw new FritzBoxException("Request failed: " + response); } + if (response.body() == null) { + throw new FritzBoxException("Request failed: empty body"); + } if (response.code() == 500) { throw new FritzBoxException("Request failed: " + deserializer.getStringFromStream(response.body().byteStream())); } - return deserializer.parse(response.body().byteStream(), resultType); + final InputStream data = getInputStream(response); + if (data == null) return null; + return deserializer.parse(data, resultType); } + InputStream getInputStream(Response response) { + try { + final String content = response.body().string(); + if (content.length() < 3) return null; + LOG.trace("code {} body content '{}'", response.code(), content); + return new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + } + catch (Exception e) { /* */} + assert response.body() != null; + return response.body().byteStream(); + } + + private HttpUrl createUrl(String path, QueryParameters parameters) { final Builder builder = baseUrl.newBuilder().encodedPath(path); for (final Entry param : parameters.getParameters().entrySet()) { @@ -121,7 +141,7 @@ private Response execute(Request request) { } return response; } catch (final IOException e) { - throw new HttpException("Error executing requst " + request, e); + throw new HttpException("Error executing request" + request, e); } } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/NullHostnameVerifier.java b/src/main/java/com/github/kaklakariada/fritzbox/http/NullHostnameVerifier.java index d5a1228..ea39236 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/NullHostnameVerifier.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/NullHostnameVerifier.java @@ -27,7 +27,7 @@ public class NullHostnameVerifier implements HostnameVerifier { private static final Logger LOG = LoggerFactory.getLogger(NullHostnameVerifier.class); @Override - public boolean verify(String hostname, SSLSession session) { + public boolean verify(final String hostname, final SSLSession session) { LOG.trace("Ignore ssl certificate for {}: {}", hostname, session); return true; } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/NullTrustManager.java b/src/main/java/com/github/kaklakariada/fritzbox/http/NullTrustManager.java index 969ee17..17d5a49 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/NullTrustManager.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/NullTrustManager.java @@ -46,4 +46,4 @@ public X509Certificate[] getAcceptedIssuers() { LOG.trace("Get accepted issuers"); return new X509Certificate[0]; } -} \ No newline at end of file +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/QueryParameters.java b/src/main/java/com/github/kaklakariada/fritzbox/http/QueryParameters.java index 191f684..2a0aa5f 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/QueryParameters.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/QueryParameters.java @@ -44,7 +44,7 @@ public static class Builder { private final Map parameters; private Builder() { - this(new HashMap()); + this(new HashMap<>()); } public Builder(Map parameters) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/http/TrustSelfSignedCertificates.java b/src/main/java/com/github/kaklakariada/fritzbox/http/TrustSelfSignedCertificates.java index 117cb80..fe017e6 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/http/TrustSelfSignedCertificates.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/http/TrustSelfSignedCertificates.java @@ -17,14 +17,9 @@ */ package com.github.kaklakariada.fritzbox.http; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; +import java.security.*; -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; +import javax.net.ssl.*; /** * This class creates an {@link SSLSocketFactory} that trusts all certificates. @@ -43,19 +38,18 @@ public static SSLSocketFactory getUnsafeSslSocketFactory() { return sslContext.getSocketFactory(); } - private static void initializeSslContext(SSLContext sslContext) { + private static void initializeSslContext(final SSLContext sslContext) { final KeyManager[] keyManagers = null; final TrustManager[] trustManagers = new TrustManager[] { new NullTrustManager() }; final SecureRandom secureRandom = new SecureRandom(); - final SSLContext sslContext1 = sslContext; try { - sslContext1.init(keyManagers, trustManagers, secureRandom); + sslContext.init(keyManagers, trustManagers, secureRandom); } catch (final KeyManagementException e) { throw new HttpException("Error initializing ssl context", e); } } - private static SSLContext getSSLContext(String algorithm) { + private static SSLContext getSSLContext(final String algorithm) { try { return SSLContext.getInstance(algorithm); } catch (final NoSuchAlgorithmException e) { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/login/Md5Service.java b/src/main/java/com/github/kaklakariada/fritzbox/login/Md5Service.java index 8119eaa..7e064a4 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/login/Md5Service.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/login/Md5Service.java @@ -34,9 +34,9 @@ String md5(final String s) { private String buildHexString(final byte[] data) { final StringBuilder hexString = new StringBuilder(); for (final byte aMessageDigest : data) { - String h = Integer.toHexString(0xFF & aMessageDigest); + final StringBuilder h = new StringBuilder(Integer.toHexString(0xFF & aMessageDigest)); while (h.length() < 2) { - h = "0" + h; + h.insert(0, "0"); } hexString.append(h); } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/login/Pbkdf2ChallengeResponse.java b/src/main/java/com/github/kaklakariada/fritzbox/login/Pbkdf2ChallengeResponse.java index 7ee3599..af167d7 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/login/Pbkdf2ChallengeResponse.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/login/Pbkdf2ChallengeResponse.java @@ -25,8 +25,8 @@ import javax.crypto.spec.SecretKeySpec; /** - * PBKDF2 challenge-response. See - * https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID_english_2021-05-03.pdf + * PBKDF2 challenge-response. See ... */ class Pbkdf2ChallengeResponse implements ChallengeResponse { @@ -66,7 +66,7 @@ static String toHex(final byte[] bytes) { } /** - * Create a pbkdf2 HMAC by appling the Hmac iter times as specified. We can't use the Android-internal PBKDF2 here, + * Create a pbkdf2 HMAC by applying the Hmac iter times as specified. We can't use the Android-internal PBKDF2 here, * as it only accepts char[] arrays, not bytes (for multi-stage hashing) */ static byte[] pbkdf2HmacSha256(final byte[] password, final byte[] salt, final int iters) { @@ -89,4 +89,4 @@ static byte[] pbkdf2HmacSha256(final byte[] password, final byte[] salt, final i throw new IllegalStateException("Failed to calculate HMAC", e); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/mapping/Deserializer.java b/src/main/java/com/github/kaklakariada/fritzbox/mapping/Deserializer.java index 3252361..a956c7d 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/mapping/Deserializer.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/mapping/Deserializer.java @@ -24,6 +24,7 @@ import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; +import org.simpleframework.xml.stream.Format; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,42 +33,46 @@ */ public class Deserializer { private static final Logger LOG = LoggerFactory.getLogger(Deserializer.class); + public static final String XML_VERSION_1_0_ENCODING_UTF_8 = ""; private final Serializer xmlSerializer; public Deserializer() { - this(new Persister()); + this(new Persister(new Format(XML_VERSION_1_0_ENCODING_UTF_8))); } - Deserializer(Serializer xmlSerializer) { + Deserializer(final Serializer xmlSerializer) { this.xmlSerializer = xmlSerializer; } - public T parse(InputStream data, Class resultType) { + public T parse(final InputStream data, final Class resultType) { try { final T resultObject; if (resultType == String.class || resultType == Boolean.class || resultType == Integer.class) { + LOG.trace("Parsing simple type: {}", resultType.getSimpleName()); resultObject = parseSimpleType(resultType, data); + LOG.trace("parsed simple type: {} {}", resultType.getSimpleName(), resultObject); } else { + LOG.trace("Parsing type {}", resultType.getSimpleName()); resultObject = xmlSerializer.read(resultType, data); } LOG.trace("Parsed response: {}", resultObject); return resultObject; } catch (final Exception e) { - throw new DeserializerException("Error parsing response body", e); + throw new DeserializerException("Error parsing response body: " + e.getMessage()); } } - private T parseSimpleType(Class resultType, InputStream data) throws IOException { + private T parseSimpleType(final Class resultType, final InputStream data) throws IOException { final String string = getStringFromStream(data); if (resultType == String.class) { return resultType.cast(string); } else if (resultType == Boolean.class) { return resultType.cast("1".equals(string)); } else if (resultType == Integer.class) { - if (string.isEmpty() || "inval".equals(string)) { + if (string.isEmpty() || "inval".equals(string) || "-".equals(string)) { return null; } return resultType.cast(Integer.parseInt(string)); @@ -75,8 +80,8 @@ private T parseSimpleType(Class resultType, InputStream data) throws IOEx throw new IOException("Type '" + resultType + "' is not supported: " + string); } - public String getStringFromStream(InputStream data) { - final Scanner scanner = new Scanner(data, StandardCharsets.UTF_8.toString()); + public String getStringFromStream(final InputStream data) { + final Scanner scanner = new Scanner(data, StandardCharsets.UTF_8); final String string = scanner.next(); scanner.close(); return string; diff --git a/src/main/java/com/github/kaklakariada/fritzbox/mapping/DeserializerException.java b/src/main/java/com/github/kaklakariada/fritzbox/mapping/DeserializerException.java index 3408bab..8347159 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/mapping/DeserializerException.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/mapping/DeserializerException.java @@ -19,15 +19,18 @@ import com.github.kaklakariada.fritzbox.FritzBoxException; +import java.io.Serial; + public class DeserializerException extends FritzBoxException { + @Serial private static final long serialVersionUID = 1L; - public DeserializerException(String message, Throwable cause) { + public DeserializerException(final String message, final Throwable cause) { super(message, cause); } - public DeserializerException(String message) { + public DeserializerException(final String message) { super(message); } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/SessionInfo.java b/src/main/java/com/github/kaklakariada/fritzbox/model/SessionInfo.java index dd9e081..7714835 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/SessionInfo.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/SessionInfo.java @@ -19,9 +19,7 @@ import java.util.List; -import org.simpleframework.xml.Element; -import org.simpleframework.xml.ElementList; -import org.simpleframework.xml.Root; +import org.simpleframework.xml.*; @Root(name = "SessionInfo") public class SessionInfo { @@ -63,7 +61,10 @@ public List getUsers() { @Override public String toString() { - return "SessionInfo [sid=" + sid + ", challenge=" + challenge + ", blockTime=" + blockTime + ", rights=" - + rights + "]"; + return "SessionInfo [sid=" + sid + + ", challenge=" + challenge + + ", blockTime=" + blockTime + + ", rights=" + rights + + "]"; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/UserRight.java b/src/main/java/com/github/kaklakariada/fritzbox/model/UserRight.java index 8da0a21..120d327 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/UserRight.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/UserRight.java @@ -28,6 +28,8 @@ public class UserRight { @Override public String toString() { - return "UserRight [name=" + name + ", access=" + access + "]"; + return "UserRight [name=" + name + + ", access=" + access + + "]"; } } 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 08dd5f8..51d1edd 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 @@ -17,23 +17,28 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; +import org.simpleframework.xml.ElementList; + +import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; public abstract class AbstractDeviceStatistics { - /** + @ElementList(name = "stats", required = false, inline = true) + protected List stats; + + /** * Supply the Statistics gathered for a chosen grid * * @param grid - * grid + * grid * @return Optional - avoid NPE if no statistics present */ public Optional getStatisticsByGrid(final int grid) { return getStats() .stream() - .filter(stats -> stats.getGrid() == grid) + .filter(stat -> stat.getGrid() == grid) .findAny(); } @@ -42,24 +47,30 @@ public Optional getStatisticsByGrid(final int grid) { * * @return List */ - public abstract List getStats(); + public List getStats() { + return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())); + } /** * 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 statistics to which to add the measurment unit - * @param measurementUnit the unit to add to the statistics + * @param stats + * statistics to which to add the measurement unit + * @param measurementUnit + * the unit to add to the statistics * @return statistics with measurement units */ protected List getStats(final List stats, final MeasurementUnit measurementUnit) { + if (stats == null) { + return Collections.emptyList(); + } return stats .stream() .map(stat -> { stat.setMeasurementUnit(measurementUnit); return stat; - }) - .collect(Collectors.toList()); + }).toList(); } /** @@ -67,24 +78,28 @@ protected List getStats(final List stats, final Measurem * * @return List */ - protected abstract List statisticsToString(); + protected List statisticsToString() { + return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); + } /** - * @param type statistics type + * @param type + * statistics type * @return statistics as one line per grid */ protected List statisticsToString(final String type) { return getStats() .stream() - .map(stats -> statisticsToString(type, stats)) - .collect(Collectors.toList()); + .map(stat -> statisticsToString(type, stat)).toList(); } /** * Form a line from a single statistic. * - * @param type statistics type - * @param statistics statistic to convert to {@link String} + * @param type + * statistics type + * @param statistics + * statistic to convert to {@link String} * @return statistic as a line */ private String statisticsToString(final String type, final Statistics statistics) { 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 58fa446..fc16ab5 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 @@ -33,7 +33,7 @@ public int getState() { return state; } - public void setState(int state) { + public void setState(final int state) { this.state = state; } @@ -41,7 +41,7 @@ public long getLastAlertChgTimestamp() { return lastAlertChgTimestamp; } - public void setLastAlertChgTimestamp(long lastAlertChgTimestamp) { + public void setLastAlertChgTimestamp(final 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 03e3df6..917714a 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 @@ -33,7 +33,7 @@ public int getEndPositionsSet() { return endPositionsSet; } - public void setEndPositionsSet(int endPositionsSet) { + public void setEndPositionsSet(final int endPositionsSet) { this.endPositionsSet = endPositionsSet; } @@ -41,7 +41,7 @@ public String getMode() { return mode; } - public void setMode(String mode) { + public void setMode(final String mode) { this.mode = mode; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Button.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Button.java index 44aebd5..9e62343 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Button.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Button.java @@ -31,7 +31,7 @@ public class Button { @Element(name = "name", required = false) private String name; @Element(name = "lastpressedtimestamp", required = false) - private String lastpressedtimestamp; + private String lastPressedTimestamp; public String getIdentifier() { return identifier; @@ -45,7 +45,7 @@ public String getName() { return name; } - public String getLastpressedtimestamp() { - return lastpressedtimestamp; + public String getLastPressedTimestamp() { + return lastPressedTimestamp; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/ColorControl.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/ColorControl.java index 09d789e..85f84e6 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/ColorControl.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/ColorControl.java @@ -26,7 +26,7 @@ public class ColorControl { @Element(name = "hue", required = false) private String hue; - @Element(name = "saturation", required = false) + @Element(name = "saturation", required = false) private String saturation; @Element(name = "temperature", required = false) 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 ea4fde2..6b7cd19 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 @@ -184,10 +184,21 @@ public Humidity getHumidity() { @Override public String toString() { - return "Device [identifier=" + identifier + ", id=" + id + ", functionBitmask=" + functionBitmask - + ", firmwareVersion=" + firmwareVersion + ", manufacturer=" + manufacturer + ", productName=" - + productName + ", present=" + present + ", txbusy=" + txbusy + ", name=" + name + ", batterylow=" - + batterylow + ", battery=" + battery + ", switchState=" + switchState + ", simpleOnOff=" + simpleOnOff - + ", powerMeter=" + powerMeter + ", temperature=" + temperature + ", hkr=" + hkr + "]"; + return "Device [identifier=" + identifier + + ", id=" + id + + ", functionBitmask=" + functionBitmask + + ", firmwareVersion=" + firmwareVersion + + ", manufacturer=" + manufacturer + + ", productName=" + productName + + ", present=" + present + + ", txbusy=" + txbusy + + ", name=" + name + + ", batterylow=" + batterylow + + ", battery=" + battery + + ", switchState=" + switchState + + ", simpleOnOff=" + simpleOnOff + + ", powerMeter=" + powerMeter + + ", temperature=" + temperature + + ", hkr=" + hkr + "]"; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceList.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceList.java index 97bf7a8..a75081b 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceList.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/DeviceList.java @@ -17,8 +17,6 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import static java.util.stream.Collectors.toList; - import java.util.ArrayList; import java.util.List; @@ -38,7 +36,6 @@ public class DeviceList { @ElementList(name = "group", type = Group.class, inline = true, required = false) private List groups; - @Attribute(name = "fwversion", required = false, empty = "n/a") private String firmwareVersion; @@ -62,8 +59,7 @@ public Device getDeviceByIdentifier(String identifier) { public List getDeviceIdentifiers() { return devices.stream() // - .map(Device::getIdentifier) // - .collect(toList()); + .map(Device::getIdentifier).toList(); } public String getFirmwareVersion() { 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 5728a36..085d472 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 @@ -42,42 +42,35 @@ 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); } - @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(); + getTemperature().ifPresent(t -> allStatistics.addAll(t.statisticsToString())); + getVoltage().ifPresent(v -> allStatistics.addAll(v.statisticsToString())); + getPower().ifPresent(p -> allStatistics.addAll(p.statisticsToString())); + getEnergy().ifPresent(e -> allStatistics.addAll(e.statisticsToString())); + getHumidity().ifPresent(h -> allStatistics.addAll(h.statisticsToString())); + final StringBuilder sb = new StringBuilder(); 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 ef8e38a..cd1743c 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 @@ -17,23 +17,8 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import java.util.List; - -import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root(name = "energy") -public class Energy extends AbstractDeviceStatistics { - - @ElementList(name = "stats", required = false, inline = true) - private List stats; - - public List getStats() { - return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; - } - - @Override - protected List statisticsToString() { - return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); - } +public class Energy extends AbstractDeviceStatistics { } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/EtsiUnitInfo.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/EtsiUnitInfo.java index 2850e05..96ebe37 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/EtsiUnitInfo.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/EtsiUnitInfo.java @@ -24,20 +24,20 @@ public class EtsiUnitInfo { @Element(name = "etsideviceid") - private int etsideviceid; + private int etsiDeviceId; @Element(name = "unittype") - private int unittype; + private int unitType; @Element(name = "interfaces") private String interfaces; - public int getEtsideviceid() { - return etsideviceid; + public int getEtsiDeviceId() { + return etsiDeviceId; } - public int getUnittype() { - return unittype; + public int getUnitType() { + return unitType; } public String getInterfaces() { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/GroupInfo.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/GroupInfo.java index fe4d304..9af9fa5 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/GroupInfo.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/GroupInfo.java @@ -23,16 +23,16 @@ import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; -@Root(name="groupinfo") +@Root(name = "groupinfo") public class GroupInfo { - @Element(name="masterdeviceid") + @Element(name = "masterdeviceid") private String masterDeviceId; /** - * Comma seperated list of devices identfied by their id. + * Comma separated list of devices identified by their id. */ - @Element(name="members") + @Element(name = "members") private String members; public String getMasterDeviceId() { diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Hkr.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Hkr.java index 6e55fa0..5baee24 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Hkr.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Hkr.java @@ -24,13 +24,13 @@ public class Hkr { @Element(name = "tist", required = false) - private int tist; + private int tIst; @Element(name = "tsoll", required = false) - private int tsoll; + private int tSoll; @Element(name = "absenk", required = false) - private int tabsenk; + private int tAbsenk; @Element(name = "komfort", required = false) private int komfort; @@ -39,25 +39,25 @@ public class Hkr { private int lock; @Element(name = "devicelock", required = false) - private int devicelock; + private int deviceLock; @Element(name = "errorcode", required = false) - private int errorcode; + private int errorCode; @Element(name = "windowopenactiv", required = false) - private boolean windowopenactiv; + private boolean windowOpenActive; @Element(name = "windowopenactiveendtime", required = false) - private int windowopenactiveendtime; + private int windowOpenActiveEndTime; @Element(name = "boostactive", required = false) - private boolean boostactive; + private boolean boostActive; @Element(name = "boostactiveendtime", required = false) - private int boostactiveendtime; + private int boostActiveEndTime; @Element(name = "batterylow", required = false) - private boolean batterylow; + private boolean batteryLow; @Element(name = "battery", required = false) private int battery; @@ -66,40 +66,46 @@ public class Hkr { private NextChange nextChange; @Element(name = "summeractive", required = false) - private boolean summeractive; + private boolean summerActive; @Element(name = "holidayactive", required = false) - private boolean holidayactive; + private boolean holidayActive; - public int getTist() { - return tist; + @Element(name = "adaptiveHeatingActive", required = false) + private boolean adaptiveHeatingActive; + + @Element(name = "adaptiveHeatingRunning", required = false) + private boolean adaptiveHeatingRunning; + + public int getTIst() { + return tIst; } - public void setTist(int tist) { - this.tist = tist; + public void setTIst(final int tIst) { + this.tIst = tIst; } - public int getTsoll() { - return tsoll; + public int getTSoll() { + return tSoll; } - public void setTsoll(int tsoll) { - this.tsoll = tsoll; + public void setTSoll(final int tSoll) { + this.tSoll = tSoll; } - public int getTabsenk() { - return tabsenk; + public int getTAbsenk() { + return tAbsenk; } - public void setTabsenk(int tabsenk) { - this.tabsenk = tabsenk; + public void setTAbsenk(final int tAbsenk) { + this.tAbsenk = tAbsenk; } public int getKomfort() { return komfort; } - public void setKomfort(int komfort) { + public void setKomfort(final int komfort) { this.komfort = komfort; } @@ -107,71 +113,71 @@ public int getLock() { return lock; } - public void setLock(int lock) { + public void setLock(final int lock) { this.lock = lock; } - public int getDevicelock() { - return devicelock; + public int getDeviceLock() { + return deviceLock; } - public void setDevicelock(int devicelock) { - this.devicelock = devicelock; + public void setDeviceLock(final int deviceLock) { + this.deviceLock = deviceLock; } - public int getErrorcode() { - return errorcode; + public int getErrorCode() { + return errorCode; } - public void setErrorcode(int errorcode) { - this.errorcode = errorcode; + public void setErrorCode(final int errorCode) { + this.errorCode = errorCode; } - public boolean isWindowopenactiv() { - return windowopenactiv; + public boolean isWindowOpenActive() { + return windowOpenActive; } - public void setWindowopenactiv(boolean windowopenactiv) { - this.windowopenactiv = windowopenactiv; + public void setWindowOpenActive(final boolean windowOpenActive) { + this.windowOpenActive = windowOpenActive; } - public int getWindowopenactiveendtime() { - return windowopenactiveendtime; + public int getWindowOpenActiveEndTime() { + return windowOpenActiveEndTime; } - public void setWindowopenactiveendtime(int windowopenactiveendtime) { - this.windowopenactiveendtime = windowopenactiveendtime; + public void setWindowOpenActiveEndTime(final int windowOpenActiveEndTime) { + this.windowOpenActiveEndTime = windowOpenActiveEndTime; } - public boolean isBoostactive() { - return boostactive; + public boolean isBoostActive() { + return boostActive; } - public void setBoostactive(boolean boostactive) { - this.boostactive = boostactive; + public void setBoostActive(final boolean boostActive) { + this.boostActive = boostActive; } - public int getBoostactiveendtime() { - return boostactiveendtime; + public int getBoostActiveEndTime() { + return boostActiveEndTime; } - public void setBoostactiveendtime(int boostactiveendtime) { - this.boostactiveendtime = boostactiveendtime; + public void setBoostActiveEndTime(final int boostActiveEndTime) { + this.boostActiveEndTime = boostActiveEndTime; } - public boolean isBatterylow() { - return batterylow; + public boolean isBatteryLow() { + return batteryLow; } - public void setBatterylow(boolean batterylow) { - this.batterylow = batterylow; + public void setBatteryLow(final boolean batteryLow) { + this.batteryLow = batteryLow; } public int getBattery() { return battery; } - public void setBattery(int battery) { + public void setBattery(final int battery) { this.battery = battery; } @@ -179,30 +185,53 @@ public NextChange getNextChange() { return nextChange; } - public void setNextChange(NextChange nextChange) { + public void setNextChange(final NextChange nextChange) { this.nextChange = nextChange; } - public boolean isSummeractive() { - return summeractive; + public boolean isSummerActive() { + return summerActive; + } + + public void setSummerActive(final boolean summerActive) { + this.summerActive = summerActive; + } + + public boolean isHolidayActive() { + return holidayActive; + } + + public void setHolidayActive(final boolean holidayActive) { + this.holidayActive = holidayActive; + } + + public boolean isAdaptiveHeatingActive() { + return adaptiveHeatingActive; } - public void setSummeractive(boolean summeractive) { - this.summeractive = summeractive; + public void setAdaptiveHeatingActive(final boolean adaptiveHeatingActive) { + this.adaptiveHeatingActive = adaptiveHeatingActive; } - public boolean isHolidayactive() { - return holidayactive; + public boolean isAdaptiveHeatingRunning() { + return adaptiveHeatingRunning; } - public void setHolidayactive(boolean holidayactive) { - this.holidayactive = holidayactive; + public void setAdaptiveHeatingRunning(final boolean adaptiveHeatingRunning) { + this.adaptiveHeatingRunning = adaptiveHeatingRunning; } @Override public String toString() { - return "Hkr [tist=" + tist + ", tsoll=" + tsoll + ", tabsenk=" + tabsenk + ", komfort=" + komfort + ", lock=" - + lock + ", devicelock=" + devicelock + ", errorcode=" + errorcode + ", batterylow=" + batterylow - + ", nextChange=" + nextChange + "]"; + return "Hkr [tIst=" + tIst + + ", tSoll=" + tSoll + + ", tAbsenk=" + tAbsenk + + ", komfort=" + komfort + + ", lock=" + lock + + ", deviceLock=" + deviceLock + + ", errorCode=" + errorCode + + ", batteryLow=" + batteryLow + + ", nextChange=" + nextChange + + "]"; } } 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 c33f1ad..e8eb873 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 @@ -17,32 +17,16 @@ */ 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 = "humidity") -public class Humidity extends AbstractDeviceStatistics { - +public class Humidity extends AbstractDeviceStatistics { + @Element(name = "rel_humidity", required = false) private int relHumidity; - @ElementList(name = "stats", required = false, inline = true) - private List stats; - public int getRelHumidity() { return relHumidity; } - - public List getStats() { - 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/LevelControl.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/LevelControl.java index 710a8b7..355e96a 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/LevelControl.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/LevelControl.java @@ -27,13 +27,13 @@ public class LevelControl { private int level; @Element(name = "levelpercentage", required = false) - private int levelpercentage; + private int levelPercentage; public int getLevel() { return level; } - public int getLevelpercentage() { - return levelpercentage; + public int getLevelPercentage() { + return levelPercentage; } } diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java index 28a2abc..b098e74 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/MeasurementUnit.java @@ -20,24 +20,22 @@ import com.github.kaklakariada.fritzbox.MissingClassException; /** - * 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 Integerv + *
  • measurement unit [V, W, Wh, %]
  • + *
  • precision as double to multiply with the gathered Integer value *
- * 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. + * 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 MeasurementUnit { - TEMPERATURE("C", 0.1, Temperature.class), - VOLTAGE("V", 0.001, Voltage.class), - POWER("W", 0.01, Power.class), - ENERGY("Wh", 1, Energy.class), - HUMIDITY("%", 1, Humidity.class); + TEMPERATURE("C", 0.1, Temperature.class), VOLTAGE("V", 0.001, Voltage.class), POWER("W", 0.01, + Power.class), ENERGY("Wh", 1, Energy.class), HUMIDITY("%", 1, Humidity.class); private final String unit; private final Number precision; @@ -53,7 +51,7 @@ public String getUnit() { return unit; } - public Number getPrescision() { + public Number getPrecision() { return precision; } @@ -62,11 +60,12 @@ public Class getMapper() { } public static MeasurementUnit getMatchingMeasurementUnit(Class caller) { - for (MeasurementUnit iterator : MeasurementUnit.values()) { - if (caller.isAssignableFrom(iterator.getMapper())) { - return iterator; + for (MeasurementUnit measurementUnit : MeasurementUnit.values()) { + if (caller.isAssignableFrom(measurementUnit.getMapper())) { + return measurementUnit; } } - throw new MissingClassException(String.format("Could not detect enum of type 'MeasurementUnit' associated to class '%s'", caller.toString())); + 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/NextChange.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/NextChange.java index d7f3d08..9793603 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/NextChange.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/NextChange.java @@ -24,29 +24,30 @@ public class NextChange { @Element(name = "endperiod", required = false) - private int endperiod; + private int endPeriod; @Element(name = "tchange", required = false) - private int tchange; + private int tChange; - public int getEndperiod() { - return endperiod; + public int getEndPeriod() { + return endPeriod; } - public void setEndperiod(int endperiod) { - this.endperiod = endperiod; + public void setEndPeriod(int endPeriod) { + this.endPeriod = endPeriod; } - public int getTchange() { - return tchange; + public int getTChange() { + return tChange; } - public void setTchange(int tchange) { - this.tchange = tchange; + public void setTChange(int tChange) { + this.tChange = tChange; } @Override public String toString() { - return "NextChange [endperiod=" + endperiod + ", tchange=" + tchange + "]"; + return "NextChange [endPeriod=" + endPeriod + + ", tChange=" + tChange + "]"; } -} \ No newline at end of file +} 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 2b81520..f7cae49 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 @@ -17,24 +17,8 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import java.util.List; - -import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root(name = "power") public class Power extends AbstractDeviceStatistics { - - @ElementList(name = "stats", required = false, inline = true) - private List stats; - - public List getStats() { - 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/PowerMeter.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/PowerMeter.java index 82fa095..2ec112f 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/PowerMeter.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/PowerMeter.java @@ -48,7 +48,9 @@ public int getPowerMilliWatt() { @Override public String toString() { - return "PowerMeter [voltage=" + getVoltageVolt() + ", energyWattHours=" + energyWattHours + ", powerWatt=" - + getPowerWatt() + "]"; + return "PowerMeter [voltage=" + getVoltageVolt() + + ", energyWattHours=" + energyWattHours + + ", powerWatt=" + getPowerWatt() + + "]"; } } 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 e2542df..fb95fa9 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 @@ -19,7 +19,6 @@ import java.time.Instant; import java.util.*; -import java.util.stream.Collectors; import org.simpleframework.xml.*; @@ -37,7 +36,7 @@ public class Statistics { private int grid; @Attribute(name = "datatime", required = false) - private Long datatime; + private Long dataTime; @Text() private String csvValues; @@ -46,12 +45,15 @@ public Statistics() { // Default constructor for XML deserialization } - Statistics(final MeasurementUnit measurementUnit, final int count, final int grid, final Long datatime, + Statistics(final MeasurementUnit measurementUnit, + final int count, + final int grid, + final Long dataTime, final String csvValues) { this.measurementUnit = measurementUnit; this.count = count; this.grid = grid; - this.datatime = datatime; + this.dataTime = dataTime; this.csvValues = csvValues; } @@ -69,7 +71,7 @@ public int getGrid() { * @return raw timestamp or {@code null} if not available */ public Long getDataTimeRaw() { - return datatime; + return dataTime; } /** @@ -93,7 +95,7 @@ public String getCsvValues() { } /** - * Just for unit test provided. Therefore it is set to package private. + * Just for unit test provided. Therefore, it is set to package private. */ void setCsvValues(final String csvValues) { this.csvValues = csvValues; @@ -106,12 +108,11 @@ void setCsvValues(final String csvValues) { */ public List> getValues() { if (getCsvValues() == null) { - return new ArrayList<>(); + return Collections.emptyList(); } - return Arrays.asList(getCsvValues().split(",")) - .stream() + return Arrays.stream(getCsvValues().split(",")) .map(aValue -> Optional.ofNullable(computeValue(aValue))) - .collect(Collectors.toList()); + .toList(); } /** @@ -119,7 +120,7 @@ public List> getValues() { *

* Consists of: *

    - *
  • measurment unit [V, W, Wh, %]
  • + *
  • measurement 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 @@ -136,16 +137,14 @@ public void setMeasurementUnit(final MeasurementUnit measurementUnit) { } protected Number computeValue(final String aValue) { - Number numberValue = null; if (StringHelper.isIntegerNumber(aValue)) { final Integer intValue = Integer.valueOf(aValue.trim()); - if (measurementUnit.getPrescision() instanceof Double) { - numberValue = Double.valueOf(intValue * (Double) measurementUnit.getPrescision()); + if (measurementUnit.getPrecision() instanceof Double precision) { + return intValue * precision; } else { - numberValue = Integer.valueOf(intValue * (Integer) measurementUnit.getPrescision()); + return intValue * (Integer) measurementUnit.getPrecision(); } - return numberValue; } return null; } -} \ No newline at end of file +} diff --git a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/SwitchState.java b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/SwitchState.java index f7bce3f..3d16692 100644 --- a/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/SwitchState.java +++ b/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/SwitchState.java @@ -40,7 +40,7 @@ public enum SwitchMode { private String lock; @Element(name = "devicelock", required = false) - private String devicelock; + private String deviceLock; boolean isNull() { return state == null || mode == null || lock == null; @@ -55,7 +55,7 @@ public boolean isLocked() { } public boolean isDeviceLocked() { - return "1".equals(devicelock); + return "1".equals(deviceLock); } public SwitchMode getMode() { @@ -63,19 +63,21 @@ public SwitchMode getMode() { LOG.warn("Switch mode is null for {}", this); return null; } - switch (mode) { - case "auto": - return SwitchMode.AUTO; - case "manuell": - return SwitchMode.MANUAL; - default: + return switch (mode) { + case "auto" -> SwitchMode.AUTO; + case "manuell" -> SwitchMode.MANUAL; + default -> { LOG.warn("Unknown value for switch mode: '{}' for {}", mode, this); - return null; + yield null; } + }; } @Override public String toString() { - return "SwitchState [state=" + state + ", mode=" + mode + ", lock=" + lock + "]"; + return "SwitchState [state=" + state + + ", mode=" + mode + + ", lock=" + lock + + "]"; } } 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 47d9d73..d52b7f4 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 @@ -17,9 +17,7 @@ */ 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") @@ -31,24 +29,12 @@ public class Temperature extends AbstractDeviceStatistics { @Element(name = "offset", required = false) private int offsetDeciCelsius; - @ElementList(name = "stats", required = false, inline = true) - private List stats; - public float getCelsius() { return (deciCelsius + offsetDeciCelsius) / 10F; } - public List getStats() { - return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())); - } - @Override public String toString() { 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 96b500e..5ff0d39 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 @@ -17,23 +17,8 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import java.util.List; - -import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root(name = "voltage") public class Voltage extends AbstractDeviceStatistics { - - @ElementList(name = "stats", required = false, inline = true) - private List stats; - - public List getStats() { - return getStats(stats, MeasurementUnit.getMatchingMeasurementUnit(this.getClass())) ; - } - - @Override - protected List statisticsToString() { - return statisticsToString(MeasurementUnit.getMatchingMeasurementUnit(this.getClass()).name()); - } } diff --git a/src/test/java/com/github/kaklakariada/fritzbox/fb6690/FB6690UseCase.java b/src/test/java/com/github/kaklakariada/fritzbox/fb6690/FB6690UseCase.java new file mode 100644 index 0000000..da2a0c3 --- /dev/null +++ b/src/test/java/com/github/kaklakariada/fritzbox/fb6690/FB6690UseCase.java @@ -0,0 +1,56 @@ +/** + * 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.fb6690; + +import com.github.kaklakariada.fritzbox.mapping.Deserializer; +import com.github.kaklakariada.fritzbox.model.SessionInfo; +import com.github.kaklakariada.fritzbox.model.homeautomation.DeviceList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class FB6690UseCase { + + public static final Logger LOGGER = LoggerFactory.getLogger(FB6690UseCase.class); + + public static void main(String[] args) throws FileNotFoundException { + testSession(); + testDeviceList(); + } + + private static void testDeviceList() throws FileNotFoundException { + final Path path = Paths.get("src/test/resources/FritzBox6690/deviceList.xml"); + final File file = path.toFile(); + final InputStream data = new FileInputStream(file); + Deserializer deserializer = new Deserializer(); + final DeviceList result = deserializer.parse(data, DeviceList.class); + LOGGER.info("DeviceList {}", result); + } + + private static void testSession() throws FileNotFoundException { + final Path path = Paths.get("src/test/resources/FritzBox6690/session.xml"); + final File file = path.toFile(); + final InputStream data = new FileInputStream(file); + Deserializer deserializer = new Deserializer(); + final SessionInfo result = deserializer.parse(data, SessionInfo.class); + LOGGER.info("SessionInfo {}", result); + } +} 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 d4731a2..6ebbbed 100644 --- a/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java +++ b/src/test/java/com/github/kaklakariada/fritzbox/mapping/DeserializerTest.java @@ -19,10 +19,7 @@ import static com.github.kaklakariada.fritzbox.assertions.HomeAutomationAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; import java.io.InputStream; @@ -52,7 +49,7 @@ void parseDeviceListFritzDect200() throws IOException { @Test void parseDeviceListFritzDect301() throws IOException { final DeviceList deviceList = parseDeviceList( - Paths.get("src/test/resources/deviceListConnectedFritzDect200Payload.xml")); + Paths.get("src/test/resources/deviceListConnectedFritzDect301Payload.xml")); assertThat(deviceList.getDevices()).hasSize(1); } @@ -93,7 +90,7 @@ void parseDeviceListAllTogether() throws IOException { @Test void parseDeviceListEmpty() throws IOException { final DeviceList deviceList = parseDeviceList(Paths.get("src/test/resources/FritzOS29/deviceListEmpty.xml")); - assertThat(deviceList.getDevices()).hasSize(0); + assertThat(deviceList.getDevices()).isEmpty(); } @Test @@ -120,18 +117,17 @@ void parseDeviceStatsFritzDect200() throws IOException { .newInputStream(Paths.get("src/test/resources/FritzOS29/devicestatsFritzDect200.xml")); final DeviceStats stats = new Deserializer().parse(fileContent, DeviceStats.class); assertEquals(1, stats.getTemperature().get().getStats().size(), "Temperature has just one statistics Element"); - assertEquals(Double.valueOf(0.1), - stats.getTemperature().get().getStats().get(0).getMeasurementUnit().getPrescision(), + assertEquals(0.1, + stats.getTemperature().get().getStats().getFirst().getMeasurementUnit().getPrecision(), "Temperature statistics have unit precision '0.1'"); assertEquals(2, stats.getEnergy().get().getStats().size(), "Energy has two statistics Element"); - assertEquals(false, stats.getHumidity().isPresent(), "Humidity is missing"); + assertFalse(stats.getHumidity().isPresent(), "Humidity is missing"); - assertEquals(true, stats.getEnergy().get().getStats().get(0).getDataTimeRaw() == 1665897036, + assertEquals(1665897036, (long) stats.getEnergy().get().getStats().getFirst().getDataTimeRaw(), "DataTime (raw) is missing"); - assertEquals(false, - stats.getEnergy().get().getStats().get(0).getDataTime().toEpochMilli() == 1665897, + assertNotEquals(1665897, stats.getEnergy().get().getStats().getFirst().getDataTime().toEpochMilli(), "DataTime is missing"); } 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 200ac09..7194c67 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 @@ -17,9 +17,8 @@ */ package com.github.kaklakariada.fritzbox.model.homeautomation; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; -import java.lang.System.Logger; import java.time.Instant; import java.util.List; import java.util.Optional; @@ -32,7 +31,6 @@ class StatisticsTest { private static Statistics statistics; - private static final Logger LOGGER = System.getLogger("StatisticsTest"); @BeforeAll static void setupStatistics() { @@ -42,10 +40,10 @@ static void setupStatistics() { @Test void computeValueTest() { - assertEquals(null, statistics.computeValue(null), "Test null"); - assertEquals(Double.valueOf(0.02), statistics.computeValue("2"), "Test Integer"); - assertEquals(null, statistics.computeValue("1.1"), "Test Double"); - assertEquals(null, statistics.computeValue("1.1D"), "Test Double"); + assertNull(statistics.computeValue(null), "Test null"); + assertEquals(0.02, statistics.computeValue("2"), "Test Integer"); + assertNull(statistics.computeValue("1.1"), "Test Double"); + assertNull(statistics.computeValue("1.1D"), "Test Double"); } @Test @@ -57,27 +55,27 @@ void getCsvValuesTest() { statistics.setCsvValues(""); result = statistics.getValues(); assertEquals(1, result.size(), "(2) Number of entries"); - assertEquals(Optional.empty(), result.get(0), "(2) First number"); + assertEquals(Optional.empty(), result.getFirst(), "(2) First number"); statistics.setCsvValues("1111, 22222"); result = statistics.getValues(); assertEquals(2, result.size(), "(3) Number of entries"); - assertEquals(Double.valueOf(11.11), result.get(0).get(), "(3) First number"); + assertEquals(11.11, result.getFirst().get(), "(3) First number"); statistics.setCsvValues("1111,,22222,-"); result = statistics.getValues(); assertEquals(4, result.size(), "(4) Number of entries"); - assertEquals(Double.valueOf(11.11), result.get(0).get(), "(4) First number"); - assertEquals(true, result.get(1).isEmpty(), "(4) Second number is empty"); - assertEquals(Double.valueOf(222.22), result.get(2).get(), "(4) Third number"); - assertEquals(true, result.get(3).isEmpty(), "(4) Fourth number is empty"); + assertEquals(11.11, result.get(0).get(), "(4) First number"); + assertTrue(result.get(1).isEmpty(), "(4) Second number is empty"); + assertEquals(222.22, result.get(2).get(), "(4) Third number"); + assertTrue(result.get(3).isEmpty(), "(4) Fourth number is empty"); statistics.setCsvValues(",1111,-"); result = statistics.getValues(); assertEquals(3, result.size(), "(5) Number of entries"); - assertEquals(true, result.get(0).isEmpty(), "(5) First number is empty"); - assertEquals(Double.valueOf(11.11), result.get(1).get(), "(5) Second number"); - assertEquals(true, result.get(2).isEmpty(), "(5) Third number is empty"); + assertTrue(result.get(0).isEmpty(), "(5) First number is empty"); + assertEquals(11.11, result.get(1).get(), "(5) Second number"); + assertTrue(result.get(2).isEmpty(), "(5) Third number is empty"); } @ParameterizedTest diff --git a/src/test/resources/FritzBox6690/DeviceStats_DECT_302.xml b/src/test/resources/FritzBox6690/DeviceStats_DECT_302.xml new file mode 100644 index 0000000..0e8dd39 --- /dev/null +++ b/src/test/resources/FritzBox6690/DeviceStats_DECT_302.xml @@ -0,0 +1 @@ +170,180,200,200,200,200,200,200,210,205,205,205,210,205,200,200,200,200,200,195,195,195,190,190,190,210,215,215,210,210,215,215,210,200,200,200,200,200,200,195,195,190,190,190,185,185,185,185,190,215,210,215,215,215,210,195,180,210,205,180,175,175,175,175,175,175,175,180,180,180,180,180,180,180,180,185,185,185,185,185,185,185,190,190,190,190,190,195,195,195,200,200,200,200,200,205 diff --git a/src/test/resources/FritzBox6690/DeviceStats_DECT_440.xml b/src/test/resources/FritzBox6690/DeviceStats_DECT_440.xml new file mode 100644 index 0000000..f0f0292 --- /dev/null +++ b/src/test/resources/FritzBox6690/DeviceStats_DECT_440.xml @@ -0,0 +1 @@ +175,180,200,200,200,200,200,200,210,210,205,205,205,205,200,200,200,200,200,195,195,195,195,190,190,210,210,215,215,210,215,215,210,205,200,200,200,200,200,200,195,195,190,190,185,185,185,185,190,175,170,170,165,160,150,135,140,160,175,175,175,175,175,175,175,175,175,175,175,175,175,175,180,180,180,180,180,180,180,180,180,180,185,185,185,185,185,190,190,190,190,190,190,190,190,19038,34,31,44,44,43,42,42,38,45,46,46,48,46,45,45,44,45,44,43,43,42,42,42,38,31,46,45,45,45,46,45,45,46,46,45,45,46,45,46,46,46,46,45,45,44,44,44,43,40,44,43,43,43,43,43,39,33,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,48,48,48,48,48,48,49,49,50,49,48,48,48,48,49 diff --git a/src/test/resources/FritzBox6690/deviceList.xml b/src/test/resources/FritzBox6690/deviceList.xml new file mode 100644 index 0000000..6386fff --- /dev/null +++ b/src/test/resources/FritzBox6690/deviceList.xml @@ -0,0 +1 @@ +10FRITZ!Smart Thermo 302 #1100017503632323900000000100173545920039001010FRITZ!Smart Wohnzimmer 4401000175038 diff --git a/src/test/resources/FritzBox6690/session.xml b/src/test/resources/FritzBox6690/session.xml new file mode 100644 index 0000000..2bbc88b --- /dev/null +++ b/src/test/resources/FritzBox6690/session.xml @@ -0,0 +1,11 @@ + + + 0000000000000000 + 2$****$****$****$**** + 0 + + + fritz4012 + grafana + + \ No newline at end of file