2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.nest.internal.wwn.dto;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.nest.internal.wwn.dto.WWNDataUtil.*;
18 import java.io.IOException;
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
22 import org.junit.jupiter.api.Test;
23 import org.openhab.core.library.unit.SIUnits;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Test cases for gson parsing of model classes
30 * @author David Bennett - Initial contribution
31 * @author Wouter Born - Increase test coverage
33 public class WWNGsonParsingTest {
35 private final Logger logger = LoggerFactory.getLogger(WWNGsonParsingTest.class);
37 private static void assertEqualDateTime(String expected, Date actual) {
38 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
39 assertEquals(expected, sdf.format(actual));
43 public void verifyCompleteInput() throws IOException {
44 WWNTopLevelData topLevel = fromJson("top-level-data.json", WWNTopLevelData.class);
46 assertEquals(topLevel.getDevices().getThermostats().size(), 1);
47 assertNotNull(topLevel.getDevices().getThermostats().get(THERMOSTAT1_DEVICE_ID));
48 assertEquals(topLevel.getDevices().getCameras().size(), 2);
49 assertNotNull(topLevel.getDevices().getCameras().get(CAMERA1_DEVICE_ID));
50 assertNotNull(topLevel.getDevices().getCameras().get(CAMERA2_DEVICE_ID));
51 assertEquals(topLevel.getDevices().getSmokeCoAlarms().size(), 4);
52 assertNotNull(topLevel.getDevices().getSmokeCoAlarms().get(SMOKE1_DEVICE_ID));
53 assertNotNull(topLevel.getDevices().getSmokeCoAlarms().get(SMOKE2_DEVICE_ID));
54 assertNotNull(topLevel.getDevices().getSmokeCoAlarms().get(SMOKE3_DEVICE_ID));
55 assertNotNull(topLevel.getDevices().getSmokeCoAlarms().get(SMOKE4_DEVICE_ID));
59 public void verifyCompleteStreamingInput() throws IOException {
60 WWNTopLevelStreamingData topLevelStreamingData = fromJson("top-level-streaming-data.json",
61 WWNTopLevelStreamingData.class);
63 assertEquals("/", topLevelStreamingData.getPath());
65 WWNTopLevelData data = topLevelStreamingData.getData();
66 assertEquals(data.getDevices().getThermostats().size(), 1);
67 assertNotNull(data.getDevices().getThermostats().get(THERMOSTAT1_DEVICE_ID));
68 assertEquals(data.getDevices().getCameras().size(), 2);
69 assertNotNull(data.getDevices().getCameras().get(CAMERA1_DEVICE_ID));
70 assertNotNull(data.getDevices().getCameras().get(CAMERA2_DEVICE_ID));
71 assertEquals(data.getDevices().getSmokeCoAlarms().size(), 4);
72 assertNotNull(data.getDevices().getSmokeCoAlarms().get(SMOKE1_DEVICE_ID));
73 assertNotNull(data.getDevices().getSmokeCoAlarms().get(SMOKE2_DEVICE_ID));
74 assertNotNull(data.getDevices().getSmokeCoAlarms().get(SMOKE3_DEVICE_ID));
75 assertNotNull(data.getDevices().getSmokeCoAlarms().get(SMOKE4_DEVICE_ID));
79 public void verifyThermostat() throws IOException {
80 WWNThermostat thermostat = fromJson("thermostat-data.json", WWNThermostat.class);
81 logger.debug("Thermostat: {}", thermostat);
83 assertTrue(thermostat.isOnline());
84 assertTrue(thermostat.isCanHeat());
85 assertTrue(thermostat.isHasLeaf());
86 assertFalse(thermostat.isCanCool());
87 assertFalse(thermostat.isFanTimerActive());
88 assertFalse(thermostat.isLocked());
89 assertFalse(thermostat.isSunlightCorrectionActive());
90 assertTrue(thermostat.isSunlightCorrectionEnabled());
91 assertFalse(thermostat.isUsingEmergencyHeat());
92 assertEquals(THERMOSTAT1_DEVICE_ID, thermostat.getDeviceId());
93 assertEquals(Integer.valueOf(15), thermostat.getFanTimerDuration());
94 assertEqualDateTime("2017-02-02T21:00:06.000Z", thermostat.getLastConnection());
95 assertEqualDateTime("1970-01-01T00:00:00.000Z", thermostat.getFanTimerTimeout());
96 assertEquals(Double.valueOf(24.0), thermostat.getEcoTemperatureHigh());
97 assertEquals(Double.valueOf(12.5), thermostat.getEcoTemperatureLow());
98 assertEquals(Double.valueOf(22.0), thermostat.getLockedTempMax());
99 assertEquals(Double.valueOf(20.0), thermostat.getLockedTempMin());
100 assertEquals(WWNThermostat.Mode.HEAT, thermostat.getMode());
101 assertEquals("Living Room (Living Room)", thermostat.getName());
102 assertEquals("Living Room Thermostat (Living Room)", thermostat.getNameLong());
103 assertEquals(null, thermostat.getPreviousHvacMode());
104 assertEquals("5.6-7", thermostat.getSoftwareVersion());
105 assertEquals(WWNThermostat.State.OFF, thermostat.getHvacState());
106 assertEquals(STRUCTURE1_STRUCTURE_ID, thermostat.getStructureId());
107 assertEquals(Double.valueOf(15.5), thermostat.getTargetTemperature());
108 assertEquals(Double.valueOf(24.0), thermostat.getTargetTemperatureHigh());
109 assertEquals(Double.valueOf(20.0), thermostat.getTargetTemperatureLow());
110 assertEquals(SIUnits.CELSIUS, thermostat.getTemperatureUnit());
111 assertEquals(Integer.valueOf(0), thermostat.getTimeToTarget());
112 assertEquals(THERMOSTAT1_WHERE_ID, thermostat.getWhereId());
113 assertEquals("Living Room", thermostat.getWhereName());
117 public void thermostatTimeToTargetSupportedValueParsing() {
118 assertEquals((Integer) 0, WWNThermostat.parseTimeToTarget("~0"));
119 assertEquals((Integer) 5, WWNThermostat.parseTimeToTarget("<5"));
120 assertEquals((Integer) 10, WWNThermostat.parseTimeToTarget("<10"));
121 assertEquals((Integer) 15, WWNThermostat.parseTimeToTarget("~15"));
122 assertEquals((Integer) 90, WWNThermostat.parseTimeToTarget("~90"));
123 assertEquals((Integer) 120, WWNThermostat.parseTimeToTarget(">120"));
127 public void thermostatTimeToTargetUnsupportedValueParsing() {
128 assertThrows(NumberFormatException.class, () -> WWNThermostat.parseTimeToTarget("#5"));
132 public void verifyCamera() throws IOException {
133 WWNCamera camera = fromJson("camera-data.json", WWNCamera.class);
134 logger.debug("Camera: {}", camera);
136 assertTrue(camera.isOnline());
137 assertEquals("Upstairs", camera.getName());
138 assertEquals("Upstairs Camera", camera.getNameLong());
139 assertEquals(STRUCTURE1_STRUCTURE_ID, camera.getStructureId());
140 assertEquals(CAMERA1_WHERE_ID, camera.getWhereId());
141 assertTrue(camera.isAudioInputEnabled());
142 assertFalse(camera.isPublicShareEnabled());
143 assertFalse(camera.isStreaming());
144 assertFalse(camera.isVideoHistoryEnabled());
145 assertEquals("https://camera_app_url", camera.getAppUrl());
146 assertEquals(CAMERA1_DEVICE_ID, camera.getDeviceId());
147 assertNull(camera.getLastConnection());
148 assertEqualDateTime("2017-01-22T08:19:20.000Z", camera.getLastIsOnlineChange());
149 assertNull(camera.getPublicShareUrl());
150 assertEquals("https://camera_snapshot_url", camera.getSnapshotUrl());
151 assertEquals("205-600052", camera.getSoftwareVersion());
152 assertEquals("https://camera_web_url", camera.getWebUrl());
153 assertEquals("https://last_event_animated_image_url", camera.getLastEvent().getAnimatedImageUrl());
154 assertEquals(2, camera.getLastEvent().getActivityZones().size());
155 assertEquals("id1", camera.getLastEvent().getActivityZones().get(0));
156 assertEquals("https://last_event_app_url", camera.getLastEvent().getAppUrl());
157 assertEqualDateTime("2017-01-22T07:40:38.680Z", camera.getLastEvent().getEndTime());
158 assertEquals("https://last_event_image_url", camera.getLastEvent().getImageUrl());
159 assertEqualDateTime("2017-01-22T07:40:19.020Z", camera.getLastEvent().getStartTime());
160 assertEqualDateTime("2017-02-05T07:40:19.020Z", camera.getLastEvent().getUrlsExpireTime());
161 assertEquals("https://last_event_web_url", camera.getLastEvent().getWebUrl());
162 assertTrue(camera.getLastEvent().isHasMotion());
163 assertFalse(camera.getLastEvent().isHasPerson());
164 assertFalse(camera.getLastEvent().isHasSound());
168 public void verifySmokeDetector() throws IOException {
169 WWNSmokeDetector smokeDetector = fromJson("smoke-detector-data.json", WWNSmokeDetector.class);
170 logger.debug("SmokeDetector: {}", smokeDetector);
172 assertTrue(smokeDetector.isOnline());
173 assertEquals(SMOKE1_WHERE_ID, smokeDetector.getWhereId());
174 assertEquals(SMOKE1_DEVICE_ID, smokeDetector.getDeviceId());
175 assertEquals("Downstairs", smokeDetector.getName());
176 assertEquals("Downstairs Nest Protect", smokeDetector.getNameLong());
177 assertEqualDateTime("2017-02-02T20:53:05.338Z", smokeDetector.getLastConnection());
178 assertEquals(WWNSmokeDetector.BatteryHealth.OK, smokeDetector.getBatteryHealth());
179 assertEquals(WWNSmokeDetector.AlarmState.OK, smokeDetector.getCoAlarmState());
180 assertEquals(WWNSmokeDetector.AlarmState.OK, smokeDetector.getSmokeAlarmState());
181 assertEquals("3.1rc9", smokeDetector.getSoftwareVersion());
182 assertEquals(STRUCTURE1_STRUCTURE_ID, smokeDetector.getStructureId());
183 assertEquals(WWNSmokeDetector.UiColorState.GREEN, smokeDetector.getUiColorState());
187 public void verifyAccessToken() throws IOException {
188 WWNAccessTokenData accessToken = fromJson("access-token-data.json", WWNAccessTokenData.class);
189 logger.debug("AccessTokenData: {}", accessToken);
191 assertEquals("access_token", accessToken.getAccessToken());
192 assertEquals(Long.valueOf(315360000L), accessToken.getExpiresIn());
196 public void verifyStructure() throws IOException {
197 WWNStructure structure = fromJson("structure-data.json", WWNStructure.class);
198 logger.debug("Structure: {}", structure);
200 assertEquals("Home", structure.getName());
201 assertEquals("US", structure.getCountryCode());
202 assertEquals("98056", structure.getPostalCode());
203 assertEquals(WWNStructure.HomeAwayState.HOME, structure.getAway());
204 assertEqualDateTime("2017-02-02T03:10:08.000Z", structure.getEtaBegin());
205 assertNull(structure.getEta());
206 assertNull(structure.getPeakPeriodEndTime());
207 assertNull(structure.getPeakPeriodStartTime());
208 assertEquals(STRUCTURE1_STRUCTURE_ID, structure.getStructureId());
209 assertEquals("America/Los_Angeles", structure.getTimeZone());
210 assertFalse(structure.isRhrEnrollment());
214 public void verifyError() throws IOException {
215 WWNErrorData error = fromJson("error-data.json", WWNErrorData.class);
216 logger.debug("ErrorData: {}", error);
218 assertEquals("blocked", error.getError());
219 assertEquals("https://developer.nest.com/documentation/cloud/error-messages#blocked", error.getType());
220 assertEquals("blocked", error.getMessage());
221 assertEquals("bb514046-edc9-4bca-8239-f7a3cfb0925a", error.getInstance());