]> git.basschouten.com Git - openhab-addons.git/blob
e8d11ff000148d93e092e3fe09c3a6663cac9995
[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.volumio.internal.mapping;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.net.URL;
19 import java.net.URLConnection;
20 import java.util.Objects;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.json.JSONException;
25 import org.json.JSONObject;
26 import org.openhab.binding.volumio.internal.VolumioBindingConstants;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.PercentType;
29 import org.openhab.core.library.types.PlayPauseType;
30 import org.openhab.core.library.types.RawType;
31 import org.openhab.core.library.types.StringType;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * The {@link VolumioData} class defines state data of volumio.
37  *
38  * @author Patrick Sernetz - Initial Contribution
39  * @author Chris Wohlbrecht - Adaption for openHAB 3
40  * @author Michael Loercher - Adaption for openHAB 3
41  */
42 @NonNullByDefault
43 public class VolumioData {
44
45     private final Logger logger = LoggerFactory.getLogger(VolumioData.class);
46
47     private String title = "";
48     private boolean titleDirty;
49
50     private String album = "";
51     private boolean albumDirty;
52
53     private String artist = "";
54     private boolean artistDirty;
55
56     private int volume = 0;
57     private boolean volumeDirty;
58
59     private String state = "";
60     private boolean stateDirty;
61
62     private String trackType = "";
63     private boolean trackTypeDirty;
64
65     private String position = "";
66     private boolean positionDirty;
67
68     private byte @Nullable [] coverArt = null;
69     private String coverArtUrl = "";
70     private boolean coverArtDirty;
71
72     private boolean repeat = false;
73     private boolean repeatDirty;
74
75     private boolean random = false;
76     private boolean randomDirty;
77
78     public void update(JSONObject jsonObject) throws JSONException {
79         if (jsonObject.has(VolumioBindingConstants.CHANNEL_TITLE)) {
80             setTitle(jsonObject.getString(VolumioBindingConstants.CHANNEL_TITLE));
81         } else {
82             setTitle("");
83         }
84
85         if (jsonObject.has(VolumioBindingConstants.CHANNEL_ALBUM)
86                 && !jsonObject.isNull(VolumioBindingConstants.CHANNEL_ALBUM)) {
87             setAlbum(jsonObject.getString(VolumioBindingConstants.CHANNEL_ALBUM));
88         } else {
89             setAlbum("");
90         }
91
92         if (jsonObject.has(VolumioBindingConstants.CHANNEL_VOLUME)) {
93             setVolume(jsonObject.getInt(VolumioBindingConstants.CHANNEL_VOLUME));
94         } else {
95             setVolume(0);
96         }
97
98         if (jsonObject.has(VolumioBindingConstants.CHANNEL_ARTIST)) {
99             setArtist(jsonObject.getString(VolumioBindingConstants.CHANNEL_ARTIST));
100         } else {
101             setArtist("");
102         }
103
104         /* Special */
105         if (jsonObject.has("status")) {
106             setState(jsonObject.getString("status"));
107         } else {
108             setState("pause");
109         }
110
111         if (jsonObject.has(VolumioBindingConstants.CHANNEL_TRACK_TYPE)) {
112             setTrackType(jsonObject.getString(VolumioBindingConstants.CHANNEL_TRACK_TYPE));
113         } else {
114             setTrackType("");
115         }
116
117         if (jsonObject.has(VolumioBindingConstants.CHANNEL_COVER_ART)
118                 && !jsonObject.isNull(VolumioBindingConstants.CHANNEL_COVER_ART)) {
119             setCoverArt(jsonObject.getString(VolumioBindingConstants.CHANNEL_COVER_ART));
120         } else {
121             setCoverArt(null);
122         }
123
124         if (jsonObject.has(VolumioBindingConstants.CHANNEL_PLAY_RANDOM)
125                 && !jsonObject.isNull(VolumioBindingConstants.CHANNEL_PLAY_RANDOM)) {
126             setRandom(jsonObject.getBoolean(VolumioBindingConstants.CHANNEL_PLAY_RANDOM));
127         } else {
128             setRandom(false);
129         }
130
131         if (jsonObject.has(VolumioBindingConstants.CHANNEL_PLAY_REPEAT)
132                 && !jsonObject.isNull(VolumioBindingConstants.CHANNEL_PLAY_REPEAT)) {
133             setRepeat(jsonObject.getBoolean(VolumioBindingConstants.CHANNEL_PLAY_REPEAT));
134         } else {
135             setRepeat(false);
136         }
137     }
138
139     public StringType getTitle() {
140         return new StringType(title);
141     }
142
143     public void setTitle(String title) {
144         if (!title.equals(this.title)) {
145             this.title = title;
146             this.titleDirty = true;
147         } else {
148             this.titleDirty = false;
149         }
150     }
151
152     public StringType getAlbum() {
153         return new StringType(album);
154     }
155
156     public void setAlbum(String album) {
157         if ("null".equals(album)) {
158             album = "";
159         }
160
161         if (!album.equals(this.album)) {
162             this.album = album;
163             this.albumDirty = true;
164         } else {
165             this.albumDirty = false;
166         }
167     }
168
169     public StringType getArtist() {
170         return new StringType(artist);
171     }
172
173     public void setArtist(String artist) {
174         if ("null".equals(artist)) {
175             this.artist = "";
176         }
177
178         if (!artist.equals(this.artist)) {
179             this.artist = artist;
180             this.artistDirty = true;
181         } else {
182             this.artistDirty = false;
183         }
184     }
185
186     public PercentType getVolume() {
187         return new PercentType(volume);
188     }
189
190     public void setVolume(int volume) {
191         if (volume != this.volume) {
192             this.volume = volume;
193             this.volumeDirty = true;
194         } else {
195             this.volumeDirty = false;
196         }
197     }
198
199     public void setState(String state) {
200         if (!state.equals(this.state)) {
201             this.state = state;
202             this.stateDirty = true;
203         } else {
204             this.stateDirty = false;
205         }
206     }
207
208     public PlayPauseType getState() {
209         PlayPauseType playPauseStatus;
210
211         if ("play".equals(state)) {
212             playPauseStatus = PlayPauseType.PLAY;
213         } else {
214             playPauseStatus = PlayPauseType.PAUSE;
215         }
216
217         return playPauseStatus;
218     }
219
220     public void setTrackType(String trackType) {
221         if (!trackType.equals(this.trackType)) {
222             this.trackType = trackType;
223             this.trackTypeDirty = true;
224         } else {
225             this.trackTypeDirty = false;
226         }
227     }
228
229     public StringType getTrackType() {
230         return new StringType(trackType);
231     }
232
233     public void setPosition(String position) {
234         if (!position.equals(this.position)) {
235             this.position = position;
236             this.positionDirty = true;
237         } else {
238             this.positionDirty = false;
239         }
240     }
241
242     public void setCoverArt(@Nullable String coverArtUrl) {
243         if (coverArtUrl != null) {
244             if (!Objects.equals(coverArtUrl, this.coverArtUrl)) {
245                 if (!coverArtUrl.startsWith("http")) {
246                     return;
247                 }
248
249                 try {
250                     URL url = new URL(coverArtUrl);
251                     URLConnection connection = url.openConnection();
252                     InputStream inStream = null;
253                     inStream = connection.getInputStream();
254                     coverArt = inputStreamToByte(inStream);
255                 } catch (IOException ioe) {
256                     coverArt = null;
257                 }
258                 this.coverArtDirty = true;
259             } else {
260                 this.coverArtDirty = false;
261             }
262         } else {
263             coverArt = null;
264         }
265     }
266
267     private byte @Nullable [] inputStreamToByte(InputStream is) {
268         byte @Nullable [] imgdata = null;
269         try (ByteArrayOutputStream bytestream = new ByteArrayOutputStream()) {
270             int ch;
271             while ((ch = is.read()) != -1) {
272                 bytestream.write(ch);
273             }
274             imgdata = bytestream.toByteArray();
275             return imgdata;
276         } catch (Exception e) {
277             logger.error("Could not open or read input stream {}", e.getMessage());
278         }
279
280         return imgdata;
281     }
282
283     public @Nullable RawType getCoverArt() {
284         byte[] localCoverArt = coverArt;
285         return localCoverArt == null ? null : new RawType(localCoverArt, "image/jpeg");
286     }
287
288     public OnOffType getRandom() {
289         return OnOffType.from(random);
290     }
291
292     public void setRandom(boolean val) {
293         if (val != this.random) {
294             this.random = val;
295             this.randomDirty = true;
296         } else {
297             this.randomDirty = false;
298         }
299     }
300
301     public OnOffType getRepeat() {
302         return OnOffType.from(repeat);
303     }
304
305     public void setRepeat(boolean val) {
306         if (val != this.repeat) {
307             this.repeat = val;
308             this.repeatDirty = true;
309         } else {
310             this.repeatDirty = false;
311         }
312     }
313
314     public StringType getPosition() {
315         return new StringType(position);
316     }
317
318     public boolean isPositionDirty() {
319         return positionDirty;
320     }
321
322     public boolean isStateDirty() {
323         return stateDirty;
324     }
325
326     public boolean isTitleDirty() {
327         return titleDirty;
328     }
329
330     public boolean isAlbumDirty() {
331         return albumDirty;
332     }
333
334     public boolean isArtistDirty() {
335         return artistDirty;
336     }
337
338     public boolean isVolumeDirty() {
339         return volumeDirty;
340     }
341
342     public boolean isTrackTypeDirty() {
343         return trackTypeDirty;
344     }
345
346     public boolean isCoverArtDirty() {
347         return coverArtDirty;
348     }
349
350     public boolean isRandomDirty() {
351         return randomDirty;
352     }
353
354     public boolean isRepeatDirty() {
355         return repeatDirty;
356     }
357 }