RESTFULAPI Documentation

This plugin has been developed to offer a modern API for other developers to communicate with the VDR.

The plugin supports the following outputs formats: xml, json and html.

It also supports the following input formats: json and html.

It would not exist without the help of the following people:

- Klaus Schmidinger: Of course because of the VDR itself. Thank you also for the nice and clean layout for the API-Documentation which I "borrowed" from your PLUGINS.html.
- Gerald Dachs: Thank you for the intial idea and the initial jsonapi-Plugin.
- Volker Richert: Thank you for fixing the UTF8-Support.
- Tommi Mäkitalo: Thank you for implementing the Regex-Support in cxxtools which allows RESTful web services.
- Holger Schvestka: Thank you for improving the package structure.
- All other yaVDR-Members who I haven't already mentioned, just because you are who you are and do your best to improve the VDR experience.
- The developers of the live and vnsisserver Plugins which helped me to learn a lot about the API of VDR.
- The developers of the live plugin where I borrowed parts of the epgsearch-implementation :-)
- Daniel Kuschny: Thank you for fixing my broken regular expressions. Will pay you a beer! :-)
- Keine_Ahnung@vdr-portal for the VDR 1.6 compatibility patch

This document describes the API and how to use it. It contains a lot of examples for the different formats and services but there is still a lot more to discover if you simply try to make a few simple requests.

Someone who wants to install the plugin on his/her VDR needs following applications and libraries:

- VDR 1.7.18
- libcxxtools Rev. >= 1231, which is available as package for Ubuntu in the yavdr-PPA's

Someone who wants to develop an application which uses this API:

- XML or JSON Parser (Depends on which format you want to use! - You can also use the html-format, but that one is more a proof for the restful concept and does not show all information!)
- URL Decoder or JSON Serializer (to send data to the webservice, required e.g. to create timers, searchtimers etc...) e.g. POSTMan REST Client. There is a wide variety of REST clients available on the web.

Create a new file called plugin.restfulapi.conf in /etc/vdr/plugins/ respectively /etc/vdr/conf.avail (don't forget to create a symlink in /etc/vdr/conf.d/).
# # Command line parameters for vdr-plugin-restfulapi # --port=8002 --ip=0.0.0.0 --epgimages=/var/cache/vdr/epgimages --channellogos=/usr/share/vdr/channel-logos --webapp=/var/lib/vdr/plugins/restfulapi/webapp,/var/lib/vdr/plugins/restfulapi/a-second-webapp

This service returns a list of channels.

GET

GET http://<ip>:<port>/channels/.<format> GET http://<ip>:<port>/channels/<channelid>.<format> GET http://<ip>:<port>/channels/.<format>?start=<int>&limit=<int>

- <format> - The requested format: json, xml or html.
- <channelid> - Id of the requested channel.
- start, limit - These values are used to control the whole list. Start ist the first element you want to retrieve. Limit...

GET http://127.0.0.1:8002/channels.xml?start=0&limit=1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <channels xmlns="http://www.domain.org/restfulapi/2011/channels-xml"> <channel> <param name="name"<ORF1 HD</param> <param name="number">1</param> <param name="channel_id">C-71-71-61920</param< <param name="image">true</param> <param name="group">hd</param> <param name="transponder">330</param> <param name="stream">C-71-71-61920.ts</param> <param name="is_atsc">false</param> <param name="is_cable">true</param> <param name="is_sat">false</param> <param name="is_terr">false</param> <param name="is_radio">false</param> </channel> <count>1</count> <total>259</total> </channels>
GET http://127.0.0.1:8002/channels.json?start=0&limit=1 { "channels": [ { "name":"ORF1 HD", "number":1, "channel_id":"C-71-71-61920", "image":true, "group":"hd", "transponder":330, "stream":"C-71-71-61920.ts", "is_atsc":false, "is_cable":true, "is_terr":false, "is_sat":false, "is_radio": false } ], "count":1, "total":259 }

### Groups

This service will return a list containing all channel groups.

GET

GET http://<ip>:<port>/channels/groups.<format> GET http://<ip>:<port>/channels/groups.<format>?start=<int>&limit=<int> GET http://<ip>:<port>/channels.<format>?group=<group>

- <group> - returns the channels of the requested group
- <format> - json | xml | html

GET http://<ip>:<port>/channels/groups.xml?start=0&limit=3 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <groups xmlns="http://www.domain.org/restfulapi/2011/groups-xml"> <group>hd</group> <group>main</group> <group>stuff</group> <count>3</count> <total>3</total> </groups>
GET http://<ip>:<port>/channels/groups.json?start=0&limit=3 { "groups": [ "hd", "main", "stuff" ], "count":3, "total":3 }

### Images / Channel-Logos

This service returns the requested channel-logo.

GET

GET http://<ip>:<port>/channels/image/<channelid>

- <channelid> - id of channel

This service returns the epg information.

Since Version 0.2.0 the API returns additional media if a scraper plugin is available.
The data is available within additional_media node and contains additional information about the event such as actors etc.
Images can be retrieved using ScraperImages service.

GET

GET http://<ip>:<port>/events.<format>?chevents=1 GET http://<ip>:<port>/events/<channelid>.<format>?chevents=1&from=<from> GET http://<ip>:<port>/events/<channelid>.<format>?timespan=<timespan> GET http://<ip>:<port>/events/<channelid>/<eventid>.<format> GET http://<ip>:<port>/events/<channelid>.<format>?timespan=<timespan>&from=<from>&start=<int>&limit=<int>

- <format> - The requested format: json, xml or html.
- <channelid> - (optional) id of the channel, if not set the plugin will return the whole epg sorted by your channel list
- <timespan> - the timespan from which you want to know the event-details, if set to 0 - all events in the future will be returned
- <from> - (optional) time in the future when the requested events should end/start (default-value: now)
- <eventid> - (optional) if you only want the details of a specific event
- <chevents> - (optional) the count of events for each channel
- <chfrom> - (optional) start number of the channel, from where events will be returned
- <chto> - (optional) end number of the channel, through events will be returned
- <only_count> - (optional) if you just want to know the amount of available epg items
- <format> - The requested format: json, xml or html.

GET http://<ip>:<port>/events/C-1-1079-11110.xml?chevents=1&from=1432577700 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <events xmlns="http://www.domain.org/restfulapi/2011/events-xml"> <event> <param name="id">588333</param> <param name="title">Title</param> <param name="short_text">Humor (D 2010)</param> <param name="description">Description Text</param> <param name="channel">C-1-1079-11110</param> <param name="channel_name">ZDF HD</param> <param name="start_time">1432577700</param> <param name="duration">5400</param> <param name="table_id">80</param> <param name="version">25</param> <param name="parental_rating">0</param> <param name="vps">1432577700</param> <param name="details"></param> <param name="images">3</param> <param name="components"> <component stream="2" type="3" language="deu" description="Stereo" /> <component stream="2" type="3" language="mis" description="Audiodeskription" /> <component stream="2" type="3" language="mul" description="ohne Originalton" /> <component stream="3" type="32" language="deu" description="DVB-Untertitel" /> <component stream="4" type="66" language="deu" description="Dolby Digital 2.0" /> <component stream="5" type="11" language="deu" description="HDTV" /> </param> <param name="contents"></param> <param name="raw_contents"></param> <param name="timer_exists">false</param> <param name="timer_active">false</param> <param name="timer_id"></param> <param name="additional_media" type="movie"> <movie_id>329933</movie_id> <title>Title</title> <original_title>Original Title</original_title> <overview>Overview Text</overview> <adult>false</adult> <genres>Komödie , Lovestory</genres> <release_date>2010-06-01</release_date> <runtime>90</runtime> <poster path="movies/329933/poster.jpg" width="500" height="750" /> <fanart path="movies/329933/fanart.jpg" width="1280" height="720" /> <actor name="Name" role="Role" thumb="movies/actors/actor_49104.jpg"/> </param> </event> <count>1</count> <total>257</total> </events>
GET http://<ip>:<port>/events/C-1-1079-11110.json?chevents=1&from=1432577700 { "events": [ { "id": 588333, "title": "Title", "short_text": "Short Title", "description": "Description Text", "start_time": 1432577700, "channel": "C-1-1079-11110", "channel_name": "ZDF HD", "duration": 5400, "table_id": 80, "version": 25, "images": 3, "timer_exists": false, "timer_active": false, "timer_id": "", "parental_rating": 0, "vps": 1432577700, "components": [ { "stream": 2, "type": 3, "language": "deu", "description": "Stereo" }, { "stream": 2, "type": 3, "language": "mis", "description": "Audiodeskription" }, { "stream": 2, "type": 3, "language": "mul", "description": "ohne Originalton" }, { "stream": 3, "type": 32, "language": "deu", "description": "DVB-Untertitel" }, { "stream": 4, "type": 66, "language": "deu", "description": "Dolby Digital 2.0" }, { "stream": 5, "type": 11, "language": "deu", "description": "HDTV" } ], "contents": [], "raw_contents": [], "details": [], "additional_media": { "type": "movie", "movie_id": 329933, "title": "Title", "original_title": "Original Title", "tagline": "", "overview": "Overview Text", "adult": false, "collection_name": "", "budget": 0, "revenue": 0, "genres": "Komödie , Lovestory", "homepage": "", "release_date": "2010-06-01", "runtime": 90, "popularity": 0, "vote_average": 0, "poster": "movies/329933/poster.jpg", "fanart": "movies/329933/fanart.jpg", "collection_poster": "", "collection_fanart": "", "actors": [ { "name": "Name", "role": "Role", "thumb": "movies/actors/actor_49104.jpg" } ] } } ], "count": 1, "total": 257 }

### Images

This service returns the requested epg image.

GET

GET http://<ip>:<port>/events/image/<eventid>/<imagenumber>

- <eventid> - Id of the event
- <imagenumber> - the number of the image, in the above mentioned examples it would be 0,1 or 2

### Search

This service allows you to search for events.

Since Version 0.2.4.0 it is possible to perform a search similar to Searchtimers.

POST

POST http://<ip>:<port>/events/search.<format>?limit=5&start=0;

- <limit> - (optional) number of searchresults
- <start> - (required if limit is set) start at result
- <date_limit> - (optional) UNIX timestamp until events are returned (since 0.2.4.1)

Name | Type | Required | Value Range / Example
--- | --- | --- | ---
search | string | yes |
mode | int | yes | 0=phrase, 1=all words, 2=at least one word, 3=match exactly, 4=regex, 5=fuzzy
tolerance | int | if mode == 5 |
match_case | boolean |  |
use_title | boolean | at least one of use_title, use_subtitle, use_description |
use_subtitle | boolean | at least one of use_title, use_subtitle, use_description |
use_description | boolean | at least one of use_title, use_subtitle, use_description |
content_descriptors | string | no | concatted string of content descriptor ids
use_ext_epg_info | boolean | no |
ext_epg_info | array |  | [1#2,2#test]
use_time | boolean | no |
start_time | int | no |
stop_time | int | no |
use_channel | boolean | no | 0=no, 1=interval, 2=channel group, 3=only FTA
channel_min | string | no | channel id
channel_max | string | no | channel id
channels | string | if use_channel > 0 | channel group name
use_duration | boolean | no |
duration_min | int | if use_duration == true |
duration_max | int | if use_duration == true |
use_dayofweek | boolean | no |
dayofweek | int | if use_dayofweek == true | -127 - 6
blacklist_mode | int | no | 0=global, 1=Selection, 2=all, 3=none
blacklist_ids | array | if blacklist_mode == 1 | array of blacklist ids

POST http://<ip>:<port>/events/search.<format>?limit=5&start=0;

- <limit> - (optional) number of searchresults
- <start> - (required if limit is set) start at result

- query - (required)
- mode - (required) 0=phrase, 1=and, 2=or, 3=exact, 4=regex, 5=fuzzy
- channelid - (optional) if id invalid, the plugin will search on every channel
- use_title - (optional, default) search in the title
- use_subtitle - (optional)
- use_description - (optional)

{"query":"Asterix", "mode":0, "channelid":0,"use_title":true}

### Fetch content descriptors

GET

GET http://<ip>:<port>/events/contentdescriptors.<format>
{ "content_descriptors": [ { "id": "10", "name": "Film/Drama", "is_group": true }, { "id": "11", "name": "Detektiv/Thriller", "is_group": false }, { "id": "12", "name": "Abenteuer/Western/Krieg", "is_group": false }, . . . ], "count": 79, "total": 79 }

General Information about the plugin and vdr.

Since version 0.2.6.0 basic femon data is available. SNR, STR, BER, UNC and Status. The status field contains a colon seperated list of available status in following order:

- Locked
- Signal
- Carrier
- Viterbi
- Sync

If a status is false the list contains a minus sign instead.

GET

GET http://<ip>:<port>/info.<format>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <info xmlns="http://www.domain.org/restfulapi/2011/info-xml"> <version>0.0.1</version> <time>1432551206</time> <services> <service path="/info" version="1" internal="true" /> <service path="/channels" version="1" internal="true" /> <service path="/channels/groups" version="1" internal="true" /> <service path="/channels/image" version="1" internal="true" /> <service path="/events" version="1" internal="true" /> <service path="/events/image" version="1" internal="true" /> <service path="/events/search" version="1" internal="false" /> <service path="/recordings" version="1" internal="true" /> <service path="/recordings/cut" version="1" internal="true" /> <service path="/recordings/marks" version="1" internal="true" /> <service path="/remote" version="1" internal="true" /> <service path="/timers" version="1" internal="true" /> <service path="/osd" version="1" internal="true" /> <service path="/searchtimers" version="1" internal="false" /> <service path="/scraper" version="1" internal="true" /> <service path="/wirbelscan" version="1" internal="true" /> <service path="/wirbelscan/countries" version="1" internal="true" /> <service path="/webapp" version="1" internal="true" /> <service path="/femon" version="1" internal="true" /> </services> <channel>C-61441-10009-10331</channel> <diskusage> <free_mb>3491143</free_mb> <free_minutes>98218</free_minutes> <used_percent>67</used_percent> <description_localized>Disk 67% - 1636:58 frei</description_localized> </diskusage> <vdr> <plugins> <plugin name="dvbapi" version="2.2.0-GIT-5fdb21e" /> <plugin name="wirbelscan" version="0.0.9" /> <plugin name="svdrposd" version="1.0.0" /> <plugin name="vnsiserver" version="1.3.0" /> <plugin name="epgsearchonly" version="0.0.1" /> <plugin name="femon" version="2.2.1" /> <plugin name="markad" version="0.1.5pre" /> <plugin name="svdrpservice" version="1.0.0" /> <plugin name="restfulapi" version="0.2.3.1" /> <plugin name="epgsearch" version="1.0.1.beta5" /> <plugin name="conflictcheckonly" version="0.0.1" /> <plugin name="scraper2vdr" version="0.1.13" /> <plugin name="epg2vdr" version="0.1.12" /> <plugin name="quickepgsearch" version="0.0.1" /> <plugin name="live" version="0.3.0" /> <plugin name="streamdev-server" version="0.6.1-git" /> </plugins> </vdr> <devices> <device> <dvb_c>true</dvb_c> <dvb_s>false</dvb_s> <dvb_t>false</dvb_t> <atsc>false</atsc> <primary>false</primary> <has_decoder>false</has_decoder> <name>Philips TDA10023 DVB-C</name> <number>0</number> <channel_id>C-61441-10011-50059</channel_id> <channel_name>n-tv HD</channel_name> <channel_nr>17</channel_nr> <live>false</live> <has_ci>true</has_ci> <signal_strength>63</signal_strength> <signal_quality>5</signal_quality> <signal_str>65535</signal_str> <signal_snr>380</signal_snr> <signal_ber>0</signal_ber> <signal_unc>0</signal_unc> <signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status> <adapter>0</adapter> <frontend>0</frontend> <type>DVB-C</type> </device> <device> <dvb_c>true</dvb_c> <dvb_s>false</dvb_s> <dvb_t>true</dvb_t> <atsc>false</atsc> <primary>false</primary> <has_decoder>false</has_decoder> <name>DRXK DVB-C DVB-T</name> <number>1</number> <channel_id>C-61441-10003-53604</channel_id> <channel_name>VOX</channel_name> <channel_nr>1011</channel_nr> <live>false</live> <has_ci>false</has_ci> <signal_strength>0</signal_strength> <signal_quality>5</signal_quality> <signal_str>65535</signal_str> <signal_snr>380</signal_snr> <signal_ber>0</signal_ber> <signal_unc>0</signal_unc> <signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status> <adapter>1</adapter> <frontend>0</frontend> <type>DVB-C</type> </device> <device> <dvb_c>true</dvb_c> <dvb_s>false</dvb_s> <dvb_t>true</dvb_t> <atsc>false</atsc> <primary>false</primary> <has_decoder>false</has_decoder> <name>DRXK DVB-C DVB-T</name> <number>2</number> <channel_id>C-61441-10011-50059</channel_id> <channel_name>n-tv HD</channel_name> <channel_nr>17</channel_nr> <live>false</live> <has_ci>false</has_ci> <signal_strength>0</signal_strength> <signal_quality>5</signal_quality> <signal_str>65535</signal_str> <signal_snr>380</signal_snr> <signal_ber>0</signal_ber> <signal_unc>0</signal_unc> <signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status> <adapter>2</adapter> <frontend>0</frontend> <type>DVB-C</type> </device> </devices> </info>
{ "version": "0.0.1", "time": 1432551355, "services": [ { "path": "/info", "version": 1 }, { "path": "/channels", "version": 1 }, { "path": "/channels/groups", "version": 1 }, { "path": "/channels/image", "version": 1 }, { "path": "/events", "version": 1 }, { "path": "/events/image", "version": 1 }, { "path": "/events/search", "version": 1 }, { "path": "/recordings", "version": 1 }, { "path": "/recordings/cut", "version": 1 }, { "path": "/recordings/marks", "version": 1 }, { "path": "/remote", "version": 1 }, { "path": "/timers", "version": 1 }, { "path": "/osd", "version": 1 }, { "path": "/searchtimers", "version": 1 }, { "path": "/scraper", "version": 1 }, { "path": "/wirbelscan", "version": 1 }, { "path": "/wirbelscan/countries", "version": 1 }, { "path": "/webapp", "version": 1 }, { "path": "/femon", "version": 1 } ], "channel": "C-61441-10009-10331", "eventid": -1, "start_time": -1, "duration": -1, "title": "", "diskusage": { "free_mb": 3491143, "used_percent": 67, "free_minutes": 98218, "description_localized": "Disk 67% - 1636:58 frei" }, "vdr": { "plugins": [ { "name": "wirbelscan", "version": "0.0.9" }, { "name": "svdrposd", "version": "1.0.0" }, { "name": "vnsiserver", "version": "1.3.0" }, { "name": "epgsearchonly", "version": "0.0.1" }, { "name": "femon", "version": "2.2.1" }, { "name": "markad", "version": "0.1.5pre" }, { "name": "svdrpservice", "version": "1.0.0" }, { "name": "restfulapi", "version": "0.2.3.1" }, { "name": "epgsearch", "version": "1.0.1.beta5" }, { "name": "conflictcheckonly", "version": "0.0.1" }, { "name": "scraper2vdr", "version": "0.1.13" }, { "name": "epg2vdr", "version": "0.1.12" }, { "name": "quickepgsearch", "version": "0.0.1" }, { "name": "live", "version": "0.3.0" }, { "name": "streamdev-server", "version": "0.6.1-git" } ], "devices": [ { "name": "Philips TDA10023 DVB-C", "dvb_c": true, "dvb_s": false, "dvb_t": false, "atsc": false, "primary": false, "has_decoder": false, "number": 0, "channel_id": "C-1-1051-11100", "channel_name": "Das Erste HD", "channel_nr": 1, "live": false, "has_ci": true, "signal_strength": 81, "signal_quality": 5, "str": 65535 "snr": 378 "ber": 0 "unc": 0 "status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC" "adapter": 2, "frontend": 0, "type": "DVB-C" "adapter": 0, "frontend": 0, "type": "DVB-C" }, { "name": "DRXK DVB-C DVB-T", "dvb_c": true, "dvb_s": false, "dvb_t": true, "atsc": false, "primary": false, "has_decoder": false, "number": 1, "channel_id": "C-61441-10011-50059", "channel_name": "n-tv HD", "channel_nr": 17, "live": false, "has_ci": false, "signal_strength": 0, "signal_quality": 5, "str": 65535 "snr": 378 "ber": 0 "unc": 0 "status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC" "adapter": 2, "frontend": 0, "type": "DVB-C" "adapter": 1, "frontend": 0, "type": "DVB-C" }, { "name": "DRXK DVB-C DVB-T", "dvb_c": true, "dvb_s": false, "dvb_t": true, "atsc": false, "primary": false, "has_decoder": false, "number": 2, "channel_id": "C-61441-10011-50059", "channel_name": "n-tv HD", "channel_nr": 17, "live": false, "has_ci": false, "signal_strength": 0, "signal_quality": 5, "str": 65535 "snr": 378 "ber": 0 "unc": 0 "status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC" "adapter": 2, "frontend": 0, "type": "DVB-C" } ] } }

Instead of the channel it can also contain the currently playing video file:

<video name="Asterix in Amerika">/var/lib/video.00/Asterix_in_Amerika/2011-06-19.12.40.1-0.rec</video>

Since Version 0.2.2.2 node "vdr" also contains info about the TV-Cards attached to the system

This Service delivers current OSD contents

GET

GET http://<ip>:<port>/osd.<format>
{ "TextOsd" : { "type" : "TextOsd", "title" : "VDR - Disk 68% - 57:53 free", "message" : "", "red" : "", "green" : "Audio", "yellow" : "", "blue" : "Stop", "items" : [ { "content" : " 1 Schedule", "is_selected":true }, { "content":" 2 Channels", "is_selected":false }, { "content":" 3 Timers", "is_selected":false }, { "content":" 4 Recordings", "is_selected":false }, { "content":" 5 Search", "is_selected":false }, { "content":" 6 Media Player", "is_selected":false }, { "content":" 7 Program guide", "is_selected":false }, { "content":" 8 Quick search", "is_selected":false }, { "content":" 9 Timer conflicts", "is_selected":false }, { "content":" 10 Setup", "is_selected":false }, { "content":" 11 Commands", "is_selected":false }, { "content":" Stop replaying", "is_selected":false } ] } }
{ "ProgrammeOsd" : { "present_time":1311710264, "present_title":"Der letzte Bulle", "present_subtitle":"Ich hab sie alle gehabt", "following_time":1311713161, "following_title":"direkt - das magazin", "following_subtitle":"" } }

This service can move/delete recordings and can also return all the recordings as a list.

Since Verions 0.2.0 the API returns additional media if a scraper plugin is available. The data is available within leaf additional_media and contains additional information about the event such as actors etc.
Please have a look at the data or the JSDoc Examples to get an idea about the additional structure. Images can be retrieved using ScraperImages service.

Since Version 0.2.5 one can fetch Recordings either by its full file name or by number. It is not safe to use the recording number for e.g. deleting recordings because it is not guaranteed that the numbers don't change during runtime. Hence it is recommended to use the <file_name> as parameter. Due to backwards compatibility reasons the recording number is still supported but may be removed in future versions.
To use the file name as parameter it could be necessary to url encode the path parts.

http://<ip>:<port>/recordings/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec.<format>

Since Version 0.2.5 it is also possible to request restfulapi to write a sync file in its cache directory. Simply add the <syncId> parameter with a value of of your choice to the url whithin a request to the full recording list. This sync file can be checked against the current recordings or a list of recordings sent by the client.

Future requests to the /recordings/updates service with the same id can fetch a list of new, deleted or updated recordings since the last full or updates request. Don't forget to add the syncId parameter to delete requests aswell. Restfulapi can than delete it from your clients sync list.

Additionally the /recordings/sync service has been added. You can send an array named recordings with each member containing a comma seperated file_name, hash pair. The hash is a new property of each recording that will be added if the full recording list was requested. Restfulapi will then respond with a list of recordings that have been added, deleted or changed

The updates response contains a list of recordings with a <sync_action> property that contains either add, delete or update.
One can use this feature to store the recordings in a client side database and keep it in sync without requesting the full list every time.

GET, DELETE, POST

GET http://<ip>:<port>/recordings/.<format>?syncId=my-client-id GET http://<ip>:<port>/recordings/<file_name|recordingnumber>.<format>?marks=true GET http://<ip>:<port>/recordings/updates.<format>?syncId=my-client-id POST http://<ip>:<port>/recordings/sync.<format>?syncId=my-client-id DELETE http://<ip>:<port>/recordings/<file_name|recordingnumber>?syncId=my-client-id POST http://<ip>:<port>/recordings/move.<format>

- <format> - The requested format: json, xml or html.
- <number> - The number of the recording which you want to delete. (The first recordings has the number 0.)
- <file_name> - The full file system path of the recording. Everything url encoded except slashes (directory seperator)
- <recordingnumber> - The number of the recording you want to retrieve.
- <source> - The full (url encoded) source path of the recording.
- <target> - The relative (url encoded) target path of the recording.
- <syncId> - (optional) client id for sync map file name
- <recordings[]> - <file_name>,<hash> (Form Data)
- marks=true - add the cutting marks by reading the marks file from the recording directory
- start, limit - These values are used to control the whole list. Start ist the first element you want to retrieve. Limit...

GET http://127.0.0.1:8002/recordings.xml?start=0&limit=1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <recordings xmlns="http://www.domain.org/restfulapi/2011/recordings-xml"> <recording> <param name="number">0</param> <param name="name">Asterix in Amerika</param> <param name="filename">/var/lib/video.00/Asterix_in_Amerika/2011-06-19.12.40.1-0.rec</param> <param name="is_new">false</param> <param name="is_edited">false</param> <param name="is_pes_recording">false</param> <param name="duration">-1</param> <param name="frames_per_second">50</param> <param name="marks"><0:03:17.10><1:43:07.24></param> <param name="event_title">Asterix in Amerika</param> <param name="event_short_text"></param> <param name="event_description">(Zeichentrickfilm, DEU 1994)</param> <param name="event_start_time">1308480705</param> <param name="event_duration">4611</param> <param name="sync_action"></param> <param name="hash"></param> </recording> <count>2</count><total>2</total> </recordings>
GET http://127.0.0.1:8002/recordings.json?start=0&limit=1&marks=true { "recordings": [ { "number":0, "name":"Asterix in Amerika", "file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec", "is_new":false, "is_edited":false, "is_pes_recording":false, "duration":-1, "frames_per_second":50, "marks":[ "0:03:17.10", "1:43:07.24" ], "event_title":"Asterix in Amerika", "event_short_text":"", "event_description":"(Zeichentrickfilm, DEU 1994)", "event_start_time":1308480705, "event_duration":4611 "sync_action":"" "hash":"" } ], "count":1, "total":2 }
POST "http://127.0.0.1:8002/recordings/move.json"

- source=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec
- target=relative/path/to/renamed%20recording

GET "http://127.0.0.1:8002/recordings/updates.json"
GET http://127.0.0.1:8002/recordings/updates.json?syncId=a-string-identifying-my-client { "recordings": [ { "number":0, "name":"Asterix in Amerika", "file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec", "is_new":false, "is_edited":false, "is_pes_recording":false, "duration":-1, "frames_per_second":50, "marks":[ "0:03:17.10", "1:43:07.24" ], "event_title":"Asterix in Amerika", "event_short_text":"", "event_description":"(Zeichentrickfilm, DEU 1994)", "event_start_time":1308480705, "event_duration":4611 "sync_action":"add" "hash":"8324fe9b80873947c9d0963d83378232" } ], "count":1, "total":2 }
POST "http://127.0.0.1:8002/recordings/sync.json?syncId=a-string-identifying-my-client"

- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,8324fe9b80873947c9d0963d83378232
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,d4da05b1e99df60d3cd0ef72b6093db3
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,e3f29839c38c74bab63ab02d0dffd6a6
- ⋮
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,46a26b76f5c8c7361d33367dcc86ced0

POST http://127.0.0.1:8002/recordings/updates.json?syncId=a-string-identifying-my-client { "recordings": [ { "number":0, "name":"Asterix in Amerika", "file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec", "is_new":false, "is_edited":false, "is_pes_recording":false, "duration":-1, "frames_per_second":50, "marks":[ "0:03:17.10", "1:43:07.24" ], "event_title":"Asterix in Amerika", "event_short_text":"", "event_description":"(Zeichentrickfilm, DEU 1994)", "event_start_time":1308480705, "event_duration":4611 "sync_action":"add" "hash":"8324fe9b80873947c9d0963d83378232" } ], "count":1, "total":2 }

This service tells your VDR to cut a recording or can tell the client if the vdr cutter is currently cutting a recording:

GET, POST

POST http://<ip>:<port>/recordings/cut/<file_name|recordingnumber> # do it! (cut the recording) GET http://<ip>:<port>/recordings/cut.<format> # this will return the status of the VDR Cutter

This service can save and delete marks. To retrieve them use the parameter "marks=true" in the request url for the recordings.

### Delete Cutting Marks:

DELETE

DELETE http://<ip>:<port>/recordings/marks/<file_name|recordingnumber>

### Create new Cutting Marks:

POST

POST http://<ip>:<port>/recordings/marks/<file_name|recordingnumber>
{ 'marks' : [ '0:02:18.10', '0:34:08.24' ] }

This service tells your VDR to play or rewind a recording:

GET, POST

GET http://<ip>:<port>/recordings/play/<file_name|recordingnumber> POST http://<ip>:<port>/recordings/play/<file_name|recordingnumber>

- <file_name> - (recommended) The full file name of the recording.
- <number> - (deprecated) The number of the recording.

This service retrieves remote commands and sends them to VDR:

POST

POST http://<ip>:<port>/remote/<key> POST http://<ip>:<port>/remote/switch/<channelid> POST http://<ip>:<port>/remote/kbd

- Up, Down, Menu, Ok, Back, Left, Right, Red, Green, Yellow, Blue, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, Info, Play, Pause, Stop, Record, FastFwd, FastRew, Next, Prev, Power, ChanUp, ChanDn, ChanPrev, VolUp, VolDn, Mute, Audio, Subtitles, Schedule, Channels, Timers, Recordings, Setup, Commands, User0, User1, User2, User3, User4, User5, User6, User7, User8, User9, None, Kbd

The second address allows to directly switch to a specific channel.
The third address allows to send strings that are interpreted as keyboard input for e.g. usage in search
The fourth address allows to send to send a sequence of keypresses

### Send keyboard input:

POST

POST http://<ip>:<port>/remote/kbd
{'kbd':'Asterix'}

### Send sequence of keypresses:

POST

POST http://<ip>:<port>/remote/seq
{ 'seq': [ 'Down', 'Down', 'Right' ] }

### Reading/Deleting Timers

This service returns a list of timers.

GET, DELETE

GET http://<ip>:<port>/timers.<format> GET http://<ip>:<port>/timers/<timerid>.<format> GET http://<ip>:<port>/timers.<format>?start=<int>&limit=<int> DELETE http://<ip>:<port>/timers/<timerid>

- <format> - The requested format: json, xml or html.
- <timerid> - Id of the timer if you want to delete one.
- start, limit - These values are used to control the whole list. Start ist the first element you want to retrieve. Limit...

GET http://127.0.0.1:8002/timers.xml?start=0&limit=1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <timers xmlns="http://www.domain.org/restfulapi/2011/timers-xml"> <timer> <param name="id">C-71-71-61920:0:1309039200:2013:2200</param> <param name="start">2013</param> <param name="stop">2200</param> <param name="start_timestamp">2011-12-24 19:00:00</param> <param name="stop_timestamp">2011-12-24 20:00:00</param> <param name="priority">50</param> <param name="lifetime">99</param> <param name="event_id">27312</param> <param name="weekdays">-------</param> <param name="day">2011-06-26</param> <param name="channel">C-71-71-61920</param> <param name="is_recording">false</param> <param name="is_pending">false>/param> <param name="filename">Mad Money>/param> <param name="channel_name">ORF1 HD>/param> <param name="is_active">true>/param> </timer> <count>1</count><total>2</total> </timers>
GET http://127.0.0.1:8002/timers.json?start=0&limit=1 { "timers": [ { "id": "C-61441-10011-50059:0:1432504800:1108:1210", "flags": 1, "start": 1108, "start_timestamp": "2015-05-25 11:08:00", "stop_timestamp": "2015-05-25 12:10:00", "stop": 1210, "priority": 50, "lifetime": 0, "event_id": -1, "weekdays": "-------", "day": "2015-05-25", "channel": "C-61441-10011-50059", "filename": "Serie~Das Universum: Planeten~Mo. 25.05.15 11:10", "channel_name": "n-tv HD", "is_pending": false, "is_recording": false, "is_active": true, "aux": "<epgsearch><channel>17 - n-tv HD</channel><searchtimer>das universum</searchtimer><start>1432544880</start><stop>1432548600</stop><s-id>79</s-id><eventid>5938</eventid></epgsearch>" "index": 1 } ], "count": 1, "total": 20 }

### Bulk delete Timers

Deletes multiple Timers at once

DELETE

DELETE http:/<ip>:<port>/timers/bulkdelete.json
{ "timers" : [ "C-61441-10004-50101:0:1432504800:1923:2025", "C-61441-10013-50001:0:1432504800:2013:2110", "C-61441-10012-50008:0:1432591200:2013:2230" ] }
{ "timers" : [ { "id" : "C-61441-10004-50101:0:1432504800:1923:2025", "deleted" : true }, { "id" : "C-61441-10013-50001:0:1432504800:2013:2110", "deleted" : true }, { "id" : "C-61441-10012-50008:0:1432591200:2013:2230", "deleted" : true } ], "count" : 3, "total" : 3 }

### Creating Timers

This service can create new timers.

POST

POST http:/<ip>:<ip>/timers

- flags - set it to 1 for an active timer
- file - name of the recording (use an url-encoder for this text if you special characters)
- stop - the time when the recording should be start - in the 24 hour system, f.e. 2015 means quarter past ten in the evening
- start - the time when the recording sholud be stoped, f.e. 2230 (half past ten in the evening)
- day - YYYY-MM-DD, f.e. 2011-12-24 -> christmas :-)
- channel - ID of the channel
- weekdays - MTWTFSS, used for repeating timers -> just use '-' if you don't want the timer to run on the specific day
- minpre, minpost can be used together with a channel and eventid to create a timer without giving the other information to the api

POST /timers HTTP/1.1 Content-Length: 98 Connection: close file=Ein%20Film&flags=1&start=1400&stop=1615&day=2011-12-24&channel=C-71-71-61920&weekdays=-------
HTTP/1.1 200 OK Content-Length: 0 Server: cxxtools-Http-Server 2.0 Connection: close Date: Sun, 26 Jun 2011 19:03:48 GMT

### Updating Timers

This service can update the previously created timers.

PUT

PUT http://<ip>:<port>/timers

- timer_id - the id of the timer

Optional Body Parameters are the ones you use to create the timer and now want to update.

PUT /timers HTTP/1.1 Content-Length: 81 Connection: close timer_id=C-71-71-61920:0:1324681200:1400:1615&start=2015&stop=2230
HTTP/1.1 200 OK Content-Length: 0 Server: cxxtools-Http-Server 2.0 Connection: close Date: Sun, 26 Jun 2011 19:20:03 GMT

This Service returns SearchTimers and can create, delete or update them. It's also possible to perform a search.

### Create a SearchTimer

POST

POST http://<ip>:<port>/searchtimers

Name | Type | Required | Value Range / Example
--- | --- | --- | ---
id | int | no |
search | string | yes |
mode | int | yes | 0=phrase, 1=all words, 2=at least one word, 3=match exactly, 4=regex, 5=fuzzy
tolerance | int | if mode == 5 |
match_case | boolean |  |
use_title | boolean | at least one of use_title, use_subtitle, use_description |
use_subtitle | boolean | at least one of use_title, use_subtitle, use_description |
use_description | boolean | at least one of use_title, use_subtitle, use_description |
content_descriptors | string | no | concatted string of content descriptor ids
use_ext_epg_info | boolean | no |
ext_epg_info | array |  | [1#2,2#test]
use_in_favorites | boolean | no |
use_time | boolean | no |
start_time | int | no |
stop_time | int | no |
use_channel | boolean | no | 0=no, 1=interval, 2=channel group, 3=only FTA
channel_min | string | no | channel id
channel_max | string | no | channel id
channels | string | if use_channel > 0 | channel group name
use_duration | boolean | no |
duration_min | int | if use_duration == true |
duration_max | int | if use_duration == true |
use_dayofweek | boolean | no |
dayofweek | int | if use_dayofweek == true | -127 - 6
use_as_searchtimer | int | no | 0=no, 1=yes, 2=user defined
use_as_searchtimer_from | int | if use_as_searchtimer == 2 | unix timestamp
use_as_searchtimer_til | int | no | unix timestamp
search_timer_action | int | no |
use_series_recording | boolean | no |
directory | string | no |
del_recs_after_days | int | no |
keep_recs | int | no |
pause_on_recs | int | no |
blacklist_mode | int | no | 0=global, 1=Selection, 2=all, 3=none
blacklist_ids | array | if blacklist_mode == 1 | array of blacklist ids
switch_min_before | int | no |
avoid_repeats | boolean | no |
allowed_repeats | int | no |
repeats_within_days | int | no |
compare_title | boolean | no |
compare_subtitle | boolean | no |
compare_summary | boolean | no |
compare_categories | int | no |
priority | int | no |
lifetime | int | no |
margin_start | int | no |
margin_stop | int | no |
use_vps | boolean | no |
del_mode | int | no | 0 = no, 1 = recordings count, 2 = days count
del_after_count_recs | int | if del_mode == 1 |
del_after_days_of_first_rec | int | id del_mode == 2 |
ignore_missing_epg_cats | boolean | no |
unmute_sound_on_switch | boolean | no |
summary_match | int | no | 0 - 100, default 90
compare_time | int | no | 0 = no, 1 = same day, 2 = same week, 3 = same month

### Delete a SearchTimer

DELETE

DELETE http://<ip>:<port>/searchtimers/<id>

### Search Events of a SearchTimer

GET

GET http://<ip>:<port>/searchtimers/search/<id>.<format>

### Fetch searchtimer blacklists

GET

GET http://<ip>:<port>/searchtimers/blacklists.<format>

### Fetch searchtimer recording dirs

GET

GET http://<ip>:<port>/searchtimers/recordingdirs.<format>

### Fetch searchtimer channel groups

GET

GET http://<ip>:<port>/searchtimers/channelgroups.<format>

### Fetch searchtimer ext EPG info defined in epgsearchcats.conf

GET

GET http://<ip>:<port>/searchtimers/extepginfo.<format>

### Check timer conflicts

GET

GET http://<ip>:<port>/searchtimers/conflicts.<(json|xml|html)>

Retrieve Images from additional media.

GET

GET http://<ip>:<port>/scraper/image/<path>/<provided>/<within>/<additional>/<media>.jpg
GET http://<ip>:<port>/scraper/image/size/360/240/<path>/<provided>/<within>/<additional/<media>.jpg GET http://<ip>:<port>/scraper/image/width/360/<path>/<provided>/<within>/<additional/<media>.jpg GET http://<ip>:<port>/scraper/image/heigh/240/<path>/<provided>/<within>/<additional/<media>.jpg

### Get the state of the Wirbelscan plugin

This service gets the state of the Wirbelscan plugin.

GET

GET http://<ip>:<port>/wirbelscan/getStatus.json
{ "status":2 }
{ "status":1, "currentDevice":"CXD2837 DVB-C DVB-T/T2", "progress":1,"strength":0, "transponder":"DVB-C 113.000MHz M2 SR6900", "numChannels":552,"newChannels":0,"nextTransponder":0 }

- 0 = no status information available, try again later.
- 1 = scan in progress.
- 2 = no scan in progress (not started, finished or stopped).
- 3 = plugin is busy, try again later.

### Retrieve the list of countries from the Wirbelscan plugin

This service retrieves the list of countries from the Wirbelscan plugin.

GET

GET http://<ip>:<port>/wirbelscan/countries.json
{"countries": [ {"id":0,"shortName":"AF","fullName":"AFGHANISTAN"}, {"id":1,"shortName":"AX","fullName":"\ufffdLAND ISLANDS"}, {"id":2,"shortName":"AL","fullName":"ALBANIA"}, {"id":3,"shortName":"DZ","fullName":"ALGERIA"}, ... {"id":246,"shortName":"ZM","fullName":"ZAMBIA"}, {"id":247,"shortName":"ZW","fullName":"ZIMBABWE"} ], "count":0, "total":248 }

### Retrieve the list of satellites from the Wirbelscan plugin

This service retrieves the list of satellites from the Wirbelscan plugin.

GET

GET http://<ip>:<port>/wirbelscan/satellites.json
{"satellites": [ {"id":0,"shortName":"S180E0","fullName":"180.0 east Intelsat 18"}, {"id":1,"shortName":"S172E0","fullName":"172.0 east GE 23"}, {"id":2,"shortName":"S169E0","fullName":"169.0 east Intelsat 5"}, {"id":3,"shortName":"S166E0","fullName":"166.0 east Intelsat 8"}, ... {"id":131,"shortName":"S139W0","fullName":"135.0 west AMC 8"}, {"id":132,"shortName":"S177W0","fullName":"177.0 west NSS 9"} ], "count":0, "total":133 }

### Retrieve the current setup of the Wirbelscan plugin

This service retrieves the current setup of the Wirbelscan plugin.

GET

GET http://<ip>:<port>/wirbelscan/getSetup.json
{ "verbosity":5, "logFile":2, "DVB_Type":2, "DVBT_Inversion":0, "DVBC_Inversion":0, "DVBC_Symbolrate":0, "DVBC_QAM":0, "CountryId":82, "SatId":6, "scanflags":31, "ATSC_type":0 }

- verbosity - 0 (errors only) .. 5 (extended debug); default = 3 (messages)
- logFile - 0 = off, 1 = stdout, 2 = syslog
- DVB_Type - DVB-T = 0, DVB-C = 1, DVB-S/S2 = 2, PVRINPUT = 3, PVRINPUT(FM Radio) = 4, ATSC = 5, TRANSPONDER = 999
- DVBT_Inversion - AUTO/OFF = 0, AUTO/ON = 1
- DVBC_Inversion - AUTO/OFF = 0, AUTO/ON = 1
- DVBC_Symbolrate - careful here - may change. AUTO = 0, 6900 = 1, 6875 = 2 (...) 14 = 5483, 15 = ALL
- DVBC_QAM - AUTO = 0,QAM64 = 1, QAM128 = 2, QAM256 = 3, ALL = 4
- CountryId - the id according to country, found in country list, see wirbelscan_GetCountry
- SatId - the id according to satellite, found in list, see wirbelscan_GetSat
- scanflags - bitwise flag of TV=1, RADIO=2, FTA=4, SCRAMBLED=8, HDTV=16 (default 31 -> TV + Radio, SD + HDTV, FTA + Scrambled)
- ATSC_type - VSB = 0, QAM = 1, both VSB+QAM = 2

### Changes the current setup of the Wirbelscan plugin

This service changes the current setup of the Wirbelscan plugin and returns the updated setup.

PUT

PUT http://<ip>:<port>/wirbelscan/setSetup.json

For a description of the setup values see Get the current setup

{ "verbosity": 3, "logFile": 1, "DVB_Type": 3, "DVBT_Inversion": 0, "DVBC_Inversion": 0, "DVBC_Symbolrate": 0, "DVBC_QAM": 0, "CountryId": 82, "SatId": 67, "scanflags": 31, "ATSC_type": 0 }

### Launch a command with the Wirbelscan plugin

This service launches a command with the Wirbelscan plugin.

POST

POST http://<ip>:<port>/wirbelscan/doCommand.json

- command

- 0 = start scanning
- 1 = stop scanning
- 2 = store current setup

{ "replycode":true }

This service can deliver files from configured folders. Multiple webapps can be defined within config file. Seperate paths with a comma. Specified paths must exist for the service to be initialized.

Known file types are defined in <plugin_conf_dir>/webapp_file_types.conf

GET

GET http://<ip>:<port>/<webapp>/<path>/<to>/<file>

Specify folder in plugin settings file (--webapp=/var/lib/vdr/plugins/restfulapi/webapp,/var/lib/vdr/plugins/restfulapi/a-second-webapp)

Retrieve Femon data

GET

GET http://<ip>:<port>/femon.json
/** * @typedef {{}} recordingData * @property {number} number * @property {string} name * @property {string} file_name * @property {string} relative_file_name * @property {string} inode * @property {boolean} is_new * @property {boolean} is_edited * @property {boolean} is_pes_recording * @property {number} duration * @property {number} filesize_mb * @property {string} channel_id * @property {number} frames_per_second * @property {Array.<string>} marks * @property {string} event_title * @property {string} event_short_text * @property {string} event_description * @property {number} event_start_time * @property {number} event_duration * @property {additionalMediaMovie|additionalMediaEpisode} additional_media * @property {string} sync_action */
/** * @typedef {{}} broadcastData * @property {string} channel * @property {string} channel_name * @property {Array.<component>} components * @property {Array} contents * @property {string} description * @property {Array} details * @property {Number} duration * @property {Number} id * @property {Number} images * @property {Number} parental_rating * @property {Array} raw_contents * @property {string} short_text * @property {Number} table_id * @property {boolean} timer_active * @property {boolean} timer_exists * @property {Number} timer_id * @property {string} title * @property {Number} version * @property {Number} vps * @property {Number} start_time * @property {Number} end_time * @property {Date} start_date * @property {Date} end_date */
/** * @typedef {{}} component * @property {String} description * @property {String} language * @property {Number} stream * @property {Number} type */
/** * @typedef {{}} actor * @property {String} name * @property {String} role * @property {String} thumb */
/** * @typedef {{}} banners * @property {Number} width * @property {Number} height * @property {String} path */
/** * @typedef {{}} fanarts * @property {Number} width * @property {Number} height * @property {String} path */
/** * @typedef {{}} posters * @property {Number} width * @property {Number} height * @property {String} path */
/** * @typedef {{}} additionalMediaMovie * @property {Array.<actor>} actors * @property {Boolean} adult * @property {String} collection_fanart * @property {String} collection_name * @property {String} collection_poster * @property {String} fanart * @property {String} genres * @property {String} homepage * @property {Number} movie_id * @property {String} original_title * @property {String} overview * @property {Number} popularity * @property {String} poster * @property {String} release_date * @property {Number} revenue * @property {Number} runtime * @property {String} tagline * @property {String} title * @property {String} type * @property {Number} vote_average */
/** * @typedef {{}} additionalMediaEpisode * @property {Array.<banners>} banners * @property {String} episode_first_aired * @property {String} episode_guest_stars * @property {Number} episode_id * @property {String} episode_image * @property {String} episode_name * @property {Number} episode_number * @property {String} episode_overview * @property {Number} episode_rating * @property {Number} episode_season * @property {Array.<fanarts>} fanarts * @property {String} first_aired * @property {String} genre * @property {String} name * @property {String} network * @property {String} overview * @property {Array.<posters>} posters * @property {Number} rating * @property {Number} series_id * @property {String} status * @property {String} type */
/** * @typedef {{}} infoData * @property {infoDiskUsage} diskusage * @property {infoService[]} services * @property {number} time * @property {infoVDR} vdr * @property {string} version * */
/** * @typedef {{}} infoVDR * @property {infoPlugin[]} plugins * @property {infoDevice[]} devices */
/** * @typedef {{}} infoDevice * @property {number} adapter * @property {boolean} atsc * @property {string} channel_id * @property {string} channel_name * @property {number} channel_nr * @property {boolean} dvb_c * @property {boolean} dvb_s * @property {boolean} dvb_t * @property {number} frontend * @property {boolean} has_ci * @property {boolean} has_decoder * @property {boolean} live * @property {string} name * @property {number} number * @property {boolean} primary * @property {number} signal_quality * @property {number} signal_strength * @property {number} snr * @property {number} str * @property {number} ber * @property {number} unc * @property {string} status * @property {string} type */
/** * @typedef {{}} infoPlugin * @property {string} name * @property {string} version */
/** * @typedef {{}} infoService * @property {string} name * @property {number} version */
/** * @typedef {{}} infoDiskUsage * @property {string} description_localized * @property {number} free_mb * @property {number} free_minutes * @property {number} used_percent */
/** * @typedef {{}} conflictResult * @property {number} count * @property {number} total * @property {Array.<timerConflict|string>} conflicts * @property {boolean} check_advised */
/** * @typedef {{}} searchTimerData * @property {number} id * @property {string} search * @property {number} mode * @property {number} tolerance * @property {boolean} match_case * @property {boolean} use_title * @property {boolean} use_subtitle * @property {boolean} use_description * @property {string} content_descriptors * @property {boolean} use_ext_epg_info * @property {Array.<string>} ext_epg_info * @property {boolean} use_in_favorites * @property {boolean} use_time * @property {number} start_time * @property {number} stop_time * @property {number} use_channel * @property {string} channel_min * @property {string} channel_max * @property {string} channels * @property {boolean} use_duration * @property {number} duration_min * @property {number} duration_max * @property {boolean} use_dayofweek * @property {number} dayofweek * @property {number} use_as_searchtimer * @property {number} use_as_searchtimer_from * @property {number} use_as_searchtimer_til * @property {number} searchtimer_action * @property {boolean} use_series_recording * @property {string} directory * @property {number} del_recs_after_days * @property {number} keep_recs * @property {number} pause_on_recs * @property {number} blacklist_mode * @property {Array.<number>} blacklist_ids * @property {number} switch_min_before * @property {boolean} avoid_repeats * @property {number} allowed_repeats * @property {number} repeats_within_days * @property {boolean} compare_title * @property {number} compare_subtitle * @property {boolean} compare_summary * @property {number} compare_categories * @property {number} priority * @property {number} lifetime * @property {number} margin_start * @property {number} margin_stop * @property {boolean} use_vps * @property {number} del_mode * @property {number} del_after_count_recs * @property {number} del_after_days_of_first_rec * @property {boolean} ignore_missing_epg_cats * @property {boolean} unmute_sound_on_switch * @property {number} summary_match * @property {number} compare_time */
/** * @typedef {{}} timerData * @property {number} event_id * @property {number} flags * @property {number} index * @property {number} lifetime * @property {number} priority * @property {number} start * @property {number} stop * @property {boolean} is_active * @property {boolean} is_pending * @property {boolean} is_recording * @property {string} aux * @property {string} channel * @property {string} day * @property {string} filename * @property {string} id * @property {string} start_timestamp * @property {string} stop_timestamp * @property {string} weekdays * @property {string} channel_name */