mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 07:02:02 +01:00
Merge 3b2ccadeba
into a1fc3632e6
This commit is contained in:
commit
7eb3b4057d
@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.awattar.internal;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
@ -47,7 +49,18 @@ public abstract class AwattarBestPriceResult {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean isActive();
|
||||
/**
|
||||
* Returns true if the best price is active.
|
||||
*
|
||||
* @param pointInTime the current time
|
||||
* @return true if the best price is active, false otherwise
|
||||
*/
|
||||
public abstract boolean isActive(Instant pointInTime);
|
||||
|
||||
/**
|
||||
* Returns the hours of the best price.
|
||||
*
|
||||
* @return the hours of the best price as a string
|
||||
*/
|
||||
public abstract String getHours();
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ public class AwattarConsecutiveBestPriceResult extends AwattarBestPriceResult {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return contains(Instant.now().toEpochMilli());
|
||||
public boolean isActive(Instant pointInTime) {
|
||||
return contains(pointInTime.toEpochMilli());
|
||||
}
|
||||
|
||||
public boolean contains(long timestamp) {
|
||||
|
@ -32,7 +32,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
public class AwattarNonConsecutiveBestPriceResult extends AwattarBestPriceResult {
|
||||
private final List<AwattarPrice> members;
|
||||
private final ZoneId zoneId;
|
||||
private boolean sorted = true;
|
||||
|
||||
public AwattarNonConsecutiveBestPriceResult(List<AwattarPrice> prices, int length, boolean inverted,
|
||||
ZoneId zoneId) {
|
||||
@ -57,15 +56,14 @@ public class AwattarNonConsecutiveBestPriceResult extends AwattarBestPriceResult
|
||||
}
|
||||
|
||||
private void addMember(AwattarPrice member) {
|
||||
sorted = false;
|
||||
members.add(member);
|
||||
updateStart(member.timerange().start());
|
||||
updateEnd(member.timerange().end());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return members.stream().anyMatch(x -> x.timerange().contains(Instant.now().toEpochMilli()));
|
||||
public boolean isActive(Instant pointInTime) {
|
||||
return members.stream().anyMatch(x -> x.timerange().contains(pointInTime.toEpochMilli()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,16 +71,9 @@ public class AwattarNonConsecutiveBestPriceResult extends AwattarBestPriceResult
|
||||
return String.format("NonConsecutiveBestpriceResult with %s", members.toString());
|
||||
}
|
||||
|
||||
private void sort() {
|
||||
if (!sorted) {
|
||||
members.sort(Comparator.comparingLong(p -> p.timerange().start()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHours() {
|
||||
boolean second = false;
|
||||
sort();
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
for (AwattarPrice price : members) {
|
||||
|
@ -20,7 +20,6 @@ import java.time.temporal.ChronoUnit;
|
||||
import javax.measure.quantity.Time;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
|
||||
@ -32,9 +31,9 @@ import org.openhab.core.library.unit.Units;
|
||||
@NonNullByDefault
|
||||
public class AwattarUtil {
|
||||
|
||||
public static long getMillisToNextMinute(int mod, TimeZoneProvider timeZoneProvider) {
|
||||
public static long getMillisToNextMinute(int mod, ZoneId zoneId) {
|
||||
long now = Instant.now().toEpochMilli();
|
||||
ZonedDateTime dt = ZonedDateTime.now(timeZoneProvider.getTimeZone()).truncatedTo(ChronoUnit.MINUTES);
|
||||
ZonedDateTime dt = ZonedDateTime.now(zoneId).truncatedTo(ChronoUnit.MINUTES);
|
||||
int min = dt.getMinute();
|
||||
int offset = min % mod;
|
||||
offset = offset == 0 ? mod : offset;
|
||||
|
@ -23,6 +23,7 @@ import static org.openhab.binding.awattar.internal.AwattarUtil.getCalendarForHou
|
||||
import static org.openhab.binding.awattar.internal.AwattarUtil.getDuration;
|
||||
import static org.openhab.binding.awattar.internal.AwattarUtil.getMillisToNextMinute;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
@ -39,7 +40,6 @@ import org.openhab.binding.awattar.internal.AwattarBestPriceResult;
|
||||
import org.openhab.binding.awattar.internal.AwattarConsecutiveBestPriceResult;
|
||||
import org.openhab.binding.awattar.internal.AwattarNonConsecutiveBestPriceResult;
|
||||
import org.openhab.binding.awattar.internal.AwattarPrice;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
@ -67,17 +67,17 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
private final Clock clock;
|
||||
|
||||
private static final int THING_REFRESH_INTERVAL = 60;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AwattarBestPriceHandler.class);
|
||||
|
||||
private @Nullable ScheduledFuture<?> thingRefresher;
|
||||
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
|
||||
public AwattarBestPriceHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
|
||||
public AwattarBestPriceHandler(Thing thing, Clock clock) {
|
||||
super(thing);
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,7 +97,7 @@ public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
* here
|
||||
*/
|
||||
thingRefresher = scheduler.scheduleAtFixedRate(this::refreshChannels,
|
||||
getMillisToNextMinute(1, timeZoneProvider), THING_REFRESH_INTERVAL * 1000L,
|
||||
getMillisToNextMinute(1, clock.getZone()), THING_REFRESH_INTERVAL * 1000L,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
long diff;
|
||||
switch (channelId) {
|
||||
case CHANNEL_ACTIVE:
|
||||
state = OnOffType.from(result.isActive());
|
||||
state = OnOffType.from(result.isActive(clock.instant()));
|
||||
break;
|
||||
case CHANNEL_START:
|
||||
state = new DateTimeType(Instant.ofEpochMilli(result.getStart()));
|
||||
@ -172,7 +172,7 @@ public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
state = new DateTimeType(Instant.ofEpochMilli(result.getEnd()));
|
||||
break;
|
||||
case CHANNEL_COUNTDOWN:
|
||||
diff = result.getStart() - Instant.now().toEpochMilli();
|
||||
diff = result.getStart() - clock.instant().toEpochMilli();
|
||||
if (diff >= 0) {
|
||||
state = getDuration(diff);
|
||||
} else {
|
||||
@ -180,8 +180,8 @@ public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
}
|
||||
break;
|
||||
case CHANNEL_REMAINING:
|
||||
if (result.isActive()) {
|
||||
diff = result.getEnd() - Instant.now().toEpochMilli();
|
||||
if (result.isActive(clock.instant())) {
|
||||
diff = result.getEnd() - clock.instant().toEpochMilli();
|
||||
state = getDuration(diff);
|
||||
} else {
|
||||
state = QuantityType.valueOf(0, Units.MINUTE);
|
||||
@ -216,20 +216,39 @@ public class AwattarBestPriceHandler extends BaseThingHandler {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time range for the given start hour and duration.
|
||||
*
|
||||
* @param start the start hour (0-23)
|
||||
* @param duration the duration in hours
|
||||
* @param zoneId the time zone to use
|
||||
* @return the range
|
||||
*/
|
||||
protected TimeRange getRange(int start, int duration, ZoneId zoneId) {
|
||||
ZonedDateTime startCal = getCalendarForHour(start, zoneId);
|
||||
ZonedDateTime endCal = startCal.plusHours(duration);
|
||||
ZonedDateTime now = ZonedDateTime.now(zoneId);
|
||||
ZonedDateTime startTime = getStartTime(start, zoneId);
|
||||
ZonedDateTime endTime = startTime.plusHours(duration);
|
||||
ZonedDateTime now = clock.instant().atZone(zoneId);
|
||||
if (now.getHour() < start) {
|
||||
// we are before the range, so we might be still within the last range
|
||||
startCal = startCal.minusDays(1);
|
||||
endCal = endCal.minusDays(1);
|
||||
startTime = startTime.minusDays(1);
|
||||
endTime = endTime.minusDays(1);
|
||||
}
|
||||
if (endCal.toInstant().toEpochMilli() < Instant.now().toEpochMilli()) {
|
||||
if (endTime.isBefore(now)) {
|
||||
// span is in the past, add one day
|
||||
startCal = startCal.plusDays(1);
|
||||
endCal = endCal.plusDays(1);
|
||||
startTime = startTime.plusDays(1);
|
||||
endTime = endTime.plusDays(1);
|
||||
}
|
||||
return new TimeRange(startCal.toInstant().toEpochMilli(), endCal.toInstant().toEpochMilli());
|
||||
return new TimeRange(startTime.toInstant().toEpochMilli(), endTime.toInstant().toEpochMilli());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start time for the given hour.
|
||||
*
|
||||
* @param start the hour. Must be between 0 and 23.
|
||||
* @param zoneId the time zone
|
||||
* @return the start time
|
||||
*/
|
||||
protected ZonedDateTime getStartTime(int start, ZoneId zoneId) {
|
||||
return getCalendarForHour(start, zoneId);
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,14 @@ package org.openhab.binding.awattar.internal.handler;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_MARKET_NET;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_TOTAL_NET;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
@ -32,7 +33,6 @@ import org.openhab.binding.awattar.internal.AwattarBridgeConfiguration;
|
||||
import org.openhab.binding.awattar.internal.AwattarPrice;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi.AwattarApiException;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.CurrencyUnits;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@ -65,20 +65,20 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AwattarBridgeHandler.class);
|
||||
private final HttpClient httpClient;
|
||||
private final Clock clock;
|
||||
|
||||
private @Nullable ScheduledFuture<?> dataRefresher;
|
||||
private Instant lastRefresh = Instant.EPOCH;
|
||||
|
||||
// This cache stores price data for up to two days
|
||||
private @Nullable SortedSet<AwattarPrice> prices;
|
||||
private ZoneId zone;
|
||||
|
||||
private @Nullable AwattarApi awattarApi;
|
||||
|
||||
public AwattarBridgeHandler(Bridge thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) {
|
||||
public AwattarBridgeHandler(Bridge thing, HttpClient httpClient, Clock clock) {
|
||||
super(thing);
|
||||
this.httpClient = httpClient;
|
||||
zone = timeZoneProvider.getTimeZone();
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,7 +87,7 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
AwattarBridgeConfiguration config = getConfigAs(AwattarBridgeConfiguration.class);
|
||||
|
||||
try {
|
||||
awattarApi = new AwattarApi(httpClient, zone, config);
|
||||
awattarApi = new AwattarApi(httpClient, clock.getZone(), config);
|
||||
|
||||
dataRefresher = scheduler.scheduleWithFixedDelay(this::refreshIfNeeded, 0, DATA_REFRESH_INTERVAL * 1000L,
|
||||
TimeUnit.MILLISECONDS);
|
||||
@ -154,17 +154,15 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
return priceUnit;
|
||||
}
|
||||
|
||||
private void createAndSendTimeSeries(String channelId, Function<AwattarPrice, Double> valueFunction) {
|
||||
private void createAndSendTimeSeries(String channelId, ToDoubleFunction<AwattarPrice> valueFunction) {
|
||||
SortedSet<AwattarPrice> locPrices = getPrices();
|
||||
Unit<?> priceUnit = getPriceUnit();
|
||||
if (locPrices == null) {
|
||||
return;
|
||||
}
|
||||
TimeSeries timeSeries = new TimeSeries(TimeSeries.Policy.REPLACE);
|
||||
locPrices.forEach(p -> {
|
||||
timeSeries.add(Instant.ofEpochMilli(p.timerange().start()),
|
||||
new QuantityType<>(valueFunction.apply(p) / 100.0, priceUnit));
|
||||
});
|
||||
locPrices.forEach(p -> timeSeries.add(Instant.ofEpochMilli(p.timerange().start()),
|
||||
new QuantityType<>(valueFunction.applyAsDouble(p) / 100.0, priceUnit)));
|
||||
sendTimeSeries(channelId, timeSeries);
|
||||
}
|
||||
|
||||
@ -186,11 +184,13 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
private boolean needRefresh() {
|
||||
// if the thing is offline, we need to refresh
|
||||
if (getThing().getStatus() != ThingStatus.ONLINE) {
|
||||
lastRefresh = clock.instant();
|
||||
return true;
|
||||
}
|
||||
|
||||
// if the local cache is empty, we need to refresh
|
||||
if (prices == null) {
|
||||
lastRefresh = clock.instant();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -200,15 +200,15 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
|
||||
// do not refresh before 15:00, since the prices for the next day are available
|
||||
// only after 14:00
|
||||
ZonedDateTime now = ZonedDateTime.now(zone);
|
||||
ZonedDateTime now = ZonedDateTime.now(clock);
|
||||
if (now.getHour() < 15) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// refresh then every 3 hours, if the last refresh was more than an hour ago
|
||||
// refresh at 15:00, 18:00 and 21:00 if the last refresh was more than an hour ago
|
||||
if (now.getHour() % 3 == 0 && lastRefresh.getEpochSecond() < now.minusHours(1).toEpochSecond()) {
|
||||
// update the last refresh time
|
||||
lastRefresh = Instant.now();
|
||||
lastRefresh = clock.instant();
|
||||
|
||||
// return true to indicate an update is needed
|
||||
return true;
|
||||
@ -218,7 +218,7 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
}
|
||||
|
||||
public ZoneId getTimeZone() {
|
||||
return zone;
|
||||
return clock.getZone();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -261,6 +261,7 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
|
||||
switch (channelUID.getId()) {
|
||||
case CHANNEL_MARKET_NET -> createAndSendTimeSeries(CHANNEL_MARKET_NET, AwattarPrice::netPrice);
|
||||
case CHANNEL_TOTAL_NET -> createAndSendTimeSeries(CHANNEL_TOTAL_NET, AwattarPrice::netTotal);
|
||||
default -> logger.warn("Channel {} not supported", channelUID.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import static org.openhab.binding.awattar.internal.AwattarBindingConstants.THING
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.THING_TYPE_BRIDGE;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.THING_TYPE_PRICE;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@ -50,13 +51,13 @@ public class AwattarHandlerFactory extends BaseThingHandlerFactory {
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_PRICE, THING_TYPE_BESTPRICE,
|
||||
THING_TYPE_BRIDGE);
|
||||
private final HttpClient httpClient;
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private final Clock systemClock;
|
||||
|
||||
@Activate
|
||||
public AwattarHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
|
||||
final @Reference TimeZoneProvider timeZoneProvider) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.systemClock = Clock.system(timeZoneProvider.getTimeZone());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,11 +70,11 @@ public class AwattarHandlerFactory extends BaseThingHandlerFactory {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_BRIDGE.equals(thingTypeUID)) {
|
||||
return new AwattarBridgeHandler((Bridge) thing, httpClient, timeZoneProvider);
|
||||
return new AwattarBridgeHandler((Bridge) thing, httpClient, systemClock);
|
||||
} else if (THING_TYPE_PRICE.equals(thingTypeUID)) {
|
||||
return new AwattarPriceHandler(thing, timeZoneProvider);
|
||||
return new AwattarPriceHandler(thing, systemClock);
|
||||
} else if (THING_TYPE_BESTPRICE.equals(thingTypeUID)) {
|
||||
return new AwattarBestPriceHandler(thing, timeZoneProvider);
|
||||
return new AwattarBestPriceHandler(thing, systemClock);
|
||||
}
|
||||
|
||||
logger.warn("Unknown thing type {}, not creating handler!", thingTypeUID);
|
||||
|
@ -23,6 +23,7 @@ import static org.openhab.binding.awattar.internal.AwattarUtil.getMillisToNextMi
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Clock;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -30,7 +31,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.awattar.internal.AwattarPrice;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@ -55,15 +55,16 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AwattarPriceHandler extends BaseThingHandler {
|
||||
private final Clock clock;
|
||||
|
||||
private static final int THING_REFRESH_INTERVAL = 60;
|
||||
private final Logger logger = LoggerFactory.getLogger(AwattarPriceHandler.class);
|
||||
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private @Nullable ScheduledFuture<?> thingRefresher;
|
||||
|
||||
public AwattarPriceHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
|
||||
public AwattarPriceHandler(Thing thing, Clock clock) {
|
||||
super(thing);
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -90,7 +91,7 @@ public class AwattarPriceHandler extends BaseThingHandler {
|
||||
* here
|
||||
*/
|
||||
thingRefresher = scheduler.scheduleAtFixedRate(this::refreshChannels,
|
||||
getMillisToNextMinute(1, timeZoneProvider), THING_REFRESH_INTERVAL * 1000,
|
||||
getMillisToNextMinute(1, clock.getZone()), THING_REFRESH_INTERVAL * 1000L,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
@ -153,7 +154,7 @@ public class AwattarPriceHandler extends BaseThingHandler {
|
||||
AwattarPrice price = bridgeHandler.getPriceFor(target.toInstant().toEpochMilli());
|
||||
|
||||
if (price == null) {
|
||||
logger.trace("No price found for hour {}", target.toString());
|
||||
logger.trace("No price found for hour {}", target);
|
||||
updateState(channelUID, state);
|
||||
return;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.awattar.internal.handler.TimeRange;
|
||||
|
||||
@ -33,6 +34,7 @@ import org.openhab.binding.awattar.internal.handler.TimeRange;
|
||||
*
|
||||
* @author Thomas Leber - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AwattarBestPriceTest {
|
||||
|
||||
private ZoneId zoneId = ZoneId.of("GMT");
|
||||
@ -85,7 +87,7 @@ public class AwattarBestPriceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void AwattarNonConsecutiveBestPriceResult_nonInverted() {
|
||||
void AwattarNonConsecutiveBestPriceResultNonInverted() {
|
||||
int length = 6;
|
||||
boolean inverted = false;
|
||||
|
||||
@ -98,7 +100,7 @@ public class AwattarBestPriceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void AwattarNonConsecutiveBestPriceResult_inverted() {
|
||||
void AwattarNonConsecutiveBestPriceResultInverted() {
|
||||
int length = 4;
|
||||
boolean inverted = true;
|
||||
|
||||
|
@ -45,7 +45,6 @@ import org.mockito.quality.Strictness;
|
||||
import org.openhab.binding.awattar.internal.AwattarBridgeConfiguration;
|
||||
import org.openhab.binding.awattar.internal.AwattarPrice;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi.AwattarApiException;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.test.java.JavaTest;
|
||||
|
||||
/**
|
||||
@ -60,7 +59,6 @@ import org.openhab.core.test.java.JavaTest;
|
||||
class AwattarApiTest extends JavaTest {
|
||||
// API Mocks
|
||||
private @Mock @NonNullByDefault({}) HttpClient httpClientMock;
|
||||
private @Mock @NonNullByDefault({}) TimeZoneProvider timeZoneProviderMock;
|
||||
private @Mock @NonNullByDefault({}) Request requestMock;
|
||||
private @Mock @NonNullByDefault({}) ContentResponse contentResponseMock;
|
||||
private @Mock @NonNullByDefault({}) AwattarBridgeConfiguration config;
|
||||
@ -86,8 +84,6 @@ class AwattarApiTest extends JavaTest {
|
||||
when(requestMock.timeout(10, TimeUnit.SECONDS)).thenReturn(requestMock);
|
||||
when(requestMock.send()).thenReturn(contentResponseMock);
|
||||
|
||||
when(timeZoneProviderMock.getTimeZone()).thenReturn(ZoneId.of("GMT+2"));
|
||||
|
||||
config.basePrice = 0.0;
|
||||
config.vatPercent = 0.0;
|
||||
config.country = "DE";
|
||||
|
@ -19,14 +19,20 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.platform.commons.support.HierarchyTraversalMode;
|
||||
import org.junit.platform.commons.support.ReflectionSupport;
|
||||
import org.mockito.Mock;
|
||||
@ -36,7 +42,6 @@ import org.mockito.quality.Strictness;
|
||||
import org.openhab.binding.awattar.internal.AwattarBindingConstants;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi.AwattarApiException;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.test.java.JavaTest;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@ -62,7 +67,8 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
private @Mock @NonNullByDefault({}) Bridge bridgeMock;
|
||||
private @Mock @NonNullByDefault({}) ThingHandlerCallback bridgeCallbackMock;
|
||||
private @Mock @NonNullByDefault({}) HttpClient httpClientMock;
|
||||
private @Mock @NonNullByDefault({}) TimeZoneProvider timeZoneProviderMock;
|
||||
private @Mock @NonNullByDefault({}) Clock clockMock;
|
||||
private @Mock @NonNullByDefault({}) Clock fixedClock;
|
||||
private @Mock @NonNullByDefault({}) AwattarApi awattarApiMock;
|
||||
|
||||
// best price handler mocks
|
||||
@ -73,10 +79,8 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IllegalArgumentException, IllegalAccessException {
|
||||
when(timeZoneProviderMock.getTimeZone()).thenReturn(ZoneId.of("GMT+2"));
|
||||
|
||||
when(bridgeMock.getUID()).thenReturn(BRIDGE_UID);
|
||||
bridgeHandler = new AwattarBridgeHandler(bridgeMock, httpClientMock, timeZoneProviderMock);
|
||||
bridgeHandler = new AwattarBridgeHandler(bridgeMock, httpClientMock, clockMock);
|
||||
bridgeHandler.setCallback(bridgeCallbackMock);
|
||||
|
||||
List<Field> fields = ReflectionSupport.findFields(AwattarBridgeHandler.class,
|
||||
@ -95,7 +99,7 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
* @throws AwattarApiException
|
||||
*/
|
||||
@Test
|
||||
void testRefreshIfNeeded_ThingOffline() throws SecurityException, AwattarApiException {
|
||||
void testRefreshIfNeededThingOffline() throws SecurityException, AwattarApiException {
|
||||
when(bridgeMock.getStatus()).thenReturn(ThingStatus.OFFLINE);
|
||||
|
||||
bridgeHandler.refreshIfNeeded();
|
||||
@ -113,7 +117,7 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
* @throws AwattarApiException
|
||||
*/
|
||||
@Test
|
||||
void testRefreshIfNeeded_DataEmpty() throws SecurityException, AwattarApiException {
|
||||
void testRefreshIfNeededDataEmpty() throws SecurityException, AwattarApiException {
|
||||
when(bridgeMock.getStatus()).thenReturn(ThingStatus.ONLINE);
|
||||
|
||||
bridgeHandler.refreshIfNeeded();
|
||||
@ -124,7 +128,7 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNeedRefresh_ThingOffline() throws SecurityException {
|
||||
void testNeedRefreshThingOffline() throws SecurityException {
|
||||
when(bridgeMock.getStatus()).thenReturn(ThingStatus.OFFLINE);
|
||||
|
||||
// get private method via reflection
|
||||
@ -136,7 +140,7 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNeedRefresh_DataEmpty() throws SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
void testNeedRefreshDataEmpty() throws SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
when(bridgeMock.getStatus()).thenReturn(ThingStatus.ONLINE);
|
||||
|
||||
List<Field> fields = ReflectionSupport.findFields(AwattarBridgeHandler.class,
|
||||
@ -154,4 +158,67 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
|
||||
|
||||
assertThat(result, is(true));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> testNeedRefreshTimes() {
|
||||
return Stream.of(
|
||||
// Update at 15:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T12:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T13:30:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T12:00:00Z"), Instant.parse("2021-01-01T13:30:00Z"), true),
|
||||
|
||||
// Update at 16:00 GMT+2 and 17:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T14:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T15:00:00Z"), false),
|
||||
|
||||
// Update at 18:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T16:00:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T15:00:00Z"), Instant.parse("2021-01-01T16:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T16:30:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T15:00:00Z"), Instant.parse("2021-01-01T16:30:00Z"), true),
|
||||
|
||||
// Update at 19:00 GMT+2 and 20:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T17:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T18:00:00Z"), false),
|
||||
|
||||
// Update at 21:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T19:00:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T18:00:00Z"), Instant.parse("2021-01-01T19:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T19:30:00Z"), true),
|
||||
Arguments.of(Instant.parse("2021-01-01T18:00:00Z"), Instant.parse("2021-01-01T19:30:00Z"), true),
|
||||
|
||||
// Update at 22:00 GMT+2, 23:00 GMT+2 and 00:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T20:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T21:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T22:00:00Z"), false),
|
||||
|
||||
// Update before 15:00 GMT+2
|
||||
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T14:00:00Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T10:59:58Z"), Instant.parse("2021-01-01T11:59:59Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T11:59:59Z"), Instant.parse("2021-01-01T11:59:59Z"), false),
|
||||
Arguments.of(Instant.parse("2021-01-01T13:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), false));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testNeedRefreshTimes(Instant lastUpdate, Instant nowUpdate, Boolean expectedResult) {
|
||||
when(bridgeMock.getStatus()).thenReturn(ThingStatus.ONLINE);
|
||||
|
||||
fixedClock = Clock.fixed(lastUpdate, ZoneId.of("GMT+2"));
|
||||
when(clockMock.getZone()).thenReturn(fixedClock.getZone());
|
||||
when(clockMock.instant()).thenReturn(fixedClock.instant());
|
||||
|
||||
bridgeHandler.refreshIfNeeded();
|
||||
|
||||
fixedClock = Clock.fixed(nowUpdate, ZoneId.of("GMT+2"));
|
||||
when(clockMock.getZone()).thenReturn(fixedClock.getZone());
|
||||
when(clockMock.instant()).thenReturn(fixedClock.instant());
|
||||
|
||||
// get private method via reflection
|
||||
Method method = ReflectionSupport.findMethod(AwattarBridgeHandler.class, "needRefresh", "").get();
|
||||
|
||||
boolean result = (boolean) ReflectionSupport.invokeMethod(method, bridgeHandler);
|
||||
|
||||
assertThat(result, is(expectedResult));
|
||||
}
|
||||
}
|
||||
|
@ -20,14 +20,20 @@ import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_ACTIVE;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_COUNTDOWN;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_END;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_HOURS;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_REMAINING;
|
||||
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_START;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -56,8 +62,9 @@ import org.openhab.binding.awattar.internal.api.AwattarApi;
|
||||
import org.openhab.binding.awattar.internal.api.AwattarApi.AwattarApiException;
|
||||
import org.openhab.binding.awattar.internal.dto.AwattarApiData;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.test.java.JavaTest;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@ -84,7 +91,6 @@ public class AwattarBridgeHandlerTest extends JavaTest {
|
||||
private @Mock @NonNullByDefault({}) Bridge bridgeMock;
|
||||
private @Mock @NonNullByDefault({}) ThingHandlerCallback bridgeCallbackMock;
|
||||
private @Mock @NonNullByDefault({}) HttpClient httpClientMock;
|
||||
private @Mock @NonNullByDefault({}) TimeZoneProvider timeZoneProviderMock;
|
||||
private @Mock @NonNullByDefault({}) AwattarApi awattarApiMock;
|
||||
|
||||
// best price handler mocks
|
||||
@ -109,10 +115,10 @@ public class AwattarBridgeHandlerTest extends JavaTest {
|
||||
when(awattarApiMock.getData()).thenReturn(result);
|
||||
}
|
||||
|
||||
when(timeZoneProviderMock.getTimeZone()).thenReturn(ZoneId.of("GMT+2"));
|
||||
Clock clock = Clock.fixed(Instant.parse("2024-06-15T12:00:00Z"), ZoneId.of("GMT+2"));
|
||||
|
||||
when(bridgeMock.getUID()).thenReturn(BRIDGE_UID);
|
||||
bridgeHandler = new AwattarBridgeHandler(bridgeMock, httpClientMock, timeZoneProviderMock);
|
||||
bridgeHandler = new AwattarBridgeHandler(bridgeMock, httpClientMock, clock);
|
||||
bridgeHandler.setCallback(bridgeCallbackMock);
|
||||
|
||||
// mock the private field awattarApi
|
||||
@ -166,31 +172,95 @@ public class AwattarBridgeHandlerTest extends JavaTest {
|
||||
|
||||
public static Stream<Arguments> testBestpriceHandler() {
|
||||
return Stream.of( //
|
||||
Arguments.of(1, true, CHANNEL_START, new DateTimeType("2024-06-15T14:00:00.000+0200")),
|
||||
Arguments.of(1, true, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(1, true, CHANNEL_HOURS, new StringType("14")),
|
||||
Arguments.of(1, false, CHANNEL_START, new DateTimeType("2024-06-15T14:00:00.000+0200")),
|
||||
Arguments.of(1, false, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(1, false, CHANNEL_HOURS, new StringType("14")),
|
||||
Arguments.of(2, true, CHANNEL_START, new DateTimeType("2024-06-15T13:00:00.000+0200")),
|
||||
Arguments.of(2, true, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(2, true, CHANNEL_HOURS, new StringType("13,14")),
|
||||
Arguments.of(2, false, CHANNEL_START, new DateTimeType("2024-06-15T13:00:00.000+0200")),
|
||||
Arguments.of(2, false, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(2, false, CHANNEL_HOURS, new StringType("13,14")));
|
||||
Arguments.of(24, 1, true, CHANNEL_START, new DateTimeType("2024-06-15T14:00:00.000+0200")),
|
||||
Arguments.of(24, 1, true, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(24, 1, true, CHANNEL_HOURS, new StringType("14")),
|
||||
Arguments.of(24, 1, false, CHANNEL_START, new DateTimeType("2024-06-15T14:00:00.000+0200")),
|
||||
Arguments.of(24, 1, false, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(24, 1, false, CHANNEL_HOURS, new StringType("14")),
|
||||
Arguments.of(24, 2, true, CHANNEL_START, new DateTimeType("2024-06-15T13:00:00.000+0200")),
|
||||
Arguments.of(24, 2, true, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(24, 2, true, CHANNEL_HOURS, new StringType("13,14")),
|
||||
Arguments.of(24, 2, false, CHANNEL_START, new DateTimeType("2024-06-15T13:00:00.000+0200")),
|
||||
Arguments.of(24, 2, false, CHANNEL_END, new DateTimeType("2024-06-15T15:00:00.000+0200")),
|
||||
Arguments.of(24, 2, false, CHANNEL_HOURS, new StringType("13,14")),
|
||||
Arguments.of(34, 4, false, CHANNEL_START, new DateTimeType("2024-06-15T12:00:00.000+0200")),
|
||||
Arguments.of(34, 4, false, CHANNEL_END, new DateTimeType("2024-06-15T16:00:00.000+0200")),
|
||||
Arguments.of(34, 4, false, CHANNEL_HOURS, new StringType("12,13,14,15")),
|
||||
Arguments.of(34, 8, false, CHANNEL_START, new DateTimeType("2024-06-15T12:00:00.000+0200")),
|
||||
Arguments.of(34, 8, false, CHANNEL_END, new DateTimeType("2024-06-16T16:00:00.000+0200")),
|
||||
Arguments.of(34, 8, false, CHANNEL_HOURS, new StringType("12,13,14,15,16,13,14,15")));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testBestpriceHandler(int length, boolean consecutive, String channelId, State expectedState) {
|
||||
void testBestpriceHandler(int rangeDuration, int length, boolean consecutive, String channelId,
|
||||
State expectedState) {
|
||||
ThingUID bestPriceUid = new ThingUID(AwattarBindingConstants.THING_TYPE_BESTPRICE, "foo");
|
||||
Map<String, Object> config = Map.of("length", length, "consecutive", consecutive);
|
||||
Map<String, Object> config = Map.of("rangeDuration", rangeDuration, "length", length, "consecutive",
|
||||
consecutive);
|
||||
when(bestpriceMock.getConfiguration()).thenReturn(new Configuration(config));
|
||||
|
||||
AwattarBestPriceHandler handler = new AwattarBestPriceHandler(bestpriceMock, timeZoneProviderMock) {
|
||||
@Override
|
||||
protected TimeRange getRange(int start, int duration, ZoneId zoneId) {
|
||||
return new TimeRange(1718402400000L, 1718488800000L);
|
||||
AwattarBestPriceHandler handler = new AwattarBestPriceHandler(bestpriceMock,
|
||||
Clock.fixed(Instant.parse("2024-06-15T12:00:00Z"), ZoneId.of("GMT+2"))) {
|
||||
protected ZonedDateTime getStartTime(int start, ZoneId zoneId) {
|
||||
return ZonedDateTime.of(2024, 6, 15, 12, 0, 0, 0, zoneId);
|
||||
}
|
||||
};
|
||||
|
||||
handler.setCallback(bestPriceCallbackMock);
|
||||
|
||||
ChannelUID channelUID = new ChannelUID(bestPriceUid, channelId);
|
||||
handler.refreshChannel(channelUID);
|
||||
verify(bestPriceCallbackMock).stateUpdated(channelUID, expectedState);
|
||||
}
|
||||
|
||||
public static Stream<Arguments> testBestpriceHandlerChannels() {
|
||||
return Stream.of( //
|
||||
Arguments.of(12, 0, 24, 1, true, CHANNEL_HOURS, new StringType("14")),
|
||||
Arguments.of(12, 0, 24, 1, true, CHANNEL_ACTIVE, OnOffType.from(false)),
|
||||
Arguments.of(12, 0, 24, 1, true, CHANNEL_COUNTDOWN, new QuantityType<>("120 min")),
|
||||
Arguments.of(12, 0, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("0 min")),
|
||||
|
||||
Arguments.of(13, 59, 24, 1, true, CHANNEL_COUNTDOWN, new QuantityType<>("1 min")),
|
||||
Arguments.of(13, 59, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("0 min")),
|
||||
Arguments.of(13, 59, 24, 1, false, CHANNEL_ACTIVE, OnOffType.from(false)),
|
||||
Arguments.of(13, 59, 24, 1, true, CHANNEL_ACTIVE, OnOffType.from(false)),
|
||||
|
||||
Arguments.of(14, 01, 24, 1, true, CHANNEL_COUNTDOWN, new QuantityType<>("0 min")),
|
||||
Arguments.of(14, 01, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("59 min")),
|
||||
Arguments.of(14, 01, 24, 1, false, CHANNEL_ACTIVE, OnOffType.from(true)),
|
||||
Arguments.of(14, 01, 24, 1, true, CHANNEL_ACTIVE, OnOffType.from(true)),
|
||||
|
||||
Arguments.of(14, 59, 24, 1, true, CHANNEL_COUNTDOWN, new QuantityType<>("0 min")),
|
||||
Arguments.of(14, 59, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("1 min")),
|
||||
Arguments.of(14, 59, 24, 1, false, CHANNEL_ACTIVE, OnOffType.from(true)),
|
||||
Arguments.of(14, 59, 24, 1, true, CHANNEL_ACTIVE, OnOffType.from(true)),
|
||||
|
||||
Arguments.of(15, 00, 24, 1, true, CHANNEL_COUNTDOWN, new QuantityType<>("0 min")),
|
||||
Arguments.of(15, 00, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("0 min")),
|
||||
Arguments.of(15, 00, 24, 1, false, CHANNEL_ACTIVE, OnOffType.from(false)),
|
||||
Arguments.of(15, 00, 24, 1, true, CHANNEL_ACTIVE, OnOffType.from(false)),
|
||||
|
||||
Arguments.of(12, 0, 24, 1, true, CHANNEL_REMAINING, new QuantityType<>("0 min")));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testBestpriceHandlerChannels(int currentHour, int currentMinute, int rangeDuration, int length,
|
||||
boolean consecutive, String channelId, State expectedState) {
|
||||
ThingUID bestPriceUid = new ThingUID(AwattarBindingConstants.THING_TYPE_BESTPRICE, "foo");
|
||||
Map<String, Object> config = Map.of("rangeDuration", rangeDuration, "length", length, "consecutive",
|
||||
consecutive);
|
||||
when(bestpriceMock.getConfiguration()).thenReturn(new Configuration(config));
|
||||
|
||||
Clock clock = Clock.fixed(
|
||||
ZonedDateTime.of(2024, 6, 15, currentHour, currentMinute, 0, 0, ZoneId.of("GMT+2")).toInstant(),
|
||||
ZoneId.of("GMT+2"));
|
||||
|
||||
AwattarBestPriceHandler handler = new AwattarBestPriceHandler(bestpriceMock, clock) {
|
||||
protected ZonedDateTime getStartTime(int start, ZoneId zoneId) {
|
||||
return ZonedDateTime.of(2024, 6, 15, 0, 0, 0, 0, clock.getZone());
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user