]> git.basschouten.com Git - openhab-addons.git/blob
8e4ca5a5057fced921af5300656c9e2f4018f93e
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.irobot.internal.dto;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import com.google.gson.JsonElement;
19 import com.google.gson.annotations.SerializedName;
20
21 /**
22  * iRobot MQTT protocol messages
23  *
24  * @author Pavel Fedin - Initial contribution
25  * @author Florian Binder - Added CleanRoomsRequest
26  *
27  */
28 public class MQTTProtocol {
29     public interface Request {
30         public String getTopic();
31     }
32
33     public static class CleanRoomsRequest extends CommandRequest {
34         public int ordered;
35         @SerializedName("pmap_id")
36         public String pmapId;
37         @SerializedName("user_pmapv_id")
38         public String userPmapvId;
39         public List<Region> regions;
40
41         public CleanRoomsRequest(String cmd, String mapId, String[] pregions, String[] types, String userPmapvId) {
42             super(cmd);
43             ordered = 1;
44             pmapId = mapId;
45             this.userPmapvId = userPmapvId;
46
47             regions = new ArrayList<Region>();
48             for (int i = 0; (i < pregions.length) && (i < types.length); i++) {
49                 regions.add(new Region(pregions[i], types[i]));
50             }
51         }
52
53         public static class Region {
54             @SerializedName("region_id")
55             public String regionId;
56             public String type;
57
58             public Region(String id, String type) {
59                 this.regionId = id;
60                 this.type = type;
61             }
62         }
63     }
64
65     public static class CommandRequest implements Request {
66         public String command;
67         public long time;
68         public String initiator;
69
70         public CommandRequest(String cmd) {
71             command = cmd;
72             time = System.currentTimeMillis() / 1000;
73             initiator = "openhab";
74         }
75
76         @Override
77         public String getTopic() {
78             return "cmd";
79         }
80     }
81
82     public static class DeltaRequest implements Request {
83         public StateValue state;
84
85         public DeltaRequest(StateValue state) {
86             this.state = state;
87         }
88
89         @Override
90         public String getTopic() {
91             return "delta";
92         }
93     }
94
95     public static class CleanMissionStatus {
96         public String cycle;
97         public String phase;
98         public String initiator;
99         public int error;
100     }
101
102     public static class BinStatus {
103         public boolean present;
104         public boolean full;
105     }
106
107     public static class SignalStrength {
108         public int rssi;
109         public int snr;
110     }
111
112     public static class Schedule {
113         public String[] cycle;
114         public int[] h;
115         public int[] m;
116
117         public static final int NUM_WEEK_DAYS = 7;
118
119         public Schedule(int cycles_bitmask) {
120             cycle = new String[NUM_WEEK_DAYS];
121             for (int i = 0; i < NUM_WEEK_DAYS; i++) {
122                 enableCycle(i, (cycles_bitmask & (1 << i)) != 0);
123             }
124         }
125
126         public Schedule(String[] cycle) {
127             this.cycle = cycle;
128         }
129
130         public boolean cycleEnabled(int i) {
131             return "start".equals(cycle[i]);
132         }
133
134         public void enableCycle(int i, boolean enable) {
135             cycle[i] = enable ? "start" : "none";
136         }
137     }
138
139     public static class StateValue {
140         // Just some common type, nothing to do here
141         protected StateValue() {
142         }
143     }
144
145     public static class OpenOnly extends StateValue {
146         public boolean openOnly;
147
148         public OpenOnly(boolean openOnly) {
149             this.openOnly = openOnly;
150         }
151     }
152
153     public static class BinPause extends StateValue {
154         public boolean binPause;
155
156         public BinPause(boolean binPause) {
157             this.binPause = binPause;
158         }
159     }
160
161     public static class PowerBoost extends StateValue {
162         public boolean carpetBoost;
163         public boolean vacHigh;
164
165         public PowerBoost(boolean carpetBoost, boolean vacHigh) {
166             this.carpetBoost = carpetBoost;
167             this.vacHigh = vacHigh;
168         }
169     }
170
171     public static class CleanPasses extends StateValue {
172         public boolean noAutoPasses;
173         public boolean twoPass;
174
175         public CleanPasses(boolean noAutoPasses, boolean twoPass) {
176             this.noAutoPasses = noAutoPasses;
177             this.twoPass = twoPass;
178         }
179     }
180
181     public static class CleanSchedule extends StateValue {
182         public Schedule cleanSchedule;
183
184         public CleanSchedule(Schedule schedule) {
185             cleanSchedule = schedule;
186         }
187     }
188
189     public static class MapUploadAllowed extends StateValue {
190         public boolean mapUploadAllowed;
191
192         public MapUploadAllowed(boolean mapUploadAllowed) {
193             this.mapUploadAllowed = mapUploadAllowed;
194         }
195     }
196
197     public static class SubModSwVer {
198         public String nav;
199         public String mob;
200         public String pwr;
201         public String sft;
202         public String mobBtl;
203         public String linux;
204         public String con;
205     }
206
207     // "reported" messages never contain the full state, only a part.
208     // Therefore all the fields in this class are nullable
209     public static class GenericState extends StateValue {
210         // "cleanMissionStatus":{"cycle":"clean","phase":"hmUsrDock","expireM":0,"rechrgM":0,"error":0,"notReady":0,"mssnM":1,"sqft":7,"initiator":"rmtApp","nMssn":39}
211         public CleanMissionStatus cleanMissionStatus;
212         // "batPct":100
213         public Integer batPct;
214         // "bin":{"present":true,"full":false}
215         public BinStatus bin;
216         // "signal":{"rssi":-55,"snr":33}
217         public SignalStrength signal;
218         // "cleanSchedule":{"cycle":["none","start","start","start","start","none","none"],"h":[9,12,12,12,12,12,9],"m":[0,0,0,0,0,0,0]}
219         public Schedule cleanSchedule;
220         // "openOnly":false
221         public Boolean openOnly;
222         // "binPause":true
223         public Boolean binPause;
224         // "carpetBoost":true
225         public Boolean carpetBoost;
226         // "vacHigh":false
227         public Boolean vacHigh;
228         // "noAutoPasses":true
229         public Boolean noAutoPasses;
230         // "twoPass":true
231         public Boolean twoPass;
232         // "mapUploadAllowed":true
233         public Boolean mapUploadAllowed;
234         // "softwareVer":"v2.4.6-3"
235         public String softwareVer;
236         // "navSwVer":"01.12.01#1"
237         public String navSwVer;
238         // "wifiSwVer":"20992"
239         public String wifiSwVer;
240         // "mobilityVer":"5806"
241         public String mobilityVer;
242         // "bootloaderVer":"4042"
243         public String bootloaderVer;
244         // "umiVer":"6",
245         public String umiVer;
246         // "sku":"R981040"
247         public String sku;
248         // "batteryType":"lith"
249         public String batteryType;
250         // Used by i7:
251         // "subModSwVer":{
252         // "nav": "lewis-nav+3.2.4-EPMF+build-HEAD-7834b608797+12", "mob":"3.2.4-XX+build-HEAD-7834b608797+12",
253         // "pwr": "0.5.0+build-HEAD-7834b608797+12",
254         // "sft":"1.1.0+Lewis-Builds/Lewis-Certified-Safety/lewis-safety-bbbe81f2c82+21",
255         // "mobBtl": "4.2", "linux":"linux+2.1.6_lock-1+lewis-release-rt419+12",
256         // "con":"2.1.6-tags/release-2.1.6@c6b6585a/build"}
257         public SubModSwVer subModSwVer;
258         // "lastCommand":
259         // {"command":"start","initiator":"localApp","time":1610283995,"ordered":1,"pmap_id":"AAABBBCCCSDDDEEEFFF","regions":[{"region_id":"6","type":"rid"}]}
260         public JsonElement lastCommand;
261     }
262
263     // Data comes as JSON string: {"state":{"reported":<Actual content here>}}
264     // or: {"state":{"desired":<Some content here>}}
265     // Of the second form i've so far observed only: {"state":{"desired":{"echo":null}}}
266     // I don't know what it is, so let's ignore it.
267     public static class ReportedState {
268         public GenericState reported;
269     }
270
271     public static class StateMessage {
272         public ReportedState state;
273     }
274
275     // DISCOVERY
276     public static class RobotCapabilities {
277         public Integer pose;
278         public Integer ota;
279         public Integer multiPass;
280         public Integer carpetBoost;
281         public Integer pp;
282         public Integer binFullDetect;
283         public Integer langOta;
284         public Integer maps;
285         public Integer edge;
286         public Integer eco;
287         public Integer scvConf;
288     }
289
290     /*
291      * JSON of the following contents (addresses are undisclosed):
292      * @formatter:off
293      * {
294      *   "ver":"3",
295      *   "hostname":"Roomba-<blid>",
296      *   "robotname":"Roomba",
297      *   "robotid":"<blid>", --> available on some models only
298      *   "ip":"XXX.XXX.XXX.XXX",
299      *   "mac":"XX:XX:XX:XX:XX:XX",
300      *   "sw":"v2.4.6-3",
301      *   "sku":"R981040",
302      *   "nc":0,
303      *   "proto":"mqtt",
304      *   "cap":{
305      *     "pose":1,
306      *     "ota":2,
307      *     "multiPass":2,
308      *     "carpetBoost":1,
309      *     "pp":1,
310      *     "binFullDetect":1,
311      *     "langOta":1,
312      *     "maps":1,
313      *     "edge":1,
314      *     "eco":1,
315      *     "svcConf":1
316      *   }
317      * }
318      * @formatter:on
319      */
320     public static class DiscoveryResponse {
321         public String ver;
322         public String hostname;
323         public String robotname;
324         public String robotid;
325         public String ip;
326         public String mac;
327         public String sw;
328         public String sku;
329         public String nc;
330         public String proto;
331         public RobotCapabilities cap;
332     }
333
334     // LoginRequester
335     public static class BlidResponse {
336         public String robotid;
337         public String hostname;
338     }
339 };