Skip to content

Commit

Permalink
New binding - added plex binding for openhab 3
Browse files Browse the repository at this point in the history
Signed-off-by: Aron Beurskens <aron@netants.nl>
  • Loading branch information
Aron Beurskens committed Jan 28, 2022
1 parent 9717b7a commit 8d9a5e9
Show file tree
Hide file tree
Showing 28 changed files with 2,247 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
/bundles/org.openhab.binding.pjlinkdevice/ @nils
/bundles/org.openhab.binding.playstation/ @FluBBaOfWard
/bundles/org.openhab.binding.plclogo/ @falkena
/bundles/org.openhab.binding.plex/ @aronbeurskens
/bundles/org.openhab.binding.plugwise/ @wborn
/bundles/org.openhab.binding.plugwiseha/ @lsiepel
/bundles/org.openhab.binding.powermax/ @lolodomo
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,11 @@
<artifactId>org.openhab.binding.plclogo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.plex</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.plugwise</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.plex/NOTICE
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
76 changes: 76 additions & 0 deletions bundles/org.openhab.binding.plex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Plex Binding

_Give some details about what this binding is meant for - a protocol, system, specific device._

_If possible, provide some resources like pictures (only PNG is supported currently), a video, etc. to give an impression of what can be done with this binding._
_You can place such resources into a `doc` folder next to this README.md._

_Put each sentence in a separate line to improve readability of diffs._

## Supported Things

_Please describe the different supported things / devices including their ThingTypeUID within this section._
_Which different types are supported, which models were tested etc.?_
_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._

- `bridge`: Short description of the Bridge, if any
- `sample`: Short description of the Thing with the ThingTypeUID `sample`

## Discovery

_Describe the available auto-discovery features here._
_Mention for what it works and what needs to be kept in mind when using it._

## Binding Configuration

_If your binding requires or supports general configuration settings, please create a folder ```cfg``` and place the configuration file ```<bindingId>.cfg``` inside it._
_In this section, you should link to this file and provide some information about the options._
_The file could e.g. look like:_

```
# Configuration for the Plex Binding
#
# Default secret key for the pairing of the Plex Thing.
# It has to be between 10-40 (alphanumeric) characters.
# This may be changed by the user for security reasons.
secret=openHABSecret
```

_Note that it is planned to generate some part of this based on the information that is available within ```src/main/resources/OH-INF/binding``` of your binding._

_If your binding does not offer any generic configurations, you can remove this section completely._

## Thing Configuration

_Describe what is needed to manually configure a thing, either through the UI or via a thing-file._
_This should be mainly about its mandatory and optional configuration parameters._

_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._

### `sample` Thing Configuration

| Name | Type | Description | Default | Required | Advanced |
|-----------------|---------|---------------------------------------|---------|----------|----------|
| hostname | text | Hostname or IP address of the device | N/A | yes | no |
| password | text | Password to access the device | N/A | yes | no |
| refreshInterval | integer | Interval the device is polled in sec. | 600 | no | yes |

## 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._

| Channel | Type | Read/Write | Description |
|---------|--------|------------|-----------------------------|
| control | Switch | RW | This is the control channel |

## Full Example

_Provide a full usage example based on textual configuration files._
_*.things, *.items examples are mandatory as textual configuration is well used by many users._
_*.sitemap examples are optional._

## Any custom content here!

_Feel free to add additional sections for whatever you think should also be mentioned about your binding!_
17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.plex/pom.xml
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 https://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>
10 changes: 10 additions & 0 deletions bundles/org.openhab.binding.plex/src/main/feature/feature.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
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);
}
}
}
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());
}
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<>());
}
}
Loading

0 comments on commit 8d9a5e9

Please sign in to comment.