]> git.basschouten.com Git - openhab-addons.git/blob
df831459c34a350e579f5f7ec2d4006c23e7da4f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.mqtt.homeassistant.internal.component;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17
18 import java.util.Set;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.junit.jupiter.api.Test;
22 import org.openhab.binding.mqtt.generic.values.OnOffValue;
23 import org.openhab.binding.mqtt.generic.values.PercentageValue;
24 import org.openhab.binding.mqtt.generic.values.TextValue;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.library.types.PercentType;
27 import org.openhab.core.library.types.StringType;
28 import org.openhab.core.types.UnDefType;
29
30 /**
31  * Tests for {@link Vacuum}
32  *
33  * @author Anton Kharuzhy - Initial contribution
34  */
35 @NonNullByDefault
36 public class VacuumTests extends AbstractComponentTests {
37     public static final String CONFIG_TOPIC = "vacuum/rockrobo_vacuum";
38
39     @SuppressWarnings("null")
40     @Test
41     public void testRoborockValetudo() {
42         // @formatter:off
43         var component = discoverComponent(configTopicToMqtt(CONFIG_TOPIC), "{" +
44                 "\"name\":\"Rockrobo\"," +
45                 "\"unique_id\":\"rockrobo_vacuum\"," +
46                 "\"schema\":\"state\"," +
47                 "\"device\":{" +
48                 "   \"manufacturer\":\"Roborock\"," +
49                 "   \"model\":\"v1\"," +
50                 "   \"name\":\"rockrobo\"," +
51                 "   \"identifiers\":[\"rockrobo\"]," +
52                 "   \"sw_version\":\"0.9.9\"" +
53                 "}," +
54                 "\"supported_features\":[\"start\",\"pause\",\"stop\",\"return_home\",\"battery\",\"status\"," +
55                 "   \"locate\",\"clean_spot\",\"fan_speed\",\"send_command\"]," +
56                 "\"command_topic\":\"valetudo/rockrobo/command\"," +
57                 "\"state_topic\":\"valetudo/rockrobo/state\"," +
58                 "\"set_fan_speed_topic\":\"valetudo/rockrobo/set_fan_speed\"," +
59                 "\"fan_speed_list\":[\"min\",\"medium\",\"high\",\"max\",\"mop\"]," +
60                 "\"send_command_topic\":\"valetudo/rockrobo/custom_command\"," +
61                 "\"json_attributes_topic\":\"valetudo/rockrobo/attributes\"" +
62                 "}");
63         // @formatter:on
64
65         assertThat(component.channels.size(), is(6)); // command, state, fan speed, send command, battery, json attrs
66         assertThat(component.getName(), is("Rockrobo"));
67         assertChannel(component, Vacuum.COMMAND_CH_ID, "", "valetudo/rockrobo/command", "Rockrobo", TextValue.class);
68         assertChannel(component, Vacuum.STATE_CH_ID, "valetudo/rockrobo/state", "", "Rockrobo", TextValue.class);
69         assertChannel(component, Vacuum.FAN_SPEED_CH_ID, "valetudo/rockrobo/state", "valetudo/rockrobo/set_fan_speed",
70                 "Rockrobo", TextValue.class);
71         assertChannel(component, Vacuum.CUSTOM_COMMAND_CH_ID, "", "valetudo/rockrobo/custom_command", "Rockrobo",
72                 TextValue.class);
73         assertChannel(component, Vacuum.BATTERY_LEVEL_CH_ID, "valetudo/rockrobo/state", "", "Rockrobo",
74                 PercentageValue.class);
75         assertChannel(component, Vacuum.JSON_ATTRIBUTES_CH_ID, "valetudo/rockrobo/attributes", "", "Rockrobo",
76                 TextValue.class);
77
78         assertState(component, Vacuum.STATE_CH_ID, UnDefType.UNDEF);
79         assertState(component, Vacuum.FAN_SPEED_CH_ID, UnDefType.UNDEF);
80         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, UnDefType.UNDEF);
81         assertState(component, Vacuum.JSON_ATTRIBUTES_CH_ID, UnDefType.UNDEF);
82
83         // @formatter:off
84         String jsonValue;
85         publishMessage("valetudo/rockrobo/attributes", jsonValue = "{" +
86                 "\"mainBrush\":\"245.1\"," +
87                 "\"sideBrush\":\"145.1\"," +
88                 "\"filter\":\"95.1\"," +
89                 "\"sensor\":\"0.0\"," +
90                 "\"currentCleanTime\":\"52.0\"," +
91                 "\"currentCleanArea\":\"46.7\"," +
92                 "\"cleanTime\":\"54.9\"," +
93                 "\"cleanArea\":\"3280.9\"," +
94                 "\"cleanCount\":84," +
95                 "\"last_run_stats\":{" +
96                 "   \"startTime\":1633257319000," +
97                 "   \"endTime\":1633260439000," +
98                 "   \"duration\":3120," +
99                 "   \"area\":\"46.7\"," +
100                 "   \"errorCode\":0," +
101                 "   \"errorDescription\":\"No error\"," +
102                 "   \"finishedFlag\":true" +
103                 "}," +
104                 "\"last_bin_out\":2147483647000," +
105                 "\"state\":\"docked\"," +
106                 "\"valetudo_state\":{" +
107                 "   \"id\":8," +
108                 "   \"name\":\"Charging\"" +
109                 "}," +
110                 "\"last_bin_full\":0" +
111                 "}");
112         // @formatter:on
113
114         // @formatter:off
115         publishMessage("valetudo/rockrobo/state", "{" +
116                 "\"state\":\"docked\"," +
117                 "\"battery_level\":100," +
118                 "\"fan_speed\":\"max\"" +
119                 "}");
120         // @formatter:on
121
122         assertState(component, Vacuum.STATE_CH_ID, new StringType(Vacuum.STATE_DOCKED));
123         assertState(component, Vacuum.FAN_SPEED_CH_ID, new StringType("max"));
124         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, new PercentType(100));
125         assertState(component, Vacuum.JSON_ATTRIBUTES_CH_ID, new StringType(jsonValue));
126
127         component.getChannel(Vacuum.COMMAND_CH_ID).getState().publishValue(new StringType("start"));
128         assertPublished("valetudo/rockrobo/command", "start");
129
130         // @formatter:off
131         publishMessage("valetudo/rockrobo/state", "{" +
132                 "\"state\":\"cleaning\"," +
133                 "\"battery_level\":99," +
134                 "\"fan_speed\":\"max\"" +
135                 "}");
136         // @formatter:on
137
138         assertState(component, Vacuum.STATE_CH_ID, new StringType(Vacuum.STATE_CLEANING));
139         assertState(component, Vacuum.FAN_SPEED_CH_ID, new StringType("max"));
140         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, new PercentType(99));
141         assertState(component, Vacuum.JSON_ATTRIBUTES_CH_ID, new StringType(jsonValue));
142
143         component.getChannel(Vacuum.FAN_SPEED_CH_ID).getState().publishValue(new StringType("medium"));
144         assertPublished("valetudo/rockrobo/set_fan_speed", "medium");
145
146         // @formatter:off
147         publishMessage("valetudo/rockrobo/state", "{" +
148                 "\"state\":\"returning\"," +
149                 "\"battery_level\":80," +
150                 "\"fan_speed\":\"medium\"" +
151                 "}");
152         // @formatter:on
153
154         assertState(component, Vacuum.STATE_CH_ID, new StringType(Vacuum.STATE_RETURNING));
155         assertState(component, Vacuum.FAN_SPEED_CH_ID, new StringType("medium"));
156         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, new PercentType(80));
157         assertState(component, Vacuum.JSON_ATTRIBUTES_CH_ID, new StringType(jsonValue));
158     }
159
160     @SuppressWarnings("null")
161     @Test
162     public void testLegacySchema() {
163         // @formatter:off
164         var component = discoverComponent(configTopicToMqtt(CONFIG_TOPIC), "{" +
165                 "\"name\":\"Rockrobo\"," +
166                 "\"unique_id\":\"rockrobo_vacuum\"," +
167                 "\"device\":{" +
168                 "   \"manufacturer\":\"Roborock\"," +
169                 "   \"model\":\"v1\"," +
170                 "   \"name\":\"rockrobo\"," +
171                 "   \"identifiers\":[\"rockrobo\"]," +
172                 "   \"sw_version\":\"0.9.9\"" +
173                 "}," +
174                 "\"supported_features\":[\"turn_on\", \"turn_off\",\"pause\",\"stop\",\"return_home\",\"battery\",\"status\"," +
175                 "   \"locate\",\"clean_spot\",\"fan_speed\",\"send_command\"]," +
176                 "\"command_topic\":\"vacuum/command\"," +
177                 "\"battery_level_topic\":\"vacuum/state\"," +
178                 "\"battery_level_template\":\"{{ value_json.battery_level }}\"," +
179                 "\"charging_topic\":\"vacuum/state\"," +
180                 "\"charging_template\":\"{{ value_json.charging }}\"," +
181                 "\"cleaning_topic\":\"vacuum/state\"," +
182                 "\"cleaning_template\":\"{{ value_json.cleaning }}\"," +
183                 "\"docked_topic\":\"vacuum/state\"," +
184                 "\"docked_template\":\"{{ value_json.docked }}\"," +
185                 "\"error_topic\":\"vacuum/state\"," +
186                 "\"error_template\":\"{{ value_json.error }}\"," +
187                 "\"fan_speed_topic\":\"vacuum/state\"," +
188                 "\"set_fan_speed_topic\":\"vacuum/set_fan_speed\"," +
189                 "\"fan_speed_template\":\"{{ value_json.fan_speed }}\"," +
190                 "\"fan_speed_list\":[\"min\",\"medium\",\"high\",\"max\"]," +
191                 "\"send_command_topic\":\"vacuum/send_command\"" +
192                 "}");
193         // @formatter:on
194
195         assertThat(component.channels.size(), is(8)); // command, battery, charging, cleaning, docked, error,
196         // fan speed, send command
197         assertThat(component.getName(), is("Rockrobo"));
198         assertChannel(component, Vacuum.COMMAND_CH_ID, "", "vacuum/command", "Rockrobo", TextValue.class);
199         assertChannel(component, Vacuum.BATTERY_LEVEL_CH_ID, "vacuum/state", "", "Rockrobo", PercentageValue.class);
200         assertChannel(component, Vacuum.CHARGING_CH_ID, "vacuum/state", "", "Rockrobo", OnOffValue.class);
201         assertChannel(component, Vacuum.CLEANING_CH_ID, "vacuum/state", "", "Rockrobo", OnOffValue.class);
202         assertChannel(component, Vacuum.DOCKED_CH_ID, "vacuum/state", "", "Rockrobo", OnOffValue.class);
203         assertChannel(component, Vacuum.ERROR_CH_ID, "vacuum/state", "", "Rockrobo", TextValue.class);
204         assertChannel(component, Vacuum.FAN_SPEED_CH_ID, "vacuum/state", "vacuum/set_fan_speed", "Rockrobo",
205                 TextValue.class);
206         assertChannel(component, Vacuum.CUSTOM_COMMAND_CH_ID, "", "vacuum/send_command", "Rockrobo", TextValue.class);
207
208         // @formatter:off
209         publishMessage("vacuum/state", "{" +
210                 "\"battery_level\": 61," +
211                 "\"docked\": true," +
212                 "\"cleaning\": false," +
213                 "\"charging\": true," +
214                 "\"fan_speed\": \"off\"," +
215                 "\"error\": \"Error message\"" +
216                 "}");
217         // @formatter:on
218
219         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, new PercentType(61));
220         assertState(component, Vacuum.DOCKED_CH_ID, OnOffType.ON);
221         assertState(component, Vacuum.CLEANING_CH_ID, OnOffType.OFF);
222         assertState(component, Vacuum.CHARGING_CH_ID, OnOffType.ON);
223         assertState(component, Vacuum.FAN_SPEED_CH_ID, new StringType("off"));
224         assertState(component, Vacuum.ERROR_CH_ID, new StringType("Error message"));
225
226         component.getChannel(Vacuum.COMMAND_CH_ID).getState().publishValue(new StringType("turn_on"));
227         assertPublished("vacuum/command", "turn_on");
228
229         // @formatter:off
230         publishMessage("vacuum/state", "{" +
231                 "\"battery_level\": 55," +
232                 "\"docked\": false," +
233                 "\"cleaning\": true," +
234                 "\"charging\": false," +
235                 "\"fan_speed\": \"medium\"," +
236                 "\"error\": \"\"" +
237                 "}");
238         // @formatter:on
239
240         assertState(component, Vacuum.BATTERY_LEVEL_CH_ID, new PercentType(55));
241         assertState(component, Vacuum.DOCKED_CH_ID, OnOffType.OFF);
242         assertState(component, Vacuum.CLEANING_CH_ID, OnOffType.ON);
243         assertState(component, Vacuum.CHARGING_CH_ID, OnOffType.OFF);
244         assertState(component, Vacuum.FAN_SPEED_CH_ID, new StringType("medium"));
245         assertState(component, Vacuum.ERROR_CH_ID, new StringType(""));
246
247         component.getChannel(Vacuum.FAN_SPEED_CH_ID).getState().publishValue(new StringType("high"));
248         assertPublished("vacuum/set_fan_speed", "high");
249
250         component.getChannel(Vacuum.CUSTOM_COMMAND_CH_ID).getState().publishValue(new StringType("custom_command"));
251         assertPublished("vacuum/send_command", "custom_command");
252     }
253
254     @Override
255     protected Set<String> getConfigTopics() {
256         return Set.of(CONFIG_TOPIC);
257     }
258 }