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 3d9717c commit 0f652ac
Show file tree
Hide file tree
Showing 28 changed files with 2,261 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
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>
24 changes: 24 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,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>
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 0f652ac

Please sign in to comment.