]> git.basschouten.com Git - openhab-addons.git/blob
788471f5d8b7b1d408334dd1798427def9a48384
[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.plex.internal.handler;
14
15 import static org.openhab.binding.plex.internal.PlexBindingConstants.*;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.openhab.binding.plex.internal.config.PlexPlayerConfiguration;
19 import org.openhab.binding.plex.internal.dto.MediaContainer.MediaType;
20 import org.openhab.binding.plex.internal.dto.PlexPlayerState;
21 import org.openhab.binding.plex.internal.dto.PlexSession;
22 import org.openhab.core.library.types.PlayPauseType;
23 import org.openhab.core.library.types.StringType;
24 import org.openhab.core.thing.Bridge;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.thing.Thing;
27 import org.openhab.core.thing.ThingStatus;
28 import org.openhab.core.thing.ThingStatusDetail;
29 import org.openhab.core.thing.binding.BaseThingHandler;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.RefreshType;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * The {@link PlexBindingConstants} class defines common constants, which are
37  * used across the whole binding.
38  *
39  * @author Brian Homeyer - Initial contribution
40  * @author Aron Beurskens - Binding development
41  */
42 @NonNullByDefault
43 public class PlexPlayerHandler extends BaseThingHandler {
44     private @NonNullByDefault({}) String playerID;
45
46     private PlexSession currentSessionData;
47     private boolean foundInSession;
48
49     private final Logger logger = LoggerFactory.getLogger(PlexPlayerHandler.class);
50
51     public PlexPlayerHandler(Thing thing) {
52         super(thing);
53         currentSessionData = new PlexSession();
54     }
55
56     /**
57      * Initialize the player thing, check the bridge status and hang out waiting
58      * for the session data to get polled.
59      */
60     @Override
61     public void initialize() {
62         PlexPlayerConfiguration config = getConfigAs(PlexPlayerConfiguration.class);
63         foundInSession = false;
64         playerID = config.playerID;
65         logger.debug("Initializing PLEX player : {}", playerID);
66         updateStatus(ThingStatus.UNKNOWN);
67     }
68
69     /**
70      * Currently only the 'player' channel accepts commands, all others are read-only
71      */
72     @Override
73     public void handleCommand(ChannelUID channelUID, Command command) {
74         if (command instanceof RefreshType) {
75             logger.debug("REFRESH not implemented");
76             return;
77         }
78
79         Bridge bridge = getBridge();
80         PlexServerHandler bridgeHandler = bridge == null ? null : (PlexServerHandler) bridge.getHandler();
81
82         if (bridgeHandler == null) {
83             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_MISSING_ERROR, "No bridge associated");
84         } else {
85             switch (channelUID.getId()) {
86                 case CHANNEL_PLAYER_CONTROL:
87                     bridgeHandler.getPlexAPIConnector().controlPlayer(command, playerID);
88                     break;
89                 default:
90                     logger.debug("Channel {} not implemented/supported to control player {}", channelUID.getId(),
91                             this.thing.getUID());
92             }
93         }
94     }
95
96     /**
97      * This is really just to set these all back to false so when we refresh the data it's
98      * updated for Power On/Off. This is only called from the Server Bridge.
99      *
100      * @param foundInSession Will always be false, so this can probably be changed.
101      */
102     public void setFoundInSession(boolean foundInSession) {
103         this.foundInSession = foundInSession;
104     }
105
106     /**
107      * Returns the session key from the current player
108      *
109      * @return
110      */
111     public String getSessionKey() {
112         return currentSessionData.getSessionKey();
113     }
114
115     /**
116      * Called when this thing gets its configuration changed.
117      */
118     @Override
119     public void thingUpdated(Thing thing) {
120         dispose();
121         this.thing = thing;
122         initialize();
123     }
124
125     /**
126      * Refreshes all the data from the session XML call. This is called from the bridge
127      *
128      * @param sessionData The Video section of the XML(which is what pertains to the player)
129      */
130     public void refreshSessionData(MediaType sessionData) {
131         currentSessionData.setState(PlexPlayerState.of(sessionData.getPlayer().getState()));
132         currentSessionData.setDuration(sessionData.getMedia().getDuration());
133         currentSessionData.setMachineIdentifier(sessionData.getPlayer().getMachineIdentifier());
134         currentSessionData.setViewOffset(sessionData.getViewOffset());
135         currentSessionData.setTitle(sessionData.getTitle());
136         currentSessionData.setType(sessionData.getType());
137         currentSessionData.setThumb(sessionData.getThumb());
138         currentSessionData.setArt(sessionData.getArt());
139         currentSessionData.setLocal(sessionData.getPlayer().getLocal());
140         currentSessionData.setSessionKey(sessionData.getSessionKey());
141         currentSessionData.setUserId(sessionData.getUser().getId());
142         currentSessionData.setUserTitle(sessionData.getUser().getTitle());
143
144         foundInSession = true;
145         updateStatus(ThingStatus.ONLINE);
146     }
147
148     /**
149      * Update just the state, this status comes from the websocket.
150      *
151      * @param state - The state to update it to.
152      */
153     public synchronized void updateStateChannel(String state) {
154         currentSessionData.setState(PlexPlayerState.of(state));
155         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_STATE),
156                 new StringType(String.valueOf(foundInSession ? currentSessionData.getState() : "Stopped")));
157     }
158
159     /**
160      * Updates the channel states to match reality.
161      */
162     public synchronized void updateChannels() {
163         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_STATE),
164                 new StringType(String.valueOf(foundInSession ? currentSessionData.getState() : "Stopped")));
165         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_POWER),
166                 new StringType(String.valueOf(foundInSession ? "ON" : "OFF")));
167         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_TITLE),
168                 new StringType(String.valueOf(foundInSession ? currentSessionData.getTitle() : "")));
169         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_TYPE),
170                 new StringType(String.valueOf(foundInSession ? currentSessionData.getType() : "")));
171         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_ART),
172                 new StringType(String.valueOf(foundInSession ? currentSessionData.getArt() : "")));
173         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_THUMB),
174                 new StringType(String.valueOf(foundInSession ? currentSessionData.getThumb() : "")));
175         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_PROGRESS),
176                 new StringType(String.valueOf(foundInSession ? currentSessionData.getProgress() : "0")));
177         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_ENDTIME),
178                 new StringType(String.valueOf(foundInSession ? currentSessionData.getEndTime() : "")));
179         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_ENDTIME),
180                 new StringType(String.valueOf(foundInSession ? currentSessionData.getEndTime() : "")));
181         updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_USER),
182                 new StringType(String.valueOf(foundInSession ? currentSessionData.getUserTitle() : "")));
183
184         // Make sure player control is in sync with the play state
185         if (currentSessionData.getState() == PlexPlayerState.PLAYING) {
186             updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_CONTROL), PlayPauseType.PLAY);
187         }
188         if (currentSessionData.getState() == PlexPlayerState.PAUSED) {
189             updateState(new ChannelUID(getThing().getUID(), CHANNEL_PLAYER_CONTROL), PlayPauseType.PAUSE);
190         }
191     }
192 }