-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New binding - added plex binding for openhab 3
Signed-off-by: Aron Beurskens <[email protected]>
- Loading branch information
Aron Beurskens
committed
Jan 28, 2022
1 parent
3d9717c
commit 5052031
Showing
25 changed files
with
2,252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
This content is produced and maintained by the openHAB project. | ||
|
||
* Project home: https://www.openhab.org | ||
|
||
== Declared Project Licenses | ||
|
||
This program and the accompanying materials are made available under the terms | ||
of the Eclipse Public License 2.0 which is available at | ||
https://www.eclipse.org/legal/epl-2.0/. | ||
|
||
== Source Code | ||
|
||
https://github.com/openhab/openhab-addons |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Plex Binding | ||
|
||
This is an OH3 compatible PLEX binding. This takes a slightly different approach to the PLEX service than the original 1.x-2.x binding, though it serves a very similar purpose. | ||
|
||
## Supported Things | ||
|
||
This binding is a Bridge/Thing model for configuration. The Bridge is the actual connection to the PLEX server, the Things are the machineId's for the various players you might have. This can be somewhat confusing, but we'll get more into that shortly. | ||
|
||
The following thing types are supported: | ||
|
||
| Thing | ID | Discovery | Description | | ||
|----------|----------|-----------|-------------| | ||
| Server | server | Manual | Server bridge manages all communication with PLEX server | | ||
| Player | player | Manual | Monitor represents a machineID/Player on the PLEX server | | ||
|
||
## Discovery | ||
|
||
Discovery is not available, this is all 100% manual install. | ||
|
||
## Binding Configuration | ||
|
||
Binding configuration is done though the GUI. | ||
|
||
## Thing Configuration | ||
Bridge : | ||
Configuration is two sided here, you'll need to have your host IP and port, as well as either a Token or a valid username and password. | ||
|
||
What will happen if you have the username/password only is the binding will then get the token for you. Simple as that. | ||
|
||
Thing : | ||
This only accepts one parameter, machineID. | ||
You can configure the players manually or by scanning for players. | ||
|
||
Once the machineId is added as a thing, it will then be added when the bridge is parsing through objects that are doing something on the PLEX server. | ||
|
||
### Adding player manually | ||
Log on to https://plex.tv and navigate to https://plex.tv/devices.xml. | ||
Search for the `clientIdentifier` and add it as the `machineID` for the thing. | ||
|
||
### Adding player automatically | ||
First you have to set up the bridge and make sure its in online state. | ||
Then start playing something on the plex player you want to add. | ||
Navigate to Settings > Things > Add and choose the Plex Binding. | ||
Click the scan button and the player should be found. | ||
|
||
## Channels | ||
|
||
_Here you should provide information about available channel types, what their meaning is and how they can be used._ | ||
|
||
_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/OH-INF/thing``` of your binding._ | ||
|
||
Server : | ||
| channel | type | description | | ||
|----------|--------|------------------------------| | ||
| currentPlayers | String | Count of currently configured player | | ||
| currentPlayersActive | String | Count of configured players that are active | | ||
|
||
Player : | ||
| channel | type | description | | ||
|----------|--------|------------------------------| | ||
| state | String | Current state of the player object | | ||
| title | String | Title of the current playing media | | ||
| type | String | The type of media that is currently being played | | ||
| endtime | DateTime | The time when the current media will be finished playing | | ||
| progress | Dimmer | Progress of the currently media | | ||
| art | String | URL of the background art for the media being played | | ||
| thumb | String | URL of the cover art for the media being played | | ||
|
||
## Full Example | ||
|
||
All configuration done through PaperUI. | ||
|
||
## Any custom content here! | ||
Enjoy! Any feedback appreciated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.openhab.addons.bundles</groupId> | ||
<artifactId>org.openhab.addons.reactor.bundles</artifactId> | ||
<version>3.3.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>org.openhab.binding.plex</artifactId> | ||
|
||
<name>openHAB Add-ons :: Bundles :: Plex Binding</name> | ||
|
||
</project> |
24 changes: 24 additions & 0 deletions
24
bundles/org.openhab.binding.plex/src/main/feature/feature.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
Copyright (c) 2010-2022 Contributors to the openHAB project | ||
See the NOTICE file(s) distributed with this work for additional | ||
information. | ||
This program and the accompanying materials are made available under the | ||
terms of the Eclipse Public License 2.0 which is available at | ||
http://www.eclipse.org/legal/epl-2.0 | ||
SPDX-License-Identifier: EPL-2.0 | ||
--> | ||
<features name="org.openhab.binding.plex-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"> | ||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository> | ||
|
||
<feature name="openhab-binding-plex" description="Plex Binding" version="${project.version}"> | ||
<feature>openhab-runtime-base</feature> | ||
<feature dependency="true">openhab.tp-jaxb</feature> | ||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.plex/${project.version}</bundle> | ||
</feature> | ||
</features> |
55 changes: 55 additions & 0 deletions
55
...b.binding.plex/src/main/java/org/openhab/binding/plex/discovery/PlexDiscoveryService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.plex.discovery; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import org.openhab.binding.plex.internal.PlexBindingConstants; | ||
import org.openhab.binding.plex.internal.handler.PlexServerHandler; | ||
import org.openhab.core.config.discovery.AbstractDiscoveryService; | ||
import org.openhab.core.config.discovery.DiscoveryResult; | ||
import org.openhab.core.config.discovery.DiscoveryResultBuilder; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
import org.openhab.core.thing.ThingUID; | ||
|
||
/** | ||
* @author Brian Homeyer - Initial Configuration | ||
*/ | ||
public class PlexDiscoveryService extends AbstractDiscoveryService { | ||
private final PlexServerHandler bridgeHandler; | ||
|
||
public PlexDiscoveryService(PlexServerHandler bridgeHandler) { | ||
super(PlexBindingConstants.SUPPORTED_THING_TYPES_UIDS, 10, false); | ||
this.bridgeHandler = bridgeHandler; | ||
} | ||
|
||
@Override | ||
protected void startScan() { | ||
for (String machineId : bridgeHandler.getAvailablePlayers()) { | ||
ThingUID bridgeUID = bridgeHandler.getThing().getUID(); | ||
ThingTypeUID thingTypeUID = PlexBindingConstants.UID_PLAYER; | ||
ThingUID playerThingUid = new ThingUID(PlexBindingConstants.UID_PLAYER, bridgeUID, machineId); | ||
|
||
Map<String, Object> properties = new HashMap<>(); | ||
properties.put(PlexBindingConstants.CONFIG_PLAYER_ID, machineId); | ||
|
||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(playerThingUid).withThingType(thingTypeUID) | ||
.withProperties(properties).withBridge(bridgeUID) | ||
.withRepresentationProperty(PlexBindingConstants.CONFIG_PLAYER_ID) | ||
.withLabel("Plex Player Thing (" + machineId + ")").build(); | ||
|
||
thingDiscovered(discoveryResult); | ||
} | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
...ab.binding.plex/src/main/java/org/openhab/binding/plex/internal/PlexBindingConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.plex.internal; | ||
|
||
import java.util.Collections; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
|
||
/** | ||
* The {@link PlexBindingConstants} class defines common constants, which are | ||
* used across the whole binding. | ||
* | ||
* @author Brian Homeyer - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class PlexBindingConstants { | ||
|
||
private static final String BINDING_ID = "plex"; | ||
|
||
// Bridge thing | ||
public static final String THING_TYPE_SERVER = "server"; | ||
public static final ThingTypeUID UID_SERVER = new ThingTypeUID(BINDING_ID, THING_TYPE_SERVER); | ||
public static final Set<ThingTypeUID> SUPPORTED_SERVER_THING_TYPES_UIDS = Collections | ||
.unmodifiableSet(Stream.of(UID_SERVER).collect(Collectors.toSet())); | ||
|
||
// Monitor things | ||
public static final String THING_TYPE_PLAYER = "player"; | ||
public static final ThingTypeUID UID_PLAYER = new ThingTypeUID(BINDING_ID, THING_TYPE_PLAYER); | ||
|
||
// Collection of monitor thing types | ||
public static final Set<ThingTypeUID> SUPPORTED_PLAYER_THING_TYPES_UIDS = Collections | ||
.unmodifiableSet(Stream.of(UID_PLAYER).collect(Collectors.toSet())); | ||
|
||
// Collection of all supported thing types | ||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet( | ||
Stream.concat(SUPPORTED_PLAYER_THING_TYPES_UIDS.stream(), SUPPORTED_SERVER_THING_TYPES_UIDS.stream()) | ||
.collect(Collectors.toSet())); | ||
// General purpose stuff | ||
public static final String EMPTY = ""; | ||
public static final int DEFAULT_REFRESH_PERIOD_SEC = 5; | ||
// Config parameters | ||
// Server | ||
public static final String CONFIG_HOST = "host"; | ||
public static final String CONFIG_PORT_NUMBER = "portNumber"; | ||
public static final String CONFIG_TOKEN = "token"; | ||
public static final String CONFIG_REFRESH_RATE = "refreshRate"; | ||
// Player parameters | ||
public static final String CONFIG_PLAYER_ID = "playerID"; | ||
public static final String CONFIG_PLAYER_NAME = "playerName"; | ||
|
||
// List of all Channel ids | ||
// Server | ||
public static final String CHANNEL_SERVER_COUNT = "currentPlayers"; | ||
public static final String CHANNEL_SERVER_COUNTACTIVE = "currentPlayersActive"; | ||
// Player | ||
public static final String CHANNEL_PLAYER_STATE = "state"; | ||
public static final String CHANNEL_PLAYER_TITLE = "title"; | ||
public static final String CHANNEL_PLAYER_TYPE = "type"; | ||
public static final String CHANNEL_PLAYER_POWER = "power"; | ||
public static final String CHANNEL_PLAYER_ART = "art"; | ||
public static final String CHANNEL_PLAYER_THUMB = "thumb"; | ||
public static final String CHANNEL_PLAYER_PROGRESS = "progress"; | ||
public static final String CHANNEL_PLAYER_ENDTIME = "endtime"; | ||
|
||
public static final Set<String> SUPPORTED_CHANNEL_IDS = Stream.of(CHANNEL_SERVER_COUNT, CHANNEL_SERVER_COUNTACTIVE, | ||
CHANNEL_PLAYER_STATE, CHANNEL_PLAYER_TITLE, CHANNEL_PLAYER_TYPE, CHANNEL_PLAYER_POWER, CHANNEL_PLAYER_ART, | ||
CHANNEL_PLAYER_PROGRESS, CHANNEL_PLAYER_ENDTIME, CHANNEL_PLAYER_THUMB).collect(Collectors.toSet()); | ||
} |
86 changes: 86 additions & 0 deletions
86
...nhab.binding.plex/src/main/java/org/openhab/binding/plex/internal/PlexHandlerFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.plex.internal; | ||
|
||
import static org.openhab.binding.plex.internal.PlexBindingConstants.*; | ||
|
||
import java.util.Hashtable; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.openhab.binding.plex.discovery.PlexDiscoveryService; | ||
import org.openhab.binding.plex.internal.handler.PlexPlayerHandler; | ||
import org.openhab.binding.plex.internal.handler.PlexServerHandler; | ||
import org.openhab.core.config.discovery.DiscoveryService; | ||
import org.openhab.core.thing.Bridge; | ||
import org.openhab.core.thing.Thing; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
import org.openhab.core.thing.binding.BaseThingHandlerFactory; | ||
import org.openhab.core.thing.binding.ThingHandler; | ||
import org.openhab.core.thing.binding.ThingHandlerFactory; | ||
import org.osgi.framework.ServiceRegistration; | ||
import org.osgi.service.component.annotations.Activate; | ||
import org.osgi.service.component.annotations.Component; | ||
import org.osgi.service.component.annotations.Reference; | ||
|
||
/** | ||
* The {@link PlexHandlerFactory} is responsible for creating things and thing | ||
* handlers. | ||
* | ||
* @author Brian Homeyer - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
@Component(configurationPid = "binding.plex", service = ThingHandlerFactory.class) | ||
public class PlexHandlerFactory extends BaseThingHandlerFactory { | ||
private final PlexStateDescriptionOptionProvider stateDescriptionProvider; | ||
private @Nullable ServiceRegistration<?> plexDiscoveryServiceRegistration; | ||
|
||
@Activate | ||
public PlexHandlerFactory(final @Reference PlexStateDescriptionOptionProvider provider) { | ||
this.stateDescriptionProvider = provider; | ||
} | ||
|
||
@Override | ||
public boolean supportsThingType(ThingTypeUID thingTypeUID) { | ||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); | ||
} | ||
|
||
@Override | ||
protected @Nullable ThingHandler createHandler(Thing thing) { | ||
ThingTypeUID thingTypeUID = thing.getThingTypeUID(); | ||
if (SUPPORTED_SERVER_THING_TYPES_UIDS.contains(thingTypeUID)) { | ||
PlexServerHandler handler = new PlexServerHandler((Bridge) thing, stateDescriptionProvider); | ||
registerPlexDiscoveryService(handler); | ||
return handler; | ||
} else if (SUPPORTED_PLAYER_THING_TYPES_UIDS.contains(thingTypeUID)) { | ||
return new PlexPlayerHandler(thing); | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
protected synchronized void removeHandler(ThingHandler thingHandler) { | ||
if (thingHandler instanceof PlexServerHandler) { | ||
if (plexDiscoveryServiceRegistration != null) { | ||
// remove discovery service, if bridge handler is removed | ||
plexDiscoveryServiceRegistration.unregister(); | ||
} | ||
} | ||
} | ||
|
||
private void registerPlexDiscoveryService(PlexServerHandler handler) { | ||
PlexDiscoveryService discoveryService = new PlexDiscoveryService(handler); | ||
this.plexDiscoveryServiceRegistration = bundleContext.registerService(DiscoveryService.class.getName(), | ||
discoveryService, new Hashtable<>()); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
...x/src/main/java/org/openhab/binding/plex/internal/PlexStateDescriptionOptionProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) 2010-2022 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.plex.internal; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider; | ||
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService; | ||
import org.openhab.core.thing.type.DynamicStateDescriptionProvider; | ||
import org.osgi.service.component.annotations.Component; | ||
import org.osgi.service.component.annotations.Reference; | ||
|
||
/** | ||
* Dynamic provider of state options while leaving other state description fields as original. | ||
* | ||
* @author Brian Homeyer - Initial contribution | ||
*/ | ||
@Component(service = { DynamicStateDescriptionProvider.class, PlexStateDescriptionOptionProvider.class }) | ||
@NonNullByDefault | ||
public class PlexStateDescriptionOptionProvider extends BaseDynamicStateDescriptionProvider { | ||
@Reference | ||
protected void setChannelTypeI18nLocalizationService( | ||
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { | ||
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; | ||
} | ||
|
||
protected void unsetChannelTypeI18nLocalizationService( | ||
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { | ||
this.channelTypeI18nLocalizationService = null; | ||
} | ||
} |
Oops, something went wrong.