Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public void enablePowerMeterHighRefresh(
if (deviceId == null) {
throw new IllegalArgumentException("Cannot enable power meter high refresh as 'deviceId' is null!");
}
actionsHandler.enablePowerMeterHighRefresh(deviceId.longValue());
// TODO add input for polling interval
actionsHandler.enablePowerMeterHighRefresh(deviceId.longValue(), 10L);
}

public static void enablePowerMeterHighRefresh(ThingActions actions, @Nullable Long deviceId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
* @author Christoph Weitkamp - Initial contribution
*/
public class EnergyStats {
public static final double VOLTAGE_FACTOR = 0.01;
public static final double POWER_FACTOR = 0.01;
public static final double ENERGY_FACTOR = 0.001;

@SerializedName("DeviceConnectState")
public String deviceConnectState;
@SerializedName("VoltageStat")
Expand All @@ -33,6 +37,8 @@ public class EnergyStats {
public int mMValueVolt;
@SerializedName("MM_Value_Power")
public int mMValuePower;
@SerializedName("MM_Value_Energy")
public int mMValueEnergy;
@SerializedName("tabType")
public String tabType;
@SerializedName("DeviceID")
Expand All @@ -47,4 +53,31 @@ public class EnergyStats {
public int sumMonth;
@SerializedName("RequestResult")
public boolean requestResult;

/**
* Gets the scaled voltage value.
*
* @return the scaled voltage value
*/
public double getScaledVoltage() {
return mMValueVolt * VOLTAGE_FACTOR;
}

/**
* Gets the scaled power value.
*
* @return the scaled power value
*/
public double getScaledPower() {
return mMValuePower * POWER_FACTOR;
}

/**
* Gets the scaled energy value.
*
* @return the scaled energy value
*/
public double getScaledEnergy() {
return mMValueEnergy * ENERGY_FACTOR;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ default Collection<Class<? extends ThingHandlerService>> getServices() {
* Enables high refresh polling for this power meter.
*
* @param deviceId Id of the device.
* @param pollingInterval The interval for polling.
*/
void enablePowerMeterHighRefresh(long deviceId);
void enablePowerMeterHighRefresh(long deviceId, long pollingInterval);

/**
* Disables high refresh polling for this power meter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.avmfritz.internal.dto.PowerMeterModel;
import org.openhab.binding.avmfritz.internal.dto.json.EnergyStats;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
Expand Down Expand Up @@ -65,10 +64,10 @@ public void dispose() {
}

@Override
public void enablePowerMeterHighRefresh(long deviceId) {
public void enablePowerMeterHighRefresh(long deviceId, long pollingInterval) {
// TODO use Thing property "deviceId" instead of passing an argument
this.deviceId = deviceId;
startPolling(deviceId);
startPolling(deviceId, pollingInterval);
}

@Override
Expand All @@ -80,10 +79,11 @@ public void onEnergyStatsUpdated(String response) {
try {
EnergyStats energyStats = gson.fromJson(response, EnergyStats.class);
if (energyStats != null) {
updateThingChannelState(CHANNEL_POWER, new QuantityType<>(
energyStats.mMValuePower * PowerMeterModel.POWER_FACTOR.doubleValue(), Units.WATT));
updateThingChannelState(CHANNEL_VOLTAGE, new QuantityType<>(
energyStats.mMValueVolt * PowerMeterModel.VOLTAGE_FACTOR.doubleValue(), Units.VOLT));
updateThingChannelState(CHANNEL_ENERGY,
new QuantityType<>(energyStats.getScaledEnergy(), Units.WATT_HOUR));
updateThingChannelState(CHANNEL_POWER, new QuantityType<>(energyStats.getScaledPower(), Units.WATT));
updateThingChannelState(CHANNEL_VOLTAGE,
new QuantityType<>(energyStats.getScaledVoltage(), Units.VOLT));
}
} catch (JsonSyntaxException e) {
logger.debug("Failed to parse JSON: {}", e.getMessage());
Expand All @@ -93,10 +93,9 @@ public void onEnergyStatsUpdated(String response) {
/**
* Start the polling.
*/
private void startPolling(long deviceId) {
private void startPolling(long deviceId, long pollingInterval) {
ScheduledFuture<?> localPollingJob = pollingJob;
if (localPollingJob == null || localPollingJob.isCancelled()) {
long pollingInterval = 10;
logger.debug("Start polling job for device '{}' at interval {}s", deviceId, pollingInterval);
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
handleAction(GET_ENERGY_STATS, deviceId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2010-2025 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.avmfritz.internal.dto.json;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import org.eclipse.jdt.annotation.NonNullByDefault;

import com.google.gson.Gson;

/**
* Abstract Test cases for Plain Old Java Objects.
*
* @author Christoph Weitkamp - Initial contribution
*/
@NonNullByDefault
public abstract class AbstractJSONTest {

protected final Gson gson = new Gson();

protected <T> T getObjectFromJson(String filename, Class<T> clazz, Gson gson) throws IOException {
try (InputStream inputStream = AbstractJSONTest.class.getResourceAsStream(filename)) {
if (inputStream == null) {
throw new IOException("InputStream is null");
}
byte[] bytes = inputStream.readAllBytes();
if (bytes == null) {
throw new IOException("Resulting byte-array empty");
}
String json = new String(bytes, StandardCharsets.UTF_8);
return Objects.requireNonNull(gson.fromJson(json, clazz));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2010-2025 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.avmfritz.internal.dto.json;

import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;

/**
* * Test cases for {@link EnergyStats} Plain Old Java Objects.
*
* @author Christoph Weitkamp - Initial contribution
*/
@NonNullByDefault
public class EnergyStatsTest extends AbstractJSONTest {
public static final double DELTA = 0.0001;

@Test
public void currentStateUpdateTest() throws IOException {
EnergyStats energyStats = getObjectFromJson("EnergyStats.json", EnergyStats.class, gson);
assertNotNull(energyStats);

assertEquals(-9999, energyStats.mMValueVolt);
assertEquals(-99.99, energyStats.getScaledVoltage(), DELTA);
assertEquals(36100, energyStats.mMValuePower);
assertEquals(361.00, energyStats.getScaledPower(), DELTA);
assertEquals(17849392, energyStats.mMValueEnergy);
assertEquals(17849.392, energyStats.getScaledEnergy(), DELTA);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"DeviceConnectState": "2",
"VoltageStat":
{
"ebene": 0,
"anzahl": 60,
"values":
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"times_type": 10,
"ID": 2001,
"datatimestamp": 0
},
"MM_Value_Amp": -9999,
"sum_Year": 0,
"tabType": "10",
"sum_Day": 0,
"MM_Value_Volt": -9999,
"MM_Value_Power": 36100,
"MM_Value_Energy": 17849392,
"DeviceID": "2001",
"DeviceSwitchState": "0",
"EnergyStat":
{
"ebene": 0,
"anzahl": 60,
"values":
[
36100,
36000,
36900,
34300,
36100,
36200,
34900,
40100,
38900,
37400,
40000,
34900,
31800,
35900,
36900,
28600,
29300,
32200,
24100,
34900,
30000,
23100,
29700,
33000,
35400,
32300,
34300,
28800,
30500,
32700,
30700,
29500,
31400,
30800,
28600,
32400,
31800,
30800,
32000,
32000,
24100,
34800,
40500,
30700,
41900,
36400,
27700,
37600,
37600,
43800,
34700,
31600,
36000,
38000,
34900,
36100,
35000,
35900,
33800,
35200
],
"times_type": 10,
"ID": 2001,
"datatimestamp": 1761321051
},
"CurrentDateInSec": "1761321052",
"sum_Month": 0,
"RequestResult": true
}