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