Skip to content

Commit

Permalink
[Kodi] Add channels for fanart and thumbnail (openhab#2304)
Browse files Browse the repository at this point in the history
* [Kodi] Add channels for fanart and thumbnail (openhab#2302)

Closes openhab#2302

Also-by: Christoph Weitkamp <[email protected]>
Signed-off-by: Andreas Reinhardt <[email protected]>
(gitlab: andreasreinhardt)
  • Loading branch information
andreasreinhardt authored and martinvw committed Nov 2, 2017
1 parent 24b805c commit f238e11
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,54 @@
xmlns:config-description="http://eclipse.org/smarthome/schemas/config-description/v1.0.0"
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/config-description/v1.0.0 http://eclipse.org/smarthome/schemas/config-description-1.0.0.xsd">

<config-description uri="thing-type:kodi:kodi">
<parameter-group name="network">
<label>Network</label>
<description>Network settings.</description>
</parameter-group>
<parameter-group name="connection">
<label>Connection</label>
<description>Connection settings.</description>
</parameter-group>
<parameter name="ipAddress" type="text" required="true" groupName="network">
<label>Network Address</label>
<description>The IP or host name of the Kodi</description>
<context>network-address</context>
</parameter>
<parameter name="port" type="integer" required="true" min="1" max="65335" groupName="network">
<label>Web socket service port</label>
<description>Port for the web socket service</description>
<default>9090</default>
</parameter>
<parameter name="httpPort" type="integer" required="true" min="1" max="65335" groupName="network">
<label>HTTP service port</label>
<description>Port for the HTTP service.</description>
<default>8080</default>
<advanced>true</advanced>
</parameter>
<parameter name="httpUser" type="text" required="false" groupName="network">
<label>Username</label>
<description>User name to access HTTP service.</description>
<advanced>true</advanced>
</parameter>
<parameter name="httpPassword" type="text" required="false" groupName="network">
<context>password</context>
<label>Password</label>
<description>Password to access the HTTP service.</description>
<advanced>true</advanced>
</parameter>
<parameter name="refreshInterval" type="integer" required="false" min="1" max="60" unit="s" groupName="connection">
<label>Refresh Interval</label>
<description>The refresh interval to poll Kodi API (in s).</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>

<config-description uri="channel-type:kodi:pvr-channel">
<parameter name="group" type="text" required="true">
<label>PVR channel group</label>
<description>The PVR channel group name used to identify the channel id</description>
<description>The PVR channel group name used to identify the channel id.</description>
<default>All channels</default>
</parameter>
</config-description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,24 @@ thing-type.kodi.kodi.label = Kodi Media Center
thing-type.kodi.kodi.description = Kodi Media Center

# thing types config
thing-typ.property.kodi.kodi.version = Version
thing-type.config.kodi.kodi.group.network.label = Netzwerk
thing-type.config.kodi.kodi.group.network.description = Einstellungen für das Netzwerk.

thing-type.config.kodi.kodi.group.connection.label = Verbindung
thing-type.config.kodi.kodi.group.connection.description = Einstellungen für die Verbindung.

thing-type.config.kodi.kodi.ipAddress.label = IP-Adresse
thing-type.config.kodi.kodi.ipAddress.description = Lokale IP-Adresse oder Hostname des Kodi Media Centers.
thing-type.config.kodi.kodi.port.label = Port
thing-type.config.kodi.kodi.port.description = Port des Kodi Media Centers.
thing-type.config.kodi.kodi.port.label = Port (Webservice)
thing-type.config.kodi.kodi.port.description = Port des Kodi Media Centers Webservices.
thing-type.config.kodi.kodi.httpPort.label = Port (Weboberfläche)
thing-type.config.kodi.kodi.httpPort.description = Port der Kodi Media Center Weboberfläche.
thing-type.config.kodi.kodi.httpUser.label = Benutzer
thing-type.config.kodi.kodi.httpUser.description = Benutzer zur Authentifizierung an der Kodi Media Center Weboberfläche.
thing-type.config.kodi.kodi.httpPassword.label = Passwort
thing-type.config.kodi.kodi.httpPassword.description = Passwort zur Authentifizierung an der Kodi Media Center Weboberfläche.
thing-type.config.kodi.kodi.refreshInterval.label = Abfrageintervall
thing-type.config.kodi.kodi.refreshInterval.description = Intervall zur Abfrage der des Kodi Media Centers (in Millisekunden).
thing-type.config.kodi.kodi.refreshInterval.description = Intervall zur Abfrage der des Kodi Media Centers (in Sekunden).

# channel types
channel-type.kodi.volume.label = Lautstärke
Expand Down Expand Up @@ -51,6 +61,10 @@ channel-type.kodi.artist.label = K
channel-type.kodi.artist.description = Zeigt den Künstler des aktuellen Stücks oder Films an.
channel-type.kodi.mediatype.label = Medientyp
channel-type.kodi.mediatype.description = Zeigt den Medientyp des aktuellen Stücks oder Films (z. B. movie, song) an.
channel-type.kodi.thumbnail.label = Thumbnail
channel-type.kodi.thumbnail.description = Zeigt das Thumbnail des aktuellen Stücks oder Films an.
channel-type.kodi.fanart.label = Fan Art
channel-type.kodi.fanart.description = Zeigt das Fan Art des aktuellen Stücks oder Films an.

# channel types config
channel-type.config.kodi.pvr-channel.group.label = PVR Kanal Gruppe
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="kodi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0"
<thing:thing-descriptions bindingId="kodi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0"
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 http://eclipse.org/smarthome/schemas/thing-description-1.0.0.xsd">

<!-- Kodi Thing Type -->
Expand All @@ -26,31 +26,15 @@
<channel id="album" typeId="album" />
<channel id="artist" typeId="artist" />
<channel id="mediatype" typeId="mediatype" />
<channel id="thumbnail" typeId="thumbnail" />
<channel id="fanart" typeId="fanart" />
</channels>

<properties>
<property name="version">unknown</property>
</properties>

<config-description>
<parameter name="ipAddress" type="text" required="true">
<label>Network Address</label>
<description>The IP or host name of the Kodi</description>
<context>network-address</context>
</parameter>
<parameter name="port" type="integer" required="true" min="1" max="65335">
<label>Web socket service port</label>
<description>Port for the web socket service</description>
<default>9090</default>
</parameter>
<parameter name="refreshInterval" type="integer" required="false"
unit="s">
<label>Refresh Interval</label>
<description>The refresh interval to poll Kodi API (in ms).</description>
<default>10</default>
<advanced>true</advanced>
</parameter>
</config-description>
<config-description-ref uri="thing-type:kodi:kodi" />
</thing-type>

<!-- Kodi Commands -->
Expand Down Expand Up @@ -178,4 +162,16 @@
<description>Media type of the current file</description>
<state readOnly="true" pattern="%s"></state>
</channel-type>
<channel-type id="thumbnail">
<item-type>Image</item-type>
<label>Thumbnail</label>
<description>The current thumbnail</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="fanart">
<item-type>Image</item-type>
<label>Fanart</label>
<description>The current fanart</description>
<state readOnly="true"></state>
</channel-type>
</thing:thing-descriptions>
2 changes: 2 additions & 0 deletions addons/binding/org.openhab.binding.kodi/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ Import-Package:
org.eclipse.smarthome.config.core,
org.eclipse.smarthome.config.discovery,
org.eclipse.smarthome.core.audio,
org.eclipse.smarthome.core.cache,
org.eclipse.smarthome.core.library.types,
org.eclipse.smarthome.core.net,
org.eclipse.smarthome.core.thing,
org.eclipse.smarthome.core.thing.binding,
org.eclipse.smarthome.core.thing.binding.builder,
org.eclipse.smarthome.core.thing.type,
org.eclipse.smarthome.core.types,
org.eclipse.smarthome.io.net.http,
org.jupnp.model.meta,
org.jupnp.model.types,
org.openhab.binding.kodi,
Expand Down
14 changes: 11 additions & 3 deletions addons/binding/org.openhab.binding.kodi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ The following configuration options are available for the Kodi binding:

### Thing Configuration

The Kodi thing requires the IP address of the device hosting your Kodi media center instance and the TCP port to access it on (default: `9090`).
These parameters will be found by the auto-discovery feature.
The Kodi thing requires the IP address of the device hosting your Kodi media center instance, the TCP port to access it (default: `9090`) and the HTTP port to build URLs to the Kodi webinterface for downloading thumbnail and fanart images (default: `8080`).
You optionally can define a `httpUser` and a `httpPassword` parameter if the access to your Kodi webinterface is protected.
The IP address will be found by the auto-discovery feature.

A manual setup through a `things/kodi.things` file could look like this:

```
Thing kodi:kodi:myKodi "Kodi" @ "Living Room" [ipAddress="192.168.1.100", port="9090"]
Thing kodi:kodi:myKodi "Kodi" @ "Living Room" [ipAddress="192.168.1.100", port="9090", httpPort="8080"]
```

## Channels
Expand All @@ -79,6 +80,9 @@ The Kodi thing supports the following channels:
| inputtext | String | This channel emulates a keyboard input |
| systemcommand | String | This channel allows to send commands to `shutdown`, `suspend`, `hibernate`, `reboot` kodi |
| mediatype | String | The media type of the current file. Valid return values are: `unknown`, `channel`, `episode`, `movie`, `musicvideo`, `picture`, `radio`, `song`, `video` |
| thumbnail | Image | The URL to the thumbnail of the current file |
| fanart | Image | The URL to the fanart of the current file |


### Channel Configuration

Expand Down Expand Up @@ -117,6 +121,8 @@ String myKodi_input "Input" { channel="kodi:kodi:myKodi:
String myKodi_inputtext "Inputtext" { channel="kodi:kodi:myKodi:inputtext" }
String myKodi_systemcommand "Systemcommand" { channel="kodi:kodi:myKodi:systemcommand" }
String myKodi_mediatype "Mediatype [%s]" { channel="kodi:kodi:myKodi:mediatype" }
Image myKodi_thumbnail { channel="kodi:kodi:myKodi:thumbnail" }
Image myKodi_fanart { channel="kodi:kodi:myKodi:fanart" }
```

## Sitemap Configuration
Expand All @@ -142,6 +148,8 @@ sitemap demo label="myKodi"
Selection item=myKodi_input mappings=[Up='Up', Down='Down', Left='Left', Right='Right', Select='Select', Back='Back', Home='Home', ContextMenu='ContextMenu', Info='Info']
Selection item=myKodi_systemcommand mappings=[Shutdown='Herunterfahren', Suspend='Bereitschaft', Reboot='Neustart']
Text item=myKodi_mediatype
Image item=myKodi_thumbnail
Image item=myKodi_fanart
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*
* @author Paul Frank - Initial contribution
* @author Christoph Weitkamp - Added channels for opening PVR TV or Radio streams
* @author Andreas Reinhardt & Christoph Weitkamp - Added channels for thumbnail and fanart
*
*/
public class KodiBindingConstants {
Expand All @@ -31,7 +32,10 @@ public class KodiBindingConstants {

// List of thing parameters names
public static final String HOST_PARAMETER = "ipAddress";
public static final String PORT_PARAMETER = "port";
public static final String WS_PORT_PARAMETER = "port";
public static final String HTTP_PORT_PARAMETER = "httpPort";
public static final String HTTP_USER_PARAMETER = "httpUser";
public static final String HTTP_PASSWORD_PARAMETER = "httpPassword";
public static final String REFRESH_PARAMETER = "refreshInterval";

// List of all Channel ids
Expand All @@ -54,6 +58,8 @@ public class KodiBindingConstants {
public static final String CHANNEL_ALBUM = "album";
public static final String CHANNEL_MEDIATYPE = "mediatype";
public static final String CHANNEL_PVR_CHANNEL = "pvr-channel";
public static final String CHANNEL_THUMBNAIL = "thumbnail";
public static final String CHANNEL_FANART = "fanart";

// Module Properties
public static final String PROPERTY_VERSION = "version";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@

import static org.openhab.binding.kodi.KodiBindingConstants.*;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
import org.eclipse.smarthome.core.library.types.NextPreviousType;
import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.PercentType;
import org.eclipse.smarthome.core.library.types.PlayPauseType;
import org.eclipse.smarthome.core.library.types.RawType;
import org.eclipse.smarthome.core.library.types.RewindFastforwardType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.thing.ChannelUID;
Expand All @@ -28,9 +32,11 @@
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.UnDefType;
import org.openhab.binding.kodi.internal.KodiEventListener;
import org.openhab.binding.kodi.internal.config.KodiChannelConfig;
import org.openhab.binding.kodi.internal.config.KodiConfig;
import org.openhab.binding.kodi.internal.protocol.KodiConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -41,7 +47,8 @@
*
* @author Paul Frank - Initial contribution
* @author Christoph Weitkamp - Added channels for opening PVR TV or Radio streams
*
* @author Andreas Reinhardt & Christoph Weitkamp - Added channels for thumbnail and fanart
*
*/
public class KodiHandler extends BaseThingHandler implements KodiEventListener {

Expand Down Expand Up @@ -205,6 +212,8 @@ public void handleCommand(ChannelUID channelUID, Command command) {
case CHANNEL_SHOWTITLE:
case CHANNEL_MEDIATYPE:
case CHANNEL_PVR_CHANNEL:
case CHANNEL_THUMBNAIL:
case CHANNEL_FANART:
if (command.equals(RefreshType.REFRESH)) {
connection.updatePlayerStatus();
}
Expand All @@ -215,6 +224,17 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
}

private URI getImageBaseUrl() throws URISyntaxException {
KodiConfig config = getConfigAs(KodiConfig.class);
String host = config.getIpAddress();
int httpPort = config.getHttpPort();
String httpUser = config.getHttpUser();
String httpPassword = config.getHttpPassword();
String userInfo = (StringUtils.isEmpty(httpUser) || StringUtils.isEmpty(httpPassword)) ? null
: String.format("%s:%s", httpUser, httpPassword);
return new URI("http", userInfo, host, httpPort, "/image/", null, null);
}

public void playURI(Command command) {
connection.playURI(command.toString());
}
Expand Down Expand Up @@ -253,7 +273,7 @@ public void initialize() {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"No network address specified");
} else {
connection.connect(host, getIntConfigParameter(PORT_PARAMETER, 9090), scheduler);
connection.connect(host, getIntConfigParameter(WS_PORT_PARAMETER, 9090), scheduler, getImageBaseUrl());

connectionCheckerFuture = scheduler.scheduleWithFixedDelay(() -> {
if (!connection.checkConnection()) {
Expand Down Expand Up @@ -335,32 +355,64 @@ public void updateMuted(boolean muted) {

@Override
public void updateTitle(String title) {
updateState(CHANNEL_TITLE, new StringType(title));
updateState(CHANNEL_TITLE, createState(title));
}

@Override
public void updateShowTitle(String title) {
updateState(CHANNEL_SHOWTITLE, new StringType(title));
updateState(CHANNEL_SHOWTITLE, createState(title));
}

@Override
public void updateAlbum(String album) {
updateState(CHANNEL_ALBUM, new StringType(album));
updateState(CHANNEL_ALBUM, createState(album));
}

@Override
public void updateArtist(String artist) {
updateState(CHANNEL_ARTIST, new StringType(artist));
updateState(CHANNEL_ARTIST, createState(artist));
}

@Override
public void updateMediaType(String mediaType) {
updateState(CHANNEL_MEDIATYPE, new StringType(mediaType));
updateState(CHANNEL_MEDIATYPE, createState(mediaType));
}

@Override
public void updatePVRChannel(final String channel) {
updateState(CHANNEL_PVR_CHANNEL, new StringType(channel));
updateState(CHANNEL_PVR_CHANNEL, createState(channel));
}

@Override
public void updateThumbnail(RawType thumbnail) {
updateState(CHANNEL_THUMBNAIL, createImage(thumbnail));
}

@Override
public void updateFanart(RawType fanart) {
updateState(CHANNEL_FANART, createImage(fanart));
}

/**
* Wrap the given String in a new {@link StringType} or returns {@link UnDefType#UNDEF} if the String is empty.
*/
private State createState(String string) {
if (string == null || string.isEmpty()) {
return UnDefType.UNDEF;
} else {
return new StringType(string);
}
}

/**
* Wrap the given RawType and return it as {@link State} or return {@link UnDefType#UNDEF} if the RawType is null.
*/
private State createImage(RawType image) {
if (image == null) {
return UnDefType.UNDEF;
} else {
return image;
}
}

}
Loading

0 comments on commit f238e11

Please sign in to comment.