Simplify DateTimeType handling for Fine Offset Weather Station

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2024-11-17 20:38:13 +01:00 committed by lsiepel
parent baf7ec6c2a
commit c594446eac
11 changed files with 46 additions and 116 deletions

View File

@ -22,7 +22,6 @@ import org.openhab.binding.fineoffsetweatherstation.internal.discovery.FineOffse
import org.openhab.binding.fineoffsetweatherstation.internal.handler.FineOffsetGatewayHandler; import org.openhab.binding.fineoffsetweatherstation.internal.handler.FineOffsetGatewayHandler;
import org.openhab.binding.fineoffsetweatherstation.internal.handler.FineOffsetSensorHandler; import org.openhab.binding.fineoffsetweatherstation.internal.handler.FineOffsetSensorHandler;
import org.openhab.core.i18n.LocaleProvider; import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.i18n.TranslationProvider; import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@ -49,17 +48,15 @@ public class FineOffsetWeatherStationHandlerFactory extends BaseThingHandlerFact
private final ChannelTypeRegistry channelTypeRegistry; private final ChannelTypeRegistry channelTypeRegistry;
private final TranslationProvider translationProvider; private final TranslationProvider translationProvider;
private final LocaleProvider localeProvider; private final LocaleProvider localeProvider;
private final TimeZoneProvider timeZoneProvider;
@Activate @Activate
public FineOffsetWeatherStationHandlerFactory(@Reference FineOffsetGatewayDiscoveryService gatewayDiscoveryService, public FineOffsetWeatherStationHandlerFactory(@Reference FineOffsetGatewayDiscoveryService gatewayDiscoveryService,
@Reference ChannelTypeRegistry channelTypeRegistry, @Reference TranslationProvider translationProvider, @Reference ChannelTypeRegistry channelTypeRegistry, @Reference TranslationProvider translationProvider,
@Reference LocaleProvider localeProvider, @Reference TimeZoneProvider timeZoneProvider) { @Reference LocaleProvider localeProvider) {
this.gatewayDiscoveryService = gatewayDiscoveryService; this.gatewayDiscoveryService = gatewayDiscoveryService;
this.channelTypeRegistry = channelTypeRegistry; this.channelTypeRegistry = channelTypeRegistry;
this.translationProvider = translationProvider; this.translationProvider = translationProvider;
this.localeProvider = localeProvider; this.localeProvider = localeProvider;
this.timeZoneProvider = timeZoneProvider;
} }
@Override @Override
@ -73,7 +70,7 @@ public class FineOffsetWeatherStationHandlerFactory extends BaseThingHandlerFact
if (THING_TYPE_GATEWAY.equals(thingTypeUID) && thing instanceof Bridge bridge) { if (THING_TYPE_GATEWAY.equals(thingTypeUID) && thing instanceof Bridge bridge) {
return new FineOffsetGatewayHandler(bridge, gatewayDiscoveryService, channelTypeRegistry, return new FineOffsetGatewayHandler(bridge, gatewayDiscoveryService, channelTypeRegistry,
translationProvider, localeProvider, timeZoneProvider); translationProvider, localeProvider);
} }
if (THING_TYPE_SENSOR.equals(thingTypeUID)) { if (THING_TYPE_SENSOR.equals(thingTypeUID)) {
return new FineOffsetSensorHandler(thing); return new FineOffsetSensorHandler(thing);

View File

@ -21,7 +21,6 @@ import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketException; import java.net.SocketException;
import java.time.ZoneOffset;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -37,7 +36,6 @@ import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetSensorCon
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants; import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants;
import org.openhab.binding.fineoffsetweatherstation.internal.Utils; import org.openhab.binding.fineoffsetweatherstation.internal.Utils;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SensorDevice; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SensorDevice;
@ -195,10 +193,8 @@ public class FineOffsetGatewayDiscoveryService extends AbstractDiscoveryService
@Nullable @Nullable
private Protocol determineProtocol(FineOffsetGatewayConfiguration config) { private Protocol determineProtocol(FineOffsetGatewayConfiguration config) {
ConversionContext conversionContext = new ConversionContext(ZoneOffset.UTC);
for (Protocol protocol : Protocol.values()) { for (Protocol protocol : Protocol.values()) {
try (GatewayQueryService gatewayQueryService = protocol.getGatewayQueryService(config, null, try (GatewayQueryService gatewayQueryService = protocol.getGatewayQueryService(config, null)) {
conversionContext)) {
Collection<MeasuredValue> result = gatewayQueryService.getMeasuredValues(); Collection<MeasuredValue> result = gatewayQueryService.getMeasuredValues();
logger.trace("found {} measured values via protocol {}", result.size(), protocol); logger.trace("found {} measured values via protocol {}", result.size(), protocol);
if (!result.isEmpty()) { if (!result.isEmpty()) {

View File

@ -1,34 +0,0 @@
/**
* Copyright (c) 2010-2024 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.fineoffsetweatherstation.internal.domain;
import java.time.ZoneId;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* @author Andreas Berger - Initial contribution
*/
@NonNullByDefault
public class ConversionContext {
private final ZoneId zoneId;
public ConversionContext(ZoneId zoneId) {
this.zoneId = zoneId;
}
public ZoneId getZoneId() {
return zoneId;
}
}

View File

@ -246,19 +246,19 @@ public enum Measurand {
return MEASURANDS.get(code); return MEASURANDS.get(code);
} }
private int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context, private int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel,
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result, @Nullable ParserCustomizationType customizationType, List<MeasuredValue> result,
DebugDetails debugDetails) { DebugDetails debugDetails) {
int subOffset = 0; int subOffset = 0;
for (Parser parser : parsers) { for (Parser parser : parsers) {
subOffset += parser.extractMeasuredValues(data, offset + subOffset, channel, context, customizationType, subOffset += parser.extractMeasuredValues(data, offset + subOffset, channel, customizationType, result,
result, debugDetails); debugDetails);
} }
return subOffset; return subOffset;
} }
private interface Parser { private interface Parser {
int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context, int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel,
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result, @Nullable ParserCustomizationType customizationType, List<MeasuredValue> result,
DebugDetails debugDetails); DebugDetails debugDetails);
} }
@ -271,7 +271,7 @@ public enum Measurand {
} }
@Override @Override
public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context, public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel,
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result, @Nullable ParserCustomizationType customizationType, List<MeasuredValue> result,
DebugDetails debugDetails) { DebugDetails debugDetails) {
debugDetails.addDebugDetails(offset, skip, "skipped"); debugDetails.addDebugDetails(offset, skip, "skipped");
@ -312,11 +312,9 @@ public enum Measurand {
this.channel = channel; this.channel = channel;
} }
public int extractMeasuredValues(byte[] data, int offset, ConversionContext context, public int extractMeasuredValues(byte[] data, int offset, @Nullable ParserCustomizationType customizationType,
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result, List<MeasuredValue> result, DebugDetails debugDetails) {
DebugDetails debugDetails) { return measurand.extractMeasuredValues(data, offset, channel, customizationType, result, debugDetails);
return measurand.extractMeasuredValues(data, offset, channel, context, customizationType, result,
debugDetails);
} }
public String getDebugString() { public String getDebugString() {
@ -353,11 +351,11 @@ public enum Measurand {
} }
@Override @Override
public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context, public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel,
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result, @Nullable ParserCustomizationType customizationType, List<MeasuredValue> result,
DebugDetails debugDetails) { DebugDetails debugDetails) {
MeasureType measureType = getMeasureType(customizationType); MeasureType measureType = getMeasureType(customizationType);
State state = measureType.toState(data, offset, context); State state = measureType.toState(data, offset);
if (state != null) { if (state != null) {
debugDetails.addDebugDetails(offset, measureType.getByteSize(), debugDetails.addDebugDetails(offset, measureType.getByteSize(),
measureType.name() + ": " + state.toFullString()); measureType.name() + ": " + state.toFullString());

View File

@ -45,7 +45,6 @@ import static org.openhab.core.library.unit.Units.PARTS_PER_MILLION;
import static org.openhab.core.library.unit.Units.PERCENT; import static org.openhab.core.library.unit.Units.PERCENT;
import java.time.Instant; import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import javax.measure.Unit; import javax.measure.Unit;
@ -97,7 +96,7 @@ public enum MeasureType {
CO2(PARTS_PER_MILLION, 2, CHANNEL_TYPE_CO2, Utils::toUInt16), CO2(PARTS_PER_MILLION, 2, CHANNEL_TYPE_CO2, Utils::toUInt16),
WATER_LEAK_DETECTION(1, CHANNEL_TYPE_WATER_LEAK_DETECTION, WATER_LEAK_DETECTION(1, CHANNEL_TYPE_WATER_LEAK_DETECTION,
(data, offset, context) -> OnOffType.from(toUInt8(data[offset]) != 0)), (data, offset) -> OnOffType.from(toUInt8(data[offset]) != 0)),
LIGHTNING_DISTANCE(KILO(METRE), 1, CHANNEL_TYPE_LIGHTNING_DISTANCE, (data, offset) -> { LIGHTNING_DISTANCE(KILO(METRE), 1, CHANNEL_TYPE_LIGHTNING_DISTANCE, (data, offset) -> {
int distance = toUInt8(data[offset]); int distance = toUInt8(data[offset]);
@ -107,25 +106,23 @@ public enum MeasureType {
return distance; return distance;
}), }),
LIGHTNING_COUNTER(4, CHANNEL_TYPE_LIGHTNING_COUNTER, LIGHTNING_COUNTER(4, CHANNEL_TYPE_LIGHTNING_COUNTER, (data, offset) -> new DecimalType(toUInt32(data, offset))),
(data, offset, context) -> new DecimalType(toUInt32(data, offset))),
LIGHTNING_TIME(4, CHANNEL_TYPE_LIGHTNING_TIME, (data, offset, context) -> { LIGHTNING_TIME(4, CHANNEL_TYPE_LIGHTNING_TIME, (data, offset) -> {
int epochSecond = toUInt32(data, offset); int epochSecond = toUInt32(data, offset);
if (epochSecond == 0xFFFFFFFF) { if (epochSecond == 0xFFFFFFFF) {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
return new DateTimeType(ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), context.getZoneId())); return new DateTimeType(Instant.ofEpochSecond(epochSecond));
}), }),
MILLIWATT_PER_SQUARE_METRE(MILLI(Units.WATT).divide(SQUARE_METRE), 2, CHANNEL_TYPE_UV_RADIATION, MILLIWATT_PER_SQUARE_METRE(MILLI(Units.WATT).divide(SQUARE_METRE), 2, CHANNEL_TYPE_UV_RADIATION,
(data, offset) -> Utils.toUInt16(data, offset) / 10.), (data, offset) -> Utils.toUInt16(data, offset) / 10.),
BYTE(1, null, (data, offset, context) -> new DecimalType(toUInt8(data[offset]))), BYTE(1, null, (data, offset) -> new DecimalType(toUInt8(data[offset]))),
MEMORY(Units.BYTE, 4, null, Utils::toUInt32), MEMORY(Units.BYTE, 4, null, Utils::toUInt32),
DATE_TIME2(6, null, (data, offset, context) -> new DateTimeType( DATE_TIME2(6, null, (data, offset) -> new DateTimeType(Instant.ofEpochSecond(toUInt32(data, offset))));
ZonedDateTime.ofInstant(Instant.ofEpochSecond(toUInt32(data, offset)), context.getZoneId())));
private final int byteSize; private final int byteSize;
private final @Nullable ChannelTypeUID channelTypeUID; private final @Nullable ChannelTypeUID channelTypeUID;
@ -139,7 +136,7 @@ public enum MeasureType {
*/ */
MeasureType(Unit<?> unit, int byteSize, @Nullable ChannelTypeUID channelTypeUID, MeasureType(Unit<?> unit, int byteSize, @Nullable ChannelTypeUID channelTypeUID,
BiFunction<byte[], Integer, @Nullable Number> valueExtractor) { BiFunction<byte[], Integer, @Nullable Number> valueExtractor) {
this(byteSize, channelTypeUID, (bytes, offset, context) -> { this(byteSize, channelTypeUID, (bytes, offset) -> {
Number value = valueExtractor.apply(bytes, offset); Number value = valueExtractor.apply(bytes, offset);
return value == null ? UnDefType.UNDEF : new QuantityType<>(value, unit); return value == null ? UnDefType.UNDEF : new QuantityType<>(value, unit);
}); });
@ -164,12 +161,12 @@ public enum MeasureType {
return channelTypeUID; return channelTypeUID;
} }
public @Nullable State toState(byte[] data, int offset, ConversionContext context) { public @Nullable State toState(byte[] data, int offset) {
return stateConverter.toState(data, offset, context); return stateConverter.toState(data, offset);
} }
private interface StateConverter { private interface StateConverter {
@Nullable @Nullable
State toState(byte[] data, int offset, ConversionContext context); State toState(byte[] data, int offset);
} }
} }

View File

@ -44,12 +44,12 @@ public enum Protocol {
} }
public GatewayQueryService getGatewayQueryService(FineOffsetGatewayConfiguration config, public GatewayQueryService getGatewayQueryService(FineOffsetGatewayConfiguration config,
@Nullable ThingStatusListener thingStatusListener, ConversionContext conversionContext) { @Nullable ThingStatusListener thingStatusListener) {
return queryServiceFactory.newInstance(config, thingStatusListener, conversionContext); return queryServiceFactory.newInstance(config, thingStatusListener);
} }
private interface GatewayQueryServiceFactory { private interface GatewayQueryServiceFactory {
GatewayQueryService newInstance(FineOffsetGatewayConfiguration config, GatewayQueryService newInstance(FineOffsetGatewayConfiguration config,
@Nullable ThingStatusListener thingStatusListener, ConversionContext conversionContext); @Nullable ThingStatusListener thingStatusListener);
} }
} }

View File

@ -32,14 +32,12 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration; import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration;
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetSensorConfiguration; import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetSensorConfiguration;
import org.openhab.binding.fineoffsetweatherstation.internal.discovery.FineOffsetGatewayDiscoveryService; import org.openhab.binding.fineoffsetweatherstation.internal.discovery.FineOffsetGatewayDiscoveryService;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding; import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SensorDevice; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SensorDevice;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SystemInfo; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.SystemInfo;
import org.openhab.binding.fineoffsetweatherstation.internal.service.GatewayQueryService; import org.openhab.binding.fineoffsetweatherstation.internal.service.GatewayQueryService;
import org.openhab.core.i18n.LocaleProvider; import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.i18n.TranslationProvider; import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel; import org.openhab.core.thing.Channel;
@ -76,7 +74,6 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
private final Logger logger = LoggerFactory.getLogger(FineOffsetGatewayHandler.class); private final Logger logger = LoggerFactory.getLogger(FineOffsetGatewayHandler.class);
private final Bundle bundle; private final Bundle bundle;
private final ConversionContext conversionContext;
private @Nullable GatewayQueryService gatewayQueryService; private @Nullable GatewayQueryService gatewayQueryService;
@ -94,7 +91,7 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
public FineOffsetGatewayHandler(Bridge bridge, FineOffsetGatewayDiscoveryService gatewayDiscoveryService, public FineOffsetGatewayHandler(Bridge bridge, FineOffsetGatewayDiscoveryService gatewayDiscoveryService,
ChannelTypeRegistry channelTypeRegistry, TranslationProvider translationProvider, ChannelTypeRegistry channelTypeRegistry, TranslationProvider translationProvider,
LocaleProvider localeProvider, TimeZoneProvider timeZoneProvider) { LocaleProvider localeProvider) {
super(bridge); super(bridge);
this.bridgeUID = bridge.getUID(); this.bridgeUID = bridge.getUID();
this.gatewayDiscoveryService = gatewayDiscoveryService; this.gatewayDiscoveryService = gatewayDiscoveryService;
@ -102,7 +99,6 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
this.translationProvider = translationProvider; this.translationProvider = translationProvider;
this.localeProvider = localeProvider; this.localeProvider = localeProvider;
this.bundle = FrameworkUtil.getBundle(FineOffsetGatewayDiscoveryService.class); this.bundle = FrameworkUtil.getBundle(FineOffsetGatewayDiscoveryService.class);
this.conversionContext = new ConversionContext(timeZoneProvider.getTimeZone());
} }
@Override @Override
@ -112,7 +108,7 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
@Override @Override
public void initialize() { public void initialize() {
FineOffsetGatewayConfiguration config = getConfigAs(FineOffsetGatewayConfiguration.class); FineOffsetGatewayConfiguration config = getConfigAs(FineOffsetGatewayConfiguration.class);
gatewayQueryService = config.protocol.getGatewayQueryService(config, this::updateStatus, conversionContext); gatewayQueryService = config.protocol.getGatewayQueryService(config, this::updateStatus);
updateStatus(ThingStatus.UNKNOWN); updateStatus(ThingStatus.UNKNOWN);
fetchAndUpdateSensors(); fetchAndUpdateSensors();

View File

@ -20,7 +20,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration; import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails; import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding; import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding;
@ -39,13 +38,10 @@ public class ELVGatewayQueryService extends GatewayQueryService {
private final FineOffsetDataParser fineOffsetDataParser; private final FineOffsetDataParser fineOffsetDataParser;
private final ConversionContext conversionContext;
public ELVGatewayQueryService(FineOffsetGatewayConfiguration config, public ELVGatewayQueryService(FineOffsetGatewayConfiguration config,
@Nullable ThingStatusListener thingStatusListener, ConversionContext conversionContext) { @Nullable ThingStatusListener thingStatusListener) {
super(config, thingStatusListener); super(config, thingStatusListener);
this.fineOffsetDataParser = new FineOffsetDataParser(Protocol.ELV); this.fineOffsetDataParser = new FineOffsetDataParser(Protocol.ELV);
this.conversionContext = conversionContext;
} }
@Override @Override
@ -81,8 +77,7 @@ public class ELVGatewayQueryService extends GatewayQueryService {
return Collections.emptyList(); return Collections.emptyList();
} }
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_WS980_LIVEDATA, Protocol.ELV); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_WS980_LIVEDATA, Protocol.ELV);
List<MeasuredValue> measuredValues = fineOffsetDataParser.getMeasuredValues(data, conversionContext, List<MeasuredValue> measuredValues = fineOffsetDataParser.getMeasuredValues(data, debugDetails);
debugDetails);
logger.trace("{}", debugDetails); logger.trace("{}", debugDetails);
return measuredValues; return measuredValues;
} }

View File

@ -26,7 +26,6 @@ import java.util.function.Supplier;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.fineoffsetweatherstation.internal.Utils; import org.openhab.binding.fineoffsetweatherstation.internal.Utils;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails; import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Measurand; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Measurand;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
@ -152,7 +151,7 @@ public class FineOffsetDataParser {
return new SystemInfo(frequency, date, dst, useWh24); return new SystemInfo(frequency, date, dst, useWh24);
} }
List<MeasuredValue> getMeasuredValues(byte[] data, ConversionContext context, DebugDetails debugDetails) { List<MeasuredValue> getMeasuredValues(byte[] data, DebugDetails debugDetails) {
/* /*
* Pos| Length | Description * Pos| Length | Description
* ------------------------------------------------- * -------------------------------------------------
@ -176,14 +175,14 @@ public class FineOffsetDataParser {
idx++; // at index 5 there is an additional Byte being set to 0x04 idx++; // at index 5 there is an additional Byte being set to 0x04
debugDetails.addDebugDetails(5, 1, "ELV extra byte"); debugDetails.addDebugDetails(5, 1, "ELV extra byte");
} }
return readMeasuredValues(data, idx, context, protocol.getParserCustomizationType(), debugDetails); return readMeasuredValues(data, idx, protocol.getParserCustomizationType(), debugDetails);
} }
List<MeasuredValue> getRainData(byte[] data, ConversionContext context, DebugDetails debugDetails) { List<MeasuredValue> getRainData(byte[] data, DebugDetails debugDetails) {
return readMeasuredValues(data, 5, context, Measurand.ParserCustomizationType.RAIN_READING, debugDetails); return readMeasuredValues(data, 5, Measurand.ParserCustomizationType.RAIN_READING, debugDetails);
} }
private List<MeasuredValue> readMeasuredValues(byte[] data, int idx, ConversionContext context, private List<MeasuredValue> readMeasuredValues(byte[] data, int idx,
Measurand.@Nullable ParserCustomizationType protocol, DebugDetails debugDetails) { Measurand.@Nullable ParserCustomizationType protocol, DebugDetails debugDetails) {
var size = toUInt16(data, 3); var size = toUInt16(data, 3);
@ -198,7 +197,7 @@ public class FineOffsetDataParser {
} else { } else {
debugDetails.addDebugDetails(idx - 1, 1, "measurand " + measurand.getDebugString()); debugDetails.addDebugDetails(idx - 1, 1, "measurand " + measurand.getDebugString());
} }
idx += measurand.extractMeasuredValues(data, idx, context, protocol, result, debugDetails); idx += measurand.extractMeasuredValues(data, idx, protocol, result, debugDetails);
} }
return result; return result;
} }

View File

@ -21,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration; import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails; import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding; import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding;
@ -44,13 +43,10 @@ public class FineOffsetGatewayQueryService extends GatewayQueryService {
private final FineOffsetDataParser fineOffsetDataParser; private final FineOffsetDataParser fineOffsetDataParser;
private final ConversionContext conversionContext;
public FineOffsetGatewayQueryService(FineOffsetGatewayConfiguration config, public FineOffsetGatewayQueryService(FineOffsetGatewayConfiguration config,
@Nullable ThingStatusListener thingStatusListener, ConversionContext conversionContext) { @Nullable ThingStatusListener thingStatusListener) {
super(config, thingStatusListener); super(config, thingStatusListener);
this.fineOffsetDataParser = new FineOffsetDataParser(PROTOCOL); this.fineOffsetDataParser = new FineOffsetDataParser(PROTOCOL);
this.conversionContext = conversionContext;
} }
@Override @Override
@ -95,8 +91,7 @@ public class FineOffsetGatewayQueryService extends GatewayQueryService {
byte[] data = executeCommand(Command.CMD_GW1000_LIVEDATA); byte[] data = executeCommand(Command.CMD_GW1000_LIVEDATA);
if (data != null) { if (data != null) {
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_GW1000_LIVEDATA, PROTOCOL); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_GW1000_LIVEDATA, PROTOCOL);
List<MeasuredValue> measuredValues = fineOffsetDataParser.getMeasuredValues(data, conversionContext, List<MeasuredValue> measuredValues = fineOffsetDataParser.getMeasuredValues(data, debugDetails);
debugDetails);
for (MeasuredValue measuredValue : measuredValues) { for (MeasuredValue measuredValue : measuredValues) {
valuePerChannel.put(measuredValue.getChannelId(), measuredValue); valuePerChannel.put(measuredValue.getChannelId(), measuredValue);
} }
@ -106,8 +101,7 @@ public class FineOffsetGatewayQueryService extends GatewayQueryService {
data = executeCommand(Command.CMD_READ_RAIN); data = executeCommand(Command.CMD_READ_RAIN);
if (data != null) { if (data != null) {
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, PROTOCOL); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, PROTOCOL);
List<MeasuredValue> measuredRainValues = fineOffsetDataParser.getRainData(data, conversionContext, List<MeasuredValue> measuredRainValues = fineOffsetDataParser.getRainData(data, debugDetails);
debugDetails);
for (MeasuredValue measuredValue : measuredRainValues) { for (MeasuredValue measuredValue : measuredRainValues) {
valuePerChannel.put(measuredValue.getChannelId(), measuredValue); valuePerChannel.put(measuredValue.getChannelId(), measuredValue);
} }

View File

@ -12,7 +12,6 @@
*/ */
package org.openhab.binding.fineoffsetweatherstation.internal.service; package org.openhab.binding.fineoffsetweatherstation.internal.service;
import java.time.ZoneOffset;
import java.util.List; import java.util.List;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
@ -20,7 +19,6 @@ import org.assertj.core.groups.Tuple;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails; import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol; import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue; import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
@ -37,8 +35,7 @@ class FineOffsetDataParserTest {
byte[] bytes = HexUtils.hexToBytes( byte[] bytes = HexUtils.hexToBytes(
"FFFF2700510100D306280827EF0927EF020045074F0A00150B00000C0000150000000016000117001900000E0000100000110021120000002113000005850D00007000D12E0060005A005B005502AE028F0633"); "FFFF2700510100D306280827EF0927EF020045074F0A00150B00000C0000150000000016000117001900000E0000100000110021120000002113000005850D00007000D12E0060005A005B005502AE028F0633");
DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(data) Assertions.assertThat(data)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("temperature-indoor", "21.1 °C"), new Tuple("humidity-indoor", "40 %"), .containsExactly(new Tuple("temperature-indoor", "21.1 °C"), new Tuple("humidity-indoor", "40 %"),
@ -63,8 +60,7 @@ class FineOffsetDataParserTest {
byte[] bytes = HexUtils.hexToBytes( byte[] bytes = HexUtils.hexToBytes(
"FFFF27007B0100D206240826CC0926CC02004907450A00760B00160C001F150001C00C16000017002A00144D00372C381A0085223E1B00A72333580059005A00620000000061FFFFFFFF60FF1900380E000010002D1100A012000000A013000000A00D009F63004D417000CF2C00250020001B0018020B021E06722164"); "FFFF27007B0100D206240826CC0926CC02004907450A00760B00160C001F150001C00C16000017002A00144D00372C381A0085223E1B00A72333580059005A00620000000061FFFFFFFF60FF1900380E000010002D1100A012000000A013000000A00D009F63004D417000CF2C00250020001B0018020B021E06722164");
DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(data) Assertions.assertThat(data)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("temperature-indoor", "21 °C"), new Tuple("humidity-indoor", "36 %"), .containsExactly(new Tuple("temperature-indoor", "21 °C"), new Tuple("humidity-indoor", "36 %"),
@ -99,8 +95,7 @@ class FineOffsetDataParserTest {
byte[] bytes = HexUtils.hexToBytes( byte[] bytes = HexUtils.hexToBytes(
"FFFF2700540100CA063E0826EC0926EC02007A074C0A002F0B001F0C0023150000032016000017001A0086225558005A00620000000661654A5AF1601B1900266300884B7000CE3F001D00240016001E041A037B0695"); "FFFF2700540100CA063E0826EC0926EC02007A074C0A002F0B001F0C0023150000032016000017001A0086225558005A00620000000661654A5AF1601B1900266300884B7000CE3F001D00240016001E041A037B0695");
DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(data) Assertions.assertThat(data)
.extracting(MeasuredValue::getChannelId, .extracting(MeasuredValue::getChannelId,
measuredValue -> measuredValue.getState() instanceof DateTimeType dateTimeState measuredValue -> measuredValue.getState() instanceof DateTimeType dateTimeState
@ -131,8 +126,7 @@ class FineOffsetDataParserTest {
byte[] bytes = HexUtils.hexToBytes( byte[] bytes = HexUtils.hexToBytes(
"FFFF27002F01010B062A0826C10926C1020011074D0A004C0B000C0C000D15000226C816006317011900136C0001FED864"); "FFFF27002F01010B062A0826C10926C1020011074D0A004C0B000C0C000D15000226C816006317011900136C0001FED864");
DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(data) Assertions.assertThat(data)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("temperature-indoor", "26.7 °C"), new Tuple("humidity-indoor", "42 %"), .containsExactly(new Tuple("temperature-indoor", "26.7 °C"), new Tuple("humidity-indoor", "42 %"),
@ -150,7 +144,7 @@ class FineOffsetDataParserTest {
"FFFF0B00500401010B0201120300620401120501120629072108254B09254B0A01480B00040C000A0E000000001000000021110000002E120000014F130000100714000012FD15000B4BB816086917056D35"); "FFFF0B00500401010B0201120300620401120501120629072108254B09254B0A01480B00040C000A0E000000001000000021110000002E120000014F130000100714000012FD15000B4BB816086917056D35");
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_WS980_LIVEDATA, Protocol.ELV); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_WS980_LIVEDATA, Protocol.ELV);
List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.ELV).getMeasuredValues(data, List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.ELV).getMeasuredValues(data,
new ConversionContext(ZoneOffset.UTC), debugDetails); debugDetails);
Assertions.assertThat(measuredValues) Assertions.assertThat(measuredValues)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("temperature-indoor", "26.7 °C"), .containsExactly(new Tuple("temperature-indoor", "26.7 °C"),
@ -171,8 +165,7 @@ class FineOffsetDataParserTest {
byte[] data = HexUtils byte[] data = HexUtils
.hexToBytes("FFFF5700290E000010000000001100000024120000003113000005030D00000F0064880000017A017B0030"); .hexToBytes("FFFF5700290E000010000000001100000024120000003113000005030D00000F0064880000017A017B0030");
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT);
List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data, List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(measuredValues) Assertions.assertThat(measuredValues)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("rain-rate", "0 mm/h"), new Tuple("rain-day", "0 mm"), .containsExactly(new Tuple("rain-rate", "0 mm/h"), new Tuple("rain-day", "0 mm"),
@ -187,8 +180,7 @@ class FineOffsetDataParserTest {
"FFFF5700398000008300000009840000000985000000C786000000C7810000870064006400640064006400640064006400640064880900007A02BF"); "FFFF5700398000008300000009840000000985000000C786000000C7810000870064006400640064006400640064006400640064880900007A02BF");
Assertions.assertThat(Command.CMD_READ_RAIN.isResponseValid(data)).isTrue(); Assertions.assertThat(Command.CMD_READ_RAIN.isResponseValid(data)).isTrue();
DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT); DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT);
List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data, List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data, debugDetails);
new ConversionContext(ZoneOffset.UTC), debugDetails);
Assertions.assertThat(measuredValues) Assertions.assertThat(measuredValues)
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString()) .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
.containsExactly(new Tuple("piezo-rain-rate", "0 mm/h"), new Tuple("piezo-rain-day", "0.9 mm"), .containsExactly(new Tuple("piezo-rain-rate", "0 mm/h"), new Tuple("piezo-rain-day", "0.9 mm"),