Skip to content

Commit 6477d08

Browse files
committed
[verisure] Fix NPE when API returns null gui field for climate devices
Fixes #20324 Add null-safety checks for Device.getGui() which can return null when Gson deserializes API responses where the gui field is absent. This caused a NullPointerException in updateClimateStatus, preventing all climate temperature updates. Signed-off-by: Jan Gustafsson <jannegpriv@gmail.com>
1 parent 9f03494 commit 6477d08

5 files changed

Lines changed: 22 additions & 9 deletions

File tree

bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.jsoup.nodes.Document;
5050
import org.jsoup.nodes.Element;
5151
import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO;
52+
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Gui;
5253
import org.openhab.binding.verisure.internal.dto.VerisureBatteryStatusDTO;
5354
import org.openhab.binding.verisure.internal.dto.VerisureBroadbandConnectionsDTO;
5455
import org.openhab.binding.verisure.internal.dto.VerisureClimatesDTO;
@@ -912,7 +913,8 @@ private synchronized void updateClimateStatus(VerisureInstallation installation)
912913
if (climateList != null) {
913914
climateList.forEach(climate -> {
914915
// If thing is Mouse detection device, then skip it, but fetch temperature from it
915-
String type = climate.getDevice().getGui().getLabel();
916+
Gui gui = climate.getDevice().getGui();
917+
String type = gui != null ? gui.getLabel() : null;
916918
if ("MOUSE".equals(type)) {
917919
logger.debug("Mouse detection device!");
918920
String deviceId = climate.getDevice().getDeviceLabel();

bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureBaseThingDTO.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ public static class Device {
411411

412412
private @Nullable String deviceLabel;
413413
private @Nullable String area;
414-
private Gui gui = new Gui();
414+
private @Nullable Gui gui = new Gui();
415415
@SerializedName("__typename")
416416
private @Nullable String typename;
417417

@@ -423,7 +423,7 @@ public static class Device {
423423
return area;
424424
}
425425

426-
public Gui getGui() {
426+
public @Nullable Gui getGui() {
427427
return gui;
428428
}
429429

@@ -439,7 +439,8 @@ public int hashCode() {
439439
result = prime * result + ((localArea == null) ? 0 : localArea.hashCode());
440440
String localDeviceLabel = deviceLabel;
441441
result = prime * result + ((localDeviceLabel == null) ? 0 : localDeviceLabel.hashCode());
442-
result = prime * result + gui.hashCode();
442+
Gui localGui = gui;
443+
result = prime * result + ((localGui == null) ? 0 : localGui.hashCode());
443444
String localTypeName = typename;
444445
result = prime * result + ((localTypeName == null) ? 0 : localTypeName.hashCode());
445446
return result;
@@ -473,7 +474,12 @@ public boolean equals(@Nullable Object obj) {
473474
} else if (!localDeviceLabel.equals(other.deviceLabel)) {
474475
return false;
475476
}
476-
if (!gui.equals(other.gui)) {
477+
Gui localGui = gui;
478+
if (localGui == null) {
479+
if (other.gui != null) {
480+
return false;
481+
}
482+
} else if (!localGui.equals(other.gui)) {
477483
return false;
478484
}
479485
String localTypeName = typename;

bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureClimatesDTO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public void setBatteryStatus(@Nullable VerisureBatteryStatusDTO batteryStatus) {
4141

4242
@Override
4343
public ThingTypeUID getThingTypeUID() {
44-
String type = getData().getInstallation().getClimates().get(0).getDevice().getGui().getLabel();
44+
Gui gui = getData().getInstallation().getClimates().get(0).getDevice().getGui();
45+
String type = gui != null ? gui.getLabel() : null;
4546
if ("SMOKE".equals(type)) {
4647
return THING_TYPE_SMOKEDETECTOR;
4748
} else if ("WATER".equals(type)) {

bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureEventLogThingHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.openhab.binding.verisure.internal.VerisureSession;
2828
import org.openhab.binding.verisure.internal.VerisureThingConfiguration;
2929
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Device;
30+
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Gui;
3031
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO;
3132
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO.EventLog;
3233
import org.openhab.binding.verisure.internal.dto.VerisureEventLogDTO.PagedList;
@@ -128,8 +129,9 @@ public State getValue(String channelId, VerisureEventLogDTO verisureEventLog, Ev
128129
triggerEventChannels(eventLog);
129130
}
130131
case CHANNEL_LAST_EVENT_DEVICE_TYPE:
131-
return device != null && device.getGui().getLabel() != null ? new StringType(device.getGui().getLabel())
132-
: UnDefType.NULL;
132+
Gui gui = device != null ? device.getGui() : null;
133+
String label = gui != null ? gui.getLabel() : null;
134+
return label != null ? new StringType(label) : UnDefType.NULL;
133135
case CHANNEL_LAST_EVENT_TYPE:
134136
String lastEventType = eventLog.getPagedList().get(0).getEventType();
135137
return lastEventType != null ? new StringType(lastEventType) : UnDefType.NULL;

bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureGatewayThingHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Set;
1919

2020
import org.eclipse.jdt.annotation.NonNullByDefault;
21+
import org.openhab.binding.verisure.internal.dto.VerisureBaseThingDTO.Gui;
2122
import org.openhab.binding.verisure.internal.dto.VerisureGatewayDTO;
2223
import org.openhab.binding.verisure.internal.dto.VerisureGatewayDTO.CommunicationState;
2324
import org.openhab.core.library.types.StringType;
@@ -89,7 +90,8 @@ public State getValue(String channelId, VerisureGatewayDTO verisureGateway, Comm
8990
String state = communicationState.getResult();
9091
return state != null ? new StringType(state) : UnDefType.NULL;
9192
case CHANNEL_GATEWAY_MODEL:
92-
String model = communicationState.getDevice().getGui().getLabel();
93+
Gui gui = communicationState.getDevice().getGui();
94+
String model = gui != null ? gui.getLabel() : null;
9395
return model != null ? new StringType(model) : UnDefType.NULL;
9496
case CHANNEL_LOCATION:
9597
String location = communicationState.getDevice().getArea();

0 commit comments

Comments
 (0)