2 * Copyright (c) 2010-2024 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.robonect.internal.model;
15 import static org.junit.jupiter.api.Assertions.*;
17 import java.nio.charset.StandardCharsets;
19 import org.junit.jupiter.api.BeforeEach;
20 import org.junit.jupiter.api.Test;
23 * The goal of this class is to test the model parser to make sure the structures
24 * returned from the module can be handled.
26 * @author Marco Meyer - Initial contribution
28 public class ModelParserTest {
30 private ModelParser subject;
34 subject = new ModelParser();
38 public void shouldParseSimpleSuccessModel() {
39 String correctModel = "{\"successful\": true}";
40 RobonectAnswer answer = subject.parse(correctModel, RobonectAnswer.class);
41 assertTrue(answer.isSuccessful());
42 assertNull(answer.getErrorMessage());
43 assertNull(answer.getErrorCode());
47 public void shouldParseErrorResponseOnAllResponseTypes() {
48 String correctModel = "{\"successful\": false, \"error_code\": 7, \"error_message\": \"Automower already stopped\"}";
49 RobonectAnswer answer = subject.parse(correctModel, RobonectAnswer.class);
50 assertFalse(answer.isSuccessful());
51 assertEquals(Integer.valueOf(7), answer.getErrorCode());
52 assertEquals("Automower already stopped", answer.getErrorMessage());
54 MowerInfo info = subject.parse(correctModel, MowerInfo.class);
55 assertFalse(info.isSuccessful());
56 assertEquals(Integer.valueOf(7), info.getErrorCode());
57 assertEquals("Automower already stopped", info.getErrorMessage());
61 public void shouldParseCorrectStatusModel() {
62 String correctModel = "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 17, \"stopped\": false, \"duration\": 4359, \"mode\": 0, \"battery\": 100, \"hours\": 29}, \"timer\": {\"status\": 2, \"next\": {\"date\": \"01.05.2017\", \"time\": \"19:00:00\", \"unix\": 1493665200}}, \"wlan\": {\"signal\": -76}}";
63 MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
64 assertTrue(mowerInfo.isSuccessful());
65 assertEquals("Mein Automower", mowerInfo.getName());
66 assertEquals(MowerStatus.SLEEPING, mowerInfo.getStatus().getStatus());
67 assertFalse(mowerInfo.getStatus().isStopped());
68 assertEquals(4359, mowerInfo.getStatus().getDuration());
69 assertEquals(MowerMode.AUTO, mowerInfo.getStatus().getMode());
70 assertEquals(100, mowerInfo.getStatus().getBattery());
71 assertEquals(29, mowerInfo.getStatus().getHours());
72 assertEquals(Timer.TimerMode.STANDBY, mowerInfo.getTimer().getStatus());
73 assertEquals("01.05.2017", mowerInfo.getTimer().getNext().getDate());
74 assertEquals("19:00:00", mowerInfo.getTimer().getNext().getTime());
75 assertEquals("1493665200", mowerInfo.getTimer().getNext().getUnix());
76 assertEquals(-76, mowerInfo.getWlan().getSignal());
77 assertNull(mowerInfo.getError());
81 public void shouldParseCorrectStatusModelWithHealth() {
82 String correctModel = "{ \"successful\": true, \"name\": \"Rosenlund Automower\", \"status\": { \"status\": 4, \"stopped\": false, \"duration\": 47493, \"mode\": 0, \"battery\": 20, \"hours\": 991 }, \"timer\": { \"status\": 2, \"next\": { \"date\": \"30.07.2017\", \"time\": \"13:00:00\", \"unix\": 1501419600 } }, \"wlan\": { \"signal\": -66 }, \"health\": { \"temperature\": 28, \"humidity\": 32 } }";
83 MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
84 assertTrue(mowerInfo.isSuccessful());
85 assertEquals("Rosenlund Automower", mowerInfo.getName());
86 assertEquals(MowerStatus.CHARGING, mowerInfo.getStatus().getStatus());
87 assertFalse(mowerInfo.getStatus().isStopped());
88 assertEquals(47493, mowerInfo.getStatus().getDuration());
89 assertEquals(MowerMode.AUTO, mowerInfo.getStatus().getMode());
90 assertEquals(20, mowerInfo.getStatus().getBattery());
91 assertEquals(991, mowerInfo.getStatus().getHours());
92 assertEquals(Timer.TimerMode.STANDBY, mowerInfo.getTimer().getStatus());
93 assertEquals("30.07.2017", mowerInfo.getTimer().getNext().getDate());
94 assertEquals("13:00:00", mowerInfo.getTimer().getNext().getTime());
95 assertEquals("1501419600", mowerInfo.getTimer().getNext().getUnix());
96 assertEquals(-66, mowerInfo.getWlan().getSignal());
97 assertNull(mowerInfo.getError());
98 assertNotNull(mowerInfo.getHealth());
99 assertEquals(28, mowerInfo.getHealth().getTemperature());
100 assertEquals(32, mowerInfo.getHealth().getHumidity());
101 // "health": { "temperature": 28, "humidity": 32 }
105 public void shouldParseISOEncodedStatusModel() {
106 byte[] responseBytesISO88591 = "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 7, \"stopped\": true, \"duration\": 192, \"mode\": 1, \"battery\": 95, \"hours\": 41}, \"timer\": {\"status\": 2}, \"error\" : {\"error_code\": 15, \"error_message\": \"Utanför arbetsområdet\", \"date\": \"02.05.2017\", \"time\": \"20:36:43\", \"unix\": 1493757403}, \"wlan\": {\"signal\": -75}}"
107 .getBytes(StandardCharsets.ISO_8859_1);
108 MowerInfo mowerInfo = subject.parse(new String(responseBytesISO88591, StandardCharsets.ISO_8859_1),
110 assertEquals("Utanför arbetsområdet", mowerInfo.getError().getErrorMessage());
114 public void shouldParseCorrectStatusModelWithErrorCode() {
115 String correctModel = "{\"successful\": true, \"name\": \"Grasi\", \"status\": {\"status\": 7, \"stopped\": true, \"duration\": 423, \"mode\": 0, \"battery\": 83, \"hours\": 55}, \"timer\": {\"status\": 2, \"next\": {\"date\": \"15.05.2017\", \"time\": \"19:00:00\", \"unix\": 1494874800}}, \"wlan\": {\"signal\": -76}, \"error\": {\"error_code\": 9, \"error_message\": \"Grasi ist eingeklemmt\", \"date\": \"13.05.2017\", \"time\": \"23:00:22\", \"unix\": 1494716422}}";
116 MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
117 assertTrue(mowerInfo.isSuccessful());
118 assertEquals("Grasi", mowerInfo.getName());
119 assertEquals(MowerStatus.ERROR_STATUS, mowerInfo.getStatus().getStatus());
120 assertTrue(mowerInfo.getStatus().isStopped());
121 assertEquals(9, mowerInfo.getError().getErrorCode().intValue());
122 assertEquals("Grasi ist eingeklemmt", mowerInfo.getError().getErrorMessage());
126 public void shouldParseCorrectStatusModelMowing() {
127 String correctModel = "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 2, \"stopped\": false, \"duration\": 192, \"mode\": 1, \"battery\": 95, \"hours\": 41}, \"timer\": {\"status\": 2}, \"wlan\": {\"signal\": -75}}";
128 MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
129 assertTrue(mowerInfo.isSuccessful());
130 assertEquals("Mein Automower", mowerInfo.getName());
131 assertEquals(MowerStatus.MOWING, mowerInfo.getStatus().getStatus());
132 assertFalse(mowerInfo.getStatus().isStopped());
133 assertEquals(MowerMode.MANUAL, mowerInfo.getStatus().getMode());
137 public void shouldParseCorrectErrorModelInErrorState() {
138 String correctModel = "{\"successful\": true, \"name\": \"Mein Automower\", \"status\": {\"status\": 7, \"stopped\": true, \"duration\": 192, \"mode\": 1, \"battery\": 95, \"hours\": 41}, \"timer\": {\"status\": 2}, \"error\" : {\"error_code\": 15, \"error_message\": \"Mein Automower ist angehoben\", \"date\": \"02.05.2017\", \"time\": \"20:36:43\", \"unix\": 1493757403}, \"wlan\": {\"signal\": -75}}";
139 MowerInfo mowerInfo = subject.parse(correctModel, MowerInfo.class);
140 assertTrue(mowerInfo.isSuccessful());
141 assertEquals("Mein Automower", mowerInfo.getName());
142 assertEquals(MowerStatus.ERROR_STATUS, mowerInfo.getStatus().getStatus());
143 assertTrue(mowerInfo.getStatus().isStopped());
144 assertNotNull(mowerInfo.getError());
145 assertEquals("Mein Automower ist angehoben", mowerInfo.getError().getErrorMessage());
146 assertEquals(Integer.valueOf(15), mowerInfo.getError().getErrorCode());
147 assertEquals("02.05.2017", mowerInfo.getError().getDate());
148 assertEquals("20:36:43", mowerInfo.getError().getTime());
149 assertEquals("1493757403", mowerInfo.getError().getUnix());
153 public void shouldParseErrorsList() {
154 String errorsListResponse = "{\"errors\": [{\"error_code\": 15, \"error_message\": \"Grasi ist angehoben\", \"date\": \"02.05.2017\", \"time\": \"20:36:43\", \"unix\": 1493757403}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"26.04.2017\", \"time\": \"21:31:18\", \"unix\": 1493242278}, {\"error_code\": 13, \"error_message\": \"Kein Antrieb\", \"date\": \"21.04.2017\", \"time\": \"20:17:22\", \"unix\": 1492805842}, {\"error_code\": 10, \"error_message\": \"Grasi ist umgedreht\", \"date\": \"20.04.2017\", \"time\": \"20:14:37\", \"unix\": 1492719277}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"12.04.2017\", \"time\": \"19:10:09\", \"unix\": 1492024209}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"10.04.2017\", \"time\": \"22:59:35\", \"unix\": 1491865175}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"10.04.2017\", \"time\": \"21:21:55\", \"unix\": 1491859315}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"10.04.2017\", \"time\": \"20:26:13\", \"unix\": 1491855973}, {\"error_code\": 1, \"error_message\": \"Grasi hat Arbeitsbereich überschritten\", \"date\": \"09.04.2017\", \"time\": \"14:50:36\", \"unix\": 1491749436}, {\"error_code\": 33, \"error_message\": \"Grasi ist gekippt\", \"date\": \"09.04.2017\", \"time\": \"14:23:27\", \"unix\": 1491747807}], \"successful\": true}";
155 ErrorList errorList = subject.parse(errorsListResponse, ErrorList.class);
156 assertTrue(errorList.isSuccessful());
157 assertEquals(10, errorList.getErrors().size());
158 assertEquals(Integer.valueOf(15), errorList.getErrors().get(0).getErrorCode());
159 assertEquals("Grasi ist angehoben", errorList.getErrors().get(0).getErrorMessage());
160 assertEquals("02.05.2017", errorList.getErrors().get(0).getDate());
161 assertEquals("20:36:43", errorList.getErrors().get(0).getTime());
162 assertEquals("1493757403", errorList.getErrors().get(0).getUnix());
166 public void shouldParseName() {
167 String nameResponse = "{\"name\": \"Grasi\", \"successful\": true}";
168 Name name = subject.parse(nameResponse, Name.class);
169 assertTrue(name.isSuccessful());
170 assertEquals("Grasi", name.getName());
174 public void shouldParseVersionInfo() {
175 String versionResponse = "{\"robonect\": {\"serial\": \"05D92D32-38355048-43203030\", \"version\": \"V0.9\", \"compiled\": \"2017-03-25 20:10:00\", \"comment\": \"V0.9c\"}, \"successful\": true}";
176 VersionInfo versionInfo = subject.parse(versionResponse, VersionInfo.class);
177 assertTrue(versionInfo.isSuccessful());
178 assertEquals("05D92D32-38355048-43203030", versionInfo.getRobonect().getSerial());
179 assertEquals("V0.9", versionInfo.getRobonect().getVersion());
180 assertEquals("2017-03-25 20:10:00", versionInfo.getRobonect().getCompiled());
181 assertEquals("V0.9c", versionInfo.getRobonect().getComment());
185 public void shouldParseVersionInfoV1betaToNA() {
186 String versionResponse = """
191 production: "2017-02-07 15:12:00"
196 compiled: "2016-11-29 08:44:06"
202 serial: "05D80037-39355548-43163930",
205 compiled: "2016-10-22 01:12:00",
209 at-version: "V1.4.0",
210 sdk-version: "V2.1.0"
214 compiled: "2018-03-12 21:01:00",
215 comment: "Release V1.0 Beta2"
220 VersionInfo versionInfo = subject.parse(versionResponse, VersionInfo.class);
221 assertTrue(versionInfo.isSuccessful());
222 assertEquals("n/a", versionInfo.getRobonect().getSerial());
223 assertEquals("n/a", versionInfo.getRobonect().getVersion());
224 assertEquals("n/a", versionInfo.getRobonect().getCompiled());
225 assertEquals("n/a", versionInfo.getRobonect().getComment());