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