diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/handler/DaikinMadokaHandler.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/handler/DaikinMadokaHandler.java index 4afb58c6f71..83db79b607b 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/handler/DaikinMadokaHandler.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/handler/DaikinMadokaHandler.java @@ -24,7 +24,6 @@ import java.util.concurrent.TimeoutException; import javax.measure.quantity.Temperature; import javax.measure.quantity.Time; -import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bluetooth.BluetoothCharacteristic; @@ -84,7 +83,7 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re private final Logger logger = LoggerFactory.getLogger(DaikinMadokaHandler.class); - private @Nullable DaikinMadokaConfiguration config; + private DaikinMadokaConfiguration config = new DaikinMadokaConfiguration(); private @Nullable ExecutorService commandExecutor; @@ -109,10 +108,10 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re // Load Configuration config = getConfigAs(DaikinMadokaConfiguration.class); - DaikinMadokaConfiguration c = config; - logger.debug("[{}] Parameter value [refreshInterval]: {}", super.thing.getUID().getId(), c.refreshInterval); - logger.debug("[{}] Parameter value [commandTimeout]: {}", super.thing.getUID().getId(), c.commandTimeout); + logger.debug("[{}] Parameter value [refreshInterval]: {}", super.thing.getUID().getId(), + config.refreshInterval); + logger.debug("[{}] Parameter value [commandTimeout]: {}", super.thing.getUID().getId(), config.commandTimeout); if (getBridge() == null) { logger.debug("[{}] Bridge is null. Exiting.", super.thing.getUID().getId()); @@ -144,9 +143,9 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re } submitCommand(new GetEyeBrightnessCommand()); - }, new Random().nextInt(30), c.refreshInterval, TimeUnit.SECONDS); // We introduce a random start time, it - // avoids when having multiple devices to - // have the commands sent simultaneously. + }, new Random().nextInt(30), config.refreshInterval, TimeUnit.SECONDS); // We introduce a random start time, it + // avoids when having multiple devices to + // have the commands sent simultaneously. } private void retrieveOperationHours() throws InterruptedException { @@ -174,7 +173,6 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re .getCharacteristic(DaikinMadokaBindingConstants.CHAR_NOTIF_UUID); if (charNotif != null) { - @NonNull BluetoothCharacteristic c = charNotif; this.device.disableNotifications(c); } @@ -443,8 +441,8 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re } } - if (command.getState() == BRC1HCommand.State.SENT && this.config != null) { - if (!command.awaitStateChange(this.config.commandTimeout, TimeUnit.MILLISECONDS, + if (command.getState() == BRC1HCommand.State.SENT) { + if (!command.awaitStateChange(config.commandTimeout, TimeUnit.MILLISECONDS, BRC1HCommand.State.SUCCEEDED, BRC1HCommand.State.FAILED)) { logger.debug("[{}] Command {} to device {} timed out", super.thing.getUID().getId(), command, device.getAddress()); @@ -825,7 +823,7 @@ public class DaikinMadokaHandler extends ConnectedBluetoothHandler implements Re if (indicatorStatus != null) { this.madokaSettings.setCleanFilterIndicator(indicatorStatus); updateStateIfLinked(DaikinMadokaBindingConstants.CHANNEL_ID_CLEAN_FILTER_INDICATOR, - indicatorStatus == true ? OnOffType.ON : OnOffType.OFF); + OnOffType.from(indicatorStatus)); } } diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/DaikinMadokaConfiguration.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/DaikinMadokaConfiguration.java index 37e962989ac..141dccaa5bd 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/DaikinMadokaConfiguration.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/DaikinMadokaConfiguration.java @@ -12,14 +12,17 @@ */ package org.openhab.binding.bluetooth.daikinmadoka.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link DaikinMadokaConfiguration} class contains fields mapping thing configuration parameters. * * @author Benjamin Lafois - Initial contribution */ +@NonNullByDefault public class DaikinMadokaConfiguration { - public String address; - public Integer refreshInterval; - public Integer commandTimeout; + public String address = ""; + public int refreshInterval; + public int commandTimeout; } diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/DisableCleanFilterIndicatorCommand.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/DisableCleanFilterIndicatorCommand.java index f4536e733e3..42da102962f 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/DisableCleanFilterIndicatorCommand.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/DisableCleanFilterIndicatorCommand.java @@ -18,8 +18,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaMessage; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingException; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaValue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Command used to disable the Clean Filter Indicator notification @@ -30,8 +28,6 @@ import org.slf4j.LoggerFactory; @NonNullByDefault public class DisableCleanFilterIndicatorCommand extends BRC1HCommand { - private final Logger logger = LoggerFactory.getLogger(DisableCleanFilterIndicatorCommand.class); - @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetCleanFilterIndicatorCommand.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetCleanFilterIndicatorCommand.java index 393a0d85f32..66f70073716 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetCleanFilterIndicatorCommand.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetCleanFilterIndicatorCommand.java @@ -18,8 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaMessage; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaValue; /** * Command used to get the Clean Filter Indicator status @@ -30,15 +29,19 @@ import org.slf4j.LoggerFactory; @NonNullByDefault public class GetCleanFilterIndicatorCommand extends BRC1HCommand { - private final Logger logger = LoggerFactory.getLogger(GetCleanFilterIndicatorCommand.class); - private @Nullable Boolean cleanFilterIndicator; @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { + MadokaValue mValue = mm.getValues().get(0x62); + if (mValue == null) { + String message = "clean filter indicator is null when handling the response"; + setState(State.FAILED); + throw new MadokaParsingException(message); + } - byte[] valueCleanFilterIndicator = mm.getValues().get(0x62).getRawValue(); + byte[] valueCleanFilterIndicator = mValue.getRawValue(); if (valueCleanFilterIndicator == null || valueCleanFilterIndicator.length != 1) { setState(State.FAILED); throw new MadokaParsingException("Incorrect clean filter indicator value"); @@ -51,7 +54,12 @@ public class GetCleanFilterIndicatorCommand extends BRC1HCommand { } setState(State.SUCCEEDED); - executor.execute(() -> listener.receivedResponse(this)); + try { + executor.execute(() -> listener.receivedResponse(this)); + } catch (Exception e) { + setState(State.FAILED); + throw new MadokaParsingException(e); + } } public @Nullable Boolean getCleanFilterIndicator() { diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetEyeBrightnessCommand.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetEyeBrightnessCommand.java index a5f342f4682..1c8937824ab 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetEyeBrightnessCommand.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetEyeBrightnessCommand.java @@ -39,24 +39,32 @@ public class GetEyeBrightnessCommand extends BRC1HCommand { @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { - byte[] bEyeBrightness = mm.getValues().get(0x33).getRawValue(); + MadokaValue mValue = mm.getValues().get(0x33); + if (mValue == null) { + String message = "eye brightness is null when handling the response"; + setState(State.FAILED); + throw new MadokaParsingException(message); + } - if (bEyeBrightness == null || bEyeBrightness == null) { + byte[] bEyeBrightness = mValue.getRawValue(); + if (bEyeBrightness == null) { setState(State.FAILED); throw new MadokaParsingException("Incorrect eye brightness value"); } Integer iEyeBrightness = Integer.valueOf(bEyeBrightness[0]); - - if (iEyeBrightness != null) { - // The values accepted by the device are from 0 to 19 - integers so conversion needed for Dimmer channel - eyeBrightness = new PercentType((int) Math.round(iEyeBrightness / 0.19)); - } + // The values accepted by the device are from 0 to 19 - integers so conversion needed for Dimmer channel + eyeBrightness = new PercentType((int) Math.round(iEyeBrightness / 0.19)); logger.debug("Eye Brightness: {}", eyeBrightness); setState(State.SUCCEEDED); - executor.execute(() -> listener.receivedResponse(this)); + try { + executor.execute(() -> listener.receivedResponse(this)); + } catch (Exception e) { + setState(State.FAILED); + throw new MadokaParsingException(e); + } } @Override diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetFanspeedCommand.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetFanspeedCommand.java index e296049fea8..77ae2a88655 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetFanspeedCommand.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetFanspeedCommand.java @@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaMessage; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingException; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaProperties.FanSpeed; +import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,9 +45,16 @@ public class GetFanspeedCommand extends BRC1HCommand { @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { + MadokaValue coolValue = mm.getValues().get(0x20); + MadokaValue heatValue = mm.getValues().get(0x21); + if (heatValue == null || coolValue == null) { + String message = "heating or cooling fan speed is null when handling the response"; + setState(State.FAILED); + throw new MadokaParsingException(message); + } - byte[] valueCoolingFanSpeed = mm.getValues().get(0x20).getRawValue(); - byte[] valueHeatingFanSpeed = mm.getValues().get(0x21).getRawValue(); + byte[] valueCoolingFanSpeed = coolValue.getRawValue(); + byte[] valueHeatingFanSpeed = heatValue.getRawValue(); if (valueCoolingFanSpeed == null || valueHeatingFanSpeed == null) { setState(State.FAILED); @@ -60,7 +68,13 @@ public class GetFanspeedCommand extends BRC1HCommand { logger.debug("heatingFanSpeed: {}", heatingFanSpeed); setState(State.SUCCEEDED); - executor.execute(() -> listener.receivedResponse(this)); + + try { + executor.execute(() -> listener.receivedResponse(this)); + } catch (Exception e) { + setState(State.FAILED); + throw new MadokaParsingException(e); + } } @Override diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetIndoorOutoorTemperatures.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetIndoorOutoorTemperatures.java index 89f6c98f471..27c70eab2cb 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetIndoorOutoorTemperatures.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetIndoorOutoorTemperatures.java @@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaMessage; import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingException; +import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaValue; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.SIUnits; import org.slf4j.Logger; @@ -47,9 +48,16 @@ public class GetIndoorOutoorTemperatures extends BRC1HCommand { @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { - byte[] bIndoorTemperature = mm.getValues().get(0x40).getRawValue(); - byte[] bOutdoorTemperature = mm.getValues().get(0x41).getRawValue(); + MadokaValue indoorValue = mm.getValues().get(0x40); + MadokaValue outdoorValue = mm.getValues().get(0x41); + if (outdoorValue == null || indoorValue == null) { + String message = "indoor or outdoor value is null when handling the response"; + setState(State.FAILED); + throw new MadokaParsingException(message); + } + byte[] bIndoorTemperature = indoorValue.getRawValue(); + byte[] bOutdoorTemperature = outdoorValue.getRawValue(); if (bIndoorTemperature == null || bOutdoorTemperature == null) { setState(State.FAILED); throw new MadokaParsingException("Incorrect indoor or outdoor temperature"); @@ -66,9 +74,7 @@ public class GetIndoorOutoorTemperatures extends BRC1HCommand { } } - if (iIndoorTemperature != null) { - indoorTemperature = new QuantityType(iIndoorTemperature, SIUnits.CELSIUS); - } + indoorTemperature = new QuantityType(iIndoorTemperature, SIUnits.CELSIUS); if (iOutdoorTemperature != null) { outdoorTemperature = new QuantityType(iOutdoorTemperature, SIUnits.CELSIUS); @@ -78,7 +84,13 @@ public class GetIndoorOutoorTemperatures extends BRC1HCommand { logger.debug("Outdoor Temp: {}", outdoorTemperature); setState(State.SUCCEEDED); - executor.execute(() -> listener.receivedResponse(this)); + + try { + executor.execute(() -> listener.receivedResponse(this)); + } catch (Exception e) { + setState(State.FAILED); + throw new MadokaParsingException(e); + } } public @Nullable QuantityType getIndoorTemperature() { diff --git a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetOperationHoursCommand.java b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetOperationHoursCommand.java index 12c3420a8ee..bb54520095b 100644 --- a/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetOperationHoursCommand.java +++ b/bundles/org.openhab.binding.bluetooth.daikinmadoka/src/main/java/org/openhab/binding/bluetooth/daikinmadoka/internal/model/commands/GetOperationHoursCommand.java @@ -24,7 +24,6 @@ import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingEx import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaValue; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.Units; -import org.openhab.core.util.HexUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,33 +61,34 @@ public class GetOperationHoursCommand extends BRC1HCommand { @Override public void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm) throws MadokaParsingException { - try { - - byte[] msg = mm.getRawMessage(); - if (logger.isDebugEnabled() && msg != null) { - logger.debug("Got response for {} : {}", this.getClass().getSimpleName(), HexUtils.bytesToHex(msg)); - } - - // The specific GetOperationHours requires 2 consecutive runs for some reason. - // If value size is 0, then it will be for the next query! - if (mm.getValues().get(0x40).getSize() == 0) { - setState(State.SUCCEEDED); - return; - } - - Integer iIndoorOperationHours = (int) (mm.getValues().get(0x40).getComputedValue(ByteOrder.LITTLE_ENDIAN)); - Integer iIndoorFanHours = (int) (mm.getValues().get(0x41).getComputedValue(ByteOrder.LITTLE_ENDIAN)); - Integer iIndoorPowerHours = (int) (mm.getValues().get(0x42).getComputedValue(ByteOrder.LITTLE_ENDIAN)); - - this.indoorOperationHours = new QuantityType