]> git.basschouten.com Git - openhab-addons.git/blob
221783e907ccc002471e13b64ca3c8b25eb5a8ec
[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.heos.internal.api;
14
15 import static org.openhab.binding.heos.internal.resources.HeosConstants.*;
16
17 import java.io.IOException;
18 import java.net.URL;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.jetbrains.annotations.NotNull;
27 import org.openhab.binding.heos.internal.json.dto.HeosResponseObject;
28 import org.openhab.binding.heos.internal.json.payload.BrowseResult;
29 import org.openhab.binding.heos.internal.json.payload.Group;
30 import org.openhab.binding.heos.internal.json.payload.Media;
31 import org.openhab.binding.heos.internal.json.payload.Player;
32 import org.openhab.binding.heos.internal.resources.HeosCommands;
33 import org.openhab.binding.heos.internal.resources.HeosConstants;
34 import org.openhab.binding.heos.internal.resources.HeosEventListener;
35 import org.openhab.binding.heos.internal.resources.Telnet.ReadException;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import com.google.gson.JsonElement;
40
41 /**
42  * The {@link HeosFacade} is the interface for handling commands, which are
43  * sent to the HEOS system.
44  *
45  * @author Johannes Einig - Initial contribution
46  */
47 @NonNullByDefault
48 public class HeosFacade {
49     private static final int MAX_QUEUE_PAGES = 25;
50     private final Logger logger = LoggerFactory.getLogger(HeosFacade.class);
51
52     private final HeosSystem heosSystem;
53     private final HeosEventController eventController;
54
55     public HeosFacade(HeosSystem heosSystem, HeosEventController eventController) {
56         this.heosSystem = heosSystem;
57         this.eventController = eventController;
58     }
59
60     public synchronized List<BrowseResult> getFavorites() throws IOException, ReadException {
61         return getBrowseResults(FAVORITE_SID);
62     }
63
64     public List<BrowseResult> getInputs() throws IOException, ReadException {
65         return getBrowseResults(String.valueOf(INPUT_SID));
66     }
67
68     public List<BrowseResult> getPlaylists() throws IOException, ReadException {
69         return getBrowseResults(PLAYLISTS_SID);
70     }
71
72     @NotNull
73     private List<BrowseResult> getBrowseResults(String sourceIdentifier) throws IOException, ReadException {
74         HeosResponseObject<BrowseResult[]> response = browseSource(sourceIdentifier);
75         logger.debug("Response: {}", response);
76
77         if (response.payload == null) {
78             return Collections.emptyList();
79         }
80         logger.debug("Received results: {}", Arrays.asList(response.payload));
81
82         return Arrays.asList(response.payload);
83     }
84
85     public List<Media> getQueue(String pid) throws IOException, ReadException {
86         List<Media> media = new ArrayList<>();
87         for (int page = 0; page < MAX_QUEUE_PAGES; page++) {
88             HeosResponseObject<Media[]> response = fetchQueue(pid, page);
89             if (!response.result || response.payload == null) {
90                 break;
91             }
92
93             media.addAll(Arrays.asList(response.payload));
94
95             if (response.payload.length < 100) {
96                 break;
97             }
98
99             if (page == MAX_QUEUE_PAGES - 1) {
100                 logger.info("Currently only a maximum of {} pages is fetched for every queue", MAX_QUEUE_PAGES);
101             }
102         }
103
104         return media;
105     }
106
107     HeosResponseObject<Media[]> fetchQueue(String pid, int page) throws IOException, ReadException {
108         return heosSystem.send(HeosCommands.getQueue(pid, page * 100, (page + 1) * 100), Media[].class);
109     }
110
111     public HeosResponseObject<Player> getPlayerInfo(String pid) throws IOException, ReadException {
112         return heosSystem.send(HeosCommands.getPlayerInfo(pid), Player.class);
113     }
114
115     public HeosResponseObject<Group> getGroupInfo(String gid) throws IOException, ReadException {
116         return heosSystem.send(HeosCommands.getGroupInfo(gid), Group.class);
117     }
118
119     /**
120      * Pauses the HEOS player
121      *
122      * @param pid The PID of the dedicated player
123      */
124     public void pause(String pid) throws IOException, ReadException {
125         heosSystem.send(HeosCommands.setPlayStatePause(pid));
126     }
127
128     /**
129      * Starts the HEOS player
130      *
131      * @param pid The PID of the dedicated player
132      */
133     public void play(String pid) throws IOException, ReadException {
134         heosSystem.send(HeosCommands.setPlayStatePlay(pid));
135     }
136
137     /**
138      * Stops the HEOS player
139      *
140      * @param pid The PID of the dedicated player
141      */
142     public void stop(String pid) throws IOException, ReadException {
143         heosSystem.send(HeosCommands.setPlayStateStop(pid));
144     }
145
146     /**
147      * Jumps to the next song on the HEOS player
148      *
149      * @param pid The PID of the dedicated player
150      */
151     public void next(String pid) throws IOException, ReadException {
152         heosSystem.send(HeosCommands.playNext(pid));
153     }
154
155     /**
156      * Jumps to the previous song on the HEOS player
157      *
158      * @param pid The PID of the dedicated player
159      */
160     public void previous(String pid) throws IOException, ReadException {
161         heosSystem.send(HeosCommands.playPrevious(pid));
162     }
163
164     /**
165      * Toggles the mute state the HEOS player
166      *
167      * @param pid The PID of the dedicated player
168      */
169     public void mute(String pid) throws IOException, ReadException {
170         heosSystem.send(HeosCommands.setMuteToggle(pid));
171     }
172
173     /**
174      * Mutes the HEOS player
175      *
176      * @param pid The PID of the dedicated player
177      */
178     public void muteON(String pid) throws IOException, ReadException {
179         heosSystem.send(HeosCommands.setMuteOn(pid));
180     }
181
182     /**
183      * Un-mutes the HEOS player
184      *
185      * @param pid The PID of the dedicated player
186      */
187     public void muteOFF(String pid) throws IOException, ReadException {
188         heosSystem.send(HeosCommands.setMuteOff(pid));
189     }
190
191     /**
192      * Set the play mode of the player or group
193      *
194      * @param pid The PID of the dedicated player or group
195      * @param mode The shuffle mode: Allowed commands: on; off
196      */
197     public void setShuffleMode(String pid, String mode) throws IOException, ReadException {
198         heosSystem.send(HeosCommands.setShuffleMode(pid, mode));
199     }
200
201     /**
202      * Sets the repeat mode of the player or group
203      *
204      * @param pid The ID of the dedicated player or group
205      * @param mode The repeat mode. Allowed commands: on_all; on_one; off
206      */
207     public void setRepeatMode(String pid, String mode) throws IOException, ReadException {
208         heosSystem.send(HeosCommands.setRepeatMode(pid, mode));
209     }
210
211     /**
212      * Set the HEOS player to a dedicated volume
213      *
214      * @param vol The volume the player shall be set to (value between 0 -100)
215      * @param pid The ID of the dedicated player or group
216      */
217     public void setVolume(String vol, String pid) throws IOException, ReadException {
218         heosSystem.send(HeosCommands.setVolume(vol, pid));
219     }
220
221     /**
222      * Increases the HEOS player volume 1 Step
223      *
224      * @param pid The ID of the dedicated player or group
225      */
226     public void increaseVolume(String pid) throws IOException, ReadException {
227         heosSystem.send(HeosCommands.volumeUp(pid));
228     }
229
230     /**
231      * Decreases the HEOS player volume 1 Step
232      *
233      * @param pid The ID of the dedicated player or group
234      */
235     public void decreaseVolume(String pid) throws IOException, ReadException {
236         heosSystem.send(HeosCommands.volumeDown(pid));
237     }
238
239     /**
240      * Toggles mute state of the HEOS group
241      *
242      * @param gid The GID of the group
243      */
244     public void muteGroup(String gid) throws IOException, ReadException {
245         heosSystem.send(HeosCommands.setMuteToggle(gid));
246     }
247
248     /**
249      * Mutes the HEOS group
250      *
251      * @param gid The GID of the group
252      */
253     public void muteGroupON(String gid) throws IOException, ReadException {
254         heosSystem.send(HeosCommands.setGroupMuteOn(gid));
255     }
256
257     /**
258      * Un-mutes the HEOS group
259      *
260      * @param gid The GID of the group
261      */
262     public void muteGroupOFF(String gid) throws IOException, ReadException {
263         heosSystem.send(HeosCommands.setGroupMuteOff(gid));
264     }
265
266     /**
267      * Set the volume of the group to a specific level
268      *
269      * @param vol The volume the group shall be set to (value between 0-100)
270      * @param gid The GID of the group
271      */
272     public void volumeGroup(String vol, String gid) throws IOException, ReadException {
273         heosSystem.send(HeosCommands.setGroupVolume(vol, gid));
274     }
275
276     /**
277      * Increases the HEOS group volume 1 Step
278      *
279      * @param gid The ID of the dedicated player or group
280      */
281     public void increaseGroupVolume(String gid) throws IOException, ReadException {
282         heosSystem.send(HeosCommands.setGroupVolumeUp(gid));
283     }
284
285     /**
286      * Decreases the HEOS group volume 1 Step
287      *
288      * @param gid The ID of the dedicated player or group
289      */
290     public void decreaseGroupVolume(String gid) throws IOException, ReadException {
291         heosSystem.send(HeosCommands.setGroupVolumeDown(gid));
292     }
293
294     /**
295      * Un-Group the HEOS group to single player
296      *
297      * @param gid The GID of the group
298      */
299     public void ungroupGroup(String gid) throws IOException, ReadException {
300         String[] pid = new String[] { gid };
301         heosSystem.send(HeosCommands.setGroup(pid));
302     }
303
304     /**
305      * Builds a group from single players
306      *
307      * @param pids The single player IDs of the player which shall be grouped
308      * @return
309      */
310     public boolean groupPlayer(String[] pids) throws IOException, ReadException {
311         return heosSystem.send(HeosCommands.setGroup(pids)).result;
312     }
313
314     /**
315      * Browses through a HEOS source. Currently no response
316      *
317      * @param sid The source sid which shall be browsed
318      * @return
319      */
320     public HeosResponseObject<BrowseResult[]> browseSource(String sid) throws IOException, ReadException {
321         return heosSystem.send(HeosCommands.browseSource(sid), BrowseResult[].class);
322     }
323
324     /**
325      * Adds a media container to the queue and plays the media directly
326      * Information of the sid and cid has to be obtained via the browse function
327      *
328      * @param pid The player ID where the media object shall be played
329      * @param sid The source ID where the media is located
330      * @param cid The container ID of the media
331      */
332     public void addContainerToQueuePlayNow(String pid, String sid, String cid) throws IOException, ReadException {
333         heosSystem.send(HeosCommands.addContainerToQueuePlayNow(pid, sid, cid));
334     }
335
336     /**
337      * Reboot the bridge to which the connection is established
338      */
339     public void reboot() throws IOException, ReadException {
340         heosSystem.send(HeosCommands.rebootSystem());
341     }
342
343     /**
344      * Login in via the bridge to the HEOS account
345      *
346      * @param name The username
347      * @param password The password of the user
348      * @return
349      */
350     public HeosResponseObject<Void> logIn(String name, String password) throws IOException, ReadException {
351         return heosSystem.send(HeosCommands.signIn(name, password));
352     }
353
354     /**
355      * Get all the players known by HEOS
356      * 
357      * @return
358      */
359     public HeosResponseObject<Player[]> getPlayers() throws IOException, ReadException {
360         return heosSystem.send(HeosCommands.getPlayers(), Player[].class);
361     }
362
363     /**
364      * Get all the groups known by HEOS
365      * 
366      * @return
367      */
368     public HeosResponseObject<Group[]> getGroups() throws IOException, ReadException {
369         return heosSystem.send(HeosCommands.getGroups(), Group[].class);
370     }
371
372     /**
373      * Plays a specific station on the HEOS player
374      *
375      * @param pid The player ID
376      * @param sid The source ID where the media is located
377      * @param cid The container ID of the media
378      * @param mid The media ID of the media
379      * @param name Station name returned by 'browse' command.
380      */
381     public void playStream(@Nullable String pid, @Nullable String sid, @Nullable String cid, @Nullable String mid,
382             @Nullable String name) throws IOException, ReadException {
383         heosSystem.send(HeosCommands.playStream(pid, sid, cid, mid, name));
384     }
385
386     /**
387      * Plays a specific station on the HEOS player
388      *
389      * @param pid The player ID
390      * @param sid The source ID where the media is located
391      * @param mid The media ID of the media
392      */
393     public void playStream(String pid, String sid, String mid) throws IOException, ReadException {
394         heosSystem.send(HeosCommands.playStream(pid, sid, mid));
395     }
396
397     /**
398      * Plays a specified local input source on the player.
399      * Input name as per specified in HEOS CLI Protocol
400      *
401      * @param pid
402      * @param input
403      */
404     public void playInputSource(String pid, String input) throws IOException, ReadException {
405         heosSystem.send(HeosCommands.playInputSource(pid, pid, input));
406     }
407
408     /**
409      * Plays a specified input source from another player on the selected player.
410      * Input name as per specified in HEOS CLI Protocol
411      *
412      * @param destinationPid the PID where the source shall be played
413      * @param sourcePid the PID where the source is located.
414      * @param input the input name
415      */
416     public void playInputSource(String destinationPid, String sourcePid, String input)
417             throws IOException, ReadException {
418         heosSystem.send(HeosCommands.playInputSource(destinationPid, sourcePid, input));
419     }
420
421     /**
422      * Plays a file from a URL
423      *
424      * @param pid the PID where the file shall be played
425      * @param url the complete URL the file is located
426      */
427     public void playURL(String pid, URL url) throws IOException, ReadException {
428         heosSystem.send(HeosCommands.playURL(pid, url.toString()));
429     }
430
431     /**
432      * clear the queue
433      *
434      * @param pid The player ID the media is playing on
435      */
436     public void clearQueue(String pid) throws IOException, ReadException {
437         heosSystem.send(HeosCommands.clearQueue(pid));
438     }
439
440     /**
441      * Deletes a media from the queue
442      *
443      * @param pid The player ID the media is playing on
444      * @param qid The queue ID of the media. (starts by 1)
445      */
446     public void deleteMediaFromQueue(String pid, String qid) throws IOException, ReadException {
447         heosSystem.send(HeosCommands.deleteQueueItem(pid, qid));
448     }
449
450     /**
451      * Plays a specific media file from the queue
452      *
453      * @param pid The player ID the media shall be played on
454      * @param qid The queue ID of the media. (starts by 1)
455      */
456     public void playMediaFromQueue(String pid, String qid) throws IOException, ReadException {
457         heosSystem.send(HeosCommands.playQueueItem(pid, qid));
458     }
459
460     /**
461      * Asks for the actual state of the player. The result has
462      * to be handled by the event controller. The system returns {@link HeosConstants.PLAY},
463      * {@link HeosConstants.PAUSE} or {@link HeosConstants.STOP}.
464      *
465      * @param id The player ID the state shall get for
466      * @return
467      */
468     public HeosResponseObject<Void> getPlayState(String id) throws IOException, ReadException {
469         return heosSystem.send(HeosCommands.getPlayState(id));
470     }
471
472     /**
473      * Ask for the actual mute state of the player. The result has
474      * to be handled by the event controller. The HEOS system returns {@link HeosConstants.ON}
475      * or {@link HeosConstants.OFF}.
476      *
477      * @param id The player id the mute state shall get for
478      * @return
479      */
480     public HeosResponseObject<Void> getPlayerMuteState(String id) throws IOException, ReadException {
481         return heosSystem.send(HeosCommands.getMute(id));
482     }
483
484     /**
485      * Ask for the actual volume the player. The result has
486      * to be handled by the event controller. The HEOS system returns
487      * a value between 0 and 100
488      *
489      * @param id The player id the volume shall get for
490      * @return
491      */
492     public HeosResponseObject<Void> getPlayerVolume(String id) throws IOException, ReadException {
493         return heosSystem.send(HeosCommands.getVolume(id));
494     }
495
496     /**
497      * Ask for the actual shuffle mode of the player. The result has
498      * to be handled by the event controller. The HEOS system returns {@link HeosConstants.ON},
499      * {@link HeosConstants.HEOS_REPEAT_ALL} or {@link HeosConstants.HEOS_REPEAT_ONE}
500      *
501      * @param id The player id the shuffle mode shall get for
502      * @return
503      */
504     public HeosResponseObject<Void> getPlayMode(String id) throws IOException, ReadException {
505         return heosSystem.send(HeosCommands.getPlayMode(id));
506     }
507
508     public HeosResponseObject<Void> getGroupMuteState(String id) throws IOException, ReadException {
509         return heosSystem.send(HeosCommands.getGroupMute(id));
510     }
511
512     public HeosResponseObject<Void> getGroupVolume(String id) throws IOException, ReadException {
513         return heosSystem.send(HeosCommands.getGroupVolume(id));
514     }
515
516     public HeosResponseObject<Media> getNowPlayingMedia(String id) throws IOException, ReadException {
517         return heosSystem.send(HeosCommands.getNowPlayingMedia(id), Media.class);
518     }
519
520     /**
521      * Sends a RAW command to the HEOS bridge. The command has to be
522      * in accordance with the HEOS CLI specification
523      *
524      * @param command to send
525      * @return
526      */
527     public HeosResponseObject<JsonElement> sendRawCommand(String command) throws IOException, ReadException {
528         return heosSystem.send(command, JsonElement.class);
529     }
530
531     /**
532      * Register an {@link HeosEventListener} to get notification of system events
533      *
534      * @param listener The HeosEventListener
535      */
536     public void registerForChangeEvents(HeosEventListener listener) {
537         eventController.addListener(listener);
538     }
539
540     /**
541      * Unregister an {@link HeosEventListener} to get notification of system events
542      *
543      * @param listener The HeosEventListener
544      */
545     public void unregisterForChangeEvents(HeosEventListener listener) {
546         eventController.removeListener(listener);
547     }
548
549     public boolean isConnected() {
550         return heosSystem.isConnected();
551     }
552
553     public void closeConnection() {
554         heosSystem.closeConnection();
555     }
556 }