Updated external content (Jenkins build 919)

pull/1839/head
openHAB Build Server 2022-04-30 15:23:19 +00:00
parent 0d36d3ab05
commit a25e17ad30
4 changed files with 308 additions and 1 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,137 @@
---
id: jellyfin
label: Jellyfin
title: Jellyfin - Bindings
type: binding
description: "This is the binding for [Jellyfin](https://jellyfin.org) the volunteer-built media solution that puts you in control of your media."
since: 3x
install: manual
---
<!-- Attention authors: Do not edit directly. Please add your changes to the appropriate source repository -->
{% include base.html %}
# Jellyfin Binding
This is the binding for [Jellyfin](https://jellyfin.org) the volunteer-built media solution that puts you in control of your media.
Stream to any device from your own server, with no strings attached.
Your media, your server, your way.
This binding allows connect to Jellyfin clients that supports remote control, it's build on top of the official Jellyfin kotlin sdk.
## Supported Things
This binding was tested against the android tv, and web clients.
The only problem that I found is that the channels play-next-by-terms and play-last-by-terms don't work currently on the android tv client.
Before open an issue please test you are able to correctly control your device from the Jellyfin web ui to identify whetter is an issue on the client itself.
## Discovery
Before you are able to discover clients you should have a bridge to the server so until one is online the discovery will only look for servers on your local network. Once one is online the discovery will detect controllable clients connected to that server.
## Thing Types
| ThingTypeID | description |
|----------|------------------------------|
| server (bridge) | Jellyfin server instance |
| client | Jellyfin controllable client instance |
## Authentication
To allow the server thing to go online you should provide valid credentials for the user that the biding will use to interact with the server api (userId and token configuration properties).
Please note that the user should be allowed on the Jellyfin server to remote control devices.
In order to assist you with this process the binding expose a simple login form you can access on \<local openHAB server url\>/jellyfin/\<server thing id\> for example http://127.0.0.1:8080/jellyfin/2846b8fb60ad444f9ebd085335e3f6bf.
## Server Thing Configuration
| Config | Type | description |
|----------|----------|------------------------------|
| hostname | text | Hostname or IP address of the server (required) |
| port | integer | Port of the server (required) |
| ssl | boolean | Connect through https (required) |
| refreshSeconds | integer | Interval to pull devices state from the server |
| clientActiveWithInSeconds | integer | Amount off seconds allowed since the last client activity to assert it's online (0 disabled) |
| userId | text | The user id |
| token | text | The user access token |
## Channels
| channel | type | description |
|----------|--------|------------------------------|
| send-notification | String | Display message in client |
| media-control | Player | Control media playback |
| playing-item-name | String | Name of the item currently playing (readonly) |
| playing-item-series-name | String | Name of the item's series currently playing, only have value when item is an episode (readonly) |
| playing-item-season-name | String | Name of the item's season currently playing, only have value when item is an episode (readonly) |
| playing-item-season | Number | Number of the item's season currently playing, only have value when item is an episode (readonly) |
| playing-item-episode | Number | Number of the episode item currently playing, only have value when item is an episode (readonly) |
| playing-item-genders | String | Coma separate list genders of the item currently playing (readonly) |
| playing-item-type | String | Type of the item currently playing (readonly) |
| playing-item-percentage | Dimmer | Played percentage for the item currently playing, allow seek |
| playing-item-second | Number | Current second for the item currently playing, allow seek |
| playing-item-total-seconds | Number | Total seconds for the item currently playing (readonly) |
| play-by-terms | String | Play media by terms, works for series, episodes and movies; terms search is explained bellow |
| play-next-by-terms | String | Add to playback queue as next by terms, works for series, episodes and movies; terms search is explained bellow |
| play-last-by-terms | String | Add to playback queue as last by terms, works for series, episodes and movies; terms search is explained bellow |
| browse-by-terms | String | Browse media by terms, works for series, episodes and movies; terms search is explained bellow |
### Terms search:
The terms search has a default behavior that can be modified sending some predefined prefixes.
The default behavior will look for movies, series, or episodes whose name start with the provided text, if it found results the prevalence go as said before.
If the result is a series the binding will try to resume some episode, if not it will look for the next episode to watch and finally will fall back to the first episode.
You can prefix your search with '\<type:movie\>', '\<type:episode\>', '\<type:series\>' to restrict your search to a given type.
Also, you can target a specific series episode by season and episode numbers prefixing your search with '\<season:1\>\<episode:1\>' with the desired values. So '\<season:3\>\<episode:10\>Something' will try to play the episode 10 for the season 3 of the series named 'Something'.
## Full Example
### Example Server (Bridge) - jellyfin.bridge.things
```
Bridge jellyfin:server:exampleServerId "Jellyfin Server" [
clientActiveWithInSeconds=0,
hostname="192.168.1.177",
port=8096,
refreshSeconds=30,
ssl="false"
token=XXXXX # Optional, read bellow
userId=XXXXX # Optional, read bellow
]
```
* token and userId could be retrieved using the login form at http://YOUROPENHABIP:PORT/jellyfin/exampleServerId
### Example Client - jellyfin.clients.things
```
Thing jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID> "Jellyfin Web client" (jellyfin:server:exampleServerId)
Thing jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID> "Jellyfin Android client" (jellyfin:server:exampleServerId)
```
* I recommend creating the clients using the discovery. For getting the device ids manually I recommend to use the Jellyfin web interface with the web inspector and look for the request that is launched when you click the cast button (<jellyfin url>/Sessions?ControllableByUserId=XXXXXXXXXXXX).
### Example Items - jellyfin.items
```
String strJellyfinAndroidSendNotification { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:send-notification " }
Player plJellyfinAndroidMediaControl { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:media-control" }
String strJellyfinAndroidPlayingItemName { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-name" }
String strJellyfinAndroidPlayingItemSeriesName { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-series-name" }
String strJellyfinAndroidPlayingItemSeasonName { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-season-name" }
Number nJellyfinAndroidPlayingItemSeason { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-season" }
Number nJellyfinAndroidPlpayingItemEpisode { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-episode" }
String strJellyfinAndroidPlayingItemGenders { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-genders" }
String strJellyfinAndroidPlayingItemType { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-type" }
Dimmer dJellyfinAndroidPlayingItemPercentage { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-percentage" }
Number nJellyfinAndroidPlayingItemSecond { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-second" }
Number nJellyfinAndroidPlayingItemTotalSeconds { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:playing-item-total-seconds" }
String strJellyfinAndroidPlayByTerms { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:play-by-terms" }
String strJellyfinAndroidPlayByNextTerms { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:play-next-by-terms" }
String strJellyfinAndroidPlayByLastTerms { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:play-last-by-terms" }
String strJellyfinAndroidBrowseByTerms { channel="jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID>:browse-by-terms" }
```

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="jellyfin"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<bridge-type id="server">
<label>Jellyfin Server</label>
<description>Represents a running Jellyfin server instance</description>
<config-description>
<parameter name="hostname" type="text" required="true">
<context>network-address</context>
<label>Hostname/IP</label>
<description>Hostname or IP address of the server</description>
<default>127.0.0.1</default>
</parameter>
<parameter name="port" type="integer" min="0" max="65535" required="true">
<label>Port</label>
<description>Port of the server</description>
<default>8096</default>
</parameter>
<parameter name="ssl" type="boolean" required="true">
<label>SSL</label>
<description>Connect through https</description>
<default>false</default>
</parameter>
<parameter name="refreshSeconds" type="integer" min="10" max="300" required="true">
<label>Refresh Seconds</label>
<description>Interval to pull devices state from the server</description>
<default>30</default>
</parameter>
<parameter name="clientActiveWithInSeconds" type="integer" min="0" max="950" required="true">
<label>Client Active Timeout</label>
<description>Amount off seconds allowed since the last client activity to assert it's online (0 disabled)</description>
<default>0</default>
</parameter>
<parameter name="userId" type="text">
<label>User ID</label>
<description>The user id</description>
</parameter>
<parameter name="token" type="text">
<label>Access Token</label>
<description>The user access token</description>
</parameter>
</config-description>
</bridge-type>
<!-- Sample Thing Type -->
<thing-type id="client">
<supported-bridge-type-refs>
<bridge-type-ref id="server"/>
</supported-bridge-type-refs>
<label>Jellyfin Client</label>
<description>Represents a running Jellyfin client connected to a server</description>
<channels>
<channel id="send-notification" typeId="send-notification-channel"/>
<channel id="media-control" typeId="system.media-control"/>
<channel id="playing-item-name" typeId="playing-item-name-channel"/>
<channel id="playing-item-series-name" typeId="playing-item-series-name-channel"/>
<channel id="playing-item-season-name" typeId="playing-item-season-name-channel"/>
<channel id="playing-item-season" typeId="playing-item-season-channel"/>
<channel id="playing-item-episode" typeId="playing-item-episode-channel"/>
<channel id="playing-item-genders" typeId="playing-item-genders-channel"/>
<channel id="playing-item-type" typeId="playing-item-type-channel"/>
<channel id="playing-item-percentage" typeId="playing-item-percentage-channel"/>
<channel id="playing-item-second" typeId="playing-item-second-channel"/>
<channel id="playing-item-total-seconds" typeId="playing-item-total-seconds-channel"/>
<channel id="play-by-terms" typeId="play-by-terms-channel"/>
<channel id="play-next-by-terms" typeId="play-next-by-terms-channel"/>
<channel id="play-last-by-terms" typeId="play-last-by-terms-channel"/>
<channel id="browse-by-terms" typeId="browse-by-terms-channel"/>
</channels>
<config-description>
</config-description>
</thing-type>
<!-- Client Channels -->
<channel-type id="send-notification-channel">
<item-type>String</item-type>
<label>Send Notification</label>
<description>Send notification to the client</description>
</channel-type>
<channel-type id="playing-item-name-channel">
<item-type>String</item-type>
<label>Playing Item Name</label>
<description>Name of the item currently playing</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-series-name-channel">
<item-type>String</item-type>
<label>Playing Item Series Name</label>
<description>Name of the item's series currently playing, only have value when item is an episode</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-season-name-channel">
<item-type>String</item-type>
<label>Playing Item Season Name</label>
<description>Name of the item's season currently playing, only have value when item is an episode</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-season-channel">
<item-type>Number</item-type>
<label>Playing Item Season</label>
<description>Number of the item's season currently playing, only have value when item is an episode</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-episode-channel">
<item-type>Number</item-type>
<label>Playing Item Episode</label>
<description>Number of the episode item currently playing, only have value when item is an episode</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-genders-channel">
<item-type>String</item-type>
<label>Playing Item Genders</label>
<description>Coma separate list genders of the item currently playing</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-type-channel">
<item-type>String</item-type>
<label>Playing Item Type</label>
<description>Type of the item currently playing</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="playing-item-percentage-channel">
<item-type>Dimmer</item-type>
<label>Playing Item Percentage</label>
<description>Played percentage for the item currently playing, allow seek</description>
</channel-type>
<channel-type id="playing-item-second-channel">
<item-type>Number</item-type>
<label>Playing Item Second</label>
<description>Current second for the item currently playing, allow seek</description>
</channel-type>
<channel-type id="playing-item-total-seconds-channel">
<item-type>Number</item-type>
<label>Playing Item Total Seconds</label>
<description>Total seconds for the item currently playing</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="play-by-terms-channel">
<item-type>String</item-type>
<label>Play By Terms</label>
<description>Play media by terms, works for series, episodes and movies</description>
</channel-type>
<channel-type id="play-next-by-terms-channel">
<item-type>String</item-type>
<label>Play Next By Terms</label>
<description>Add to playback queue as next by terms; works for series, episodes and movies</description>
</channel-type>
<channel-type id="play-last-by-terms-channel">
<item-type>String</item-type>
<label>Play Last By Terms</label>
<description>Add to playback queue as last by terms; works for series, episodes and movies</description>
</channel-type>
<channel-type id="browse-by-terms-channel">
<item-type>String</item-type>
<label>Browse By Terms</label>
<description>Browse media by terms, works for series, episodes and movies</description>
</channel-type>
</thing:thing-descriptions>

View File

@ -92,6 +92,14 @@ DateTime AlarmClock "Alarm Clock [%s]" <time>
Rule template: [https://community.openhab.org/t/alarm-clock-rule/127194](https://community.openhab.org/t/alarm-clock-rule/127194)
##### Limitations
The openHAB app uses the internal Android API [https://developer.android.com/reference/kotlin/android/app/AlarmManager](AlarmManager) to get the next alarm time.
Some apps use this API (e.g. the stock calendar app) for other purposes, e.g. scheduling notifications.
Therefore the openHAB app may send invalid alarm times to the server.
To circumvent this the alarm times set by some apps are blocklisted in the openHAB app and it'll send `UNDEF` instead.
It's not possible to read the time after the next.
#### Call State
Example item definition: