70_MEDIAPORTAL.pm 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. #################################################
  2. #
  3. # 70_MEDIAPORTAL.pm
  4. # Connects to a running MediaPortal instance via the WifiRemote plugin
  5. #
  6. # $Id: 70_MEDIAPORTAL.pm 11067 2016-03-14 20:57:40Z rleins $
  7. #
  8. # Changed, adopted and new copyrighted by Reiner Leins (Reinerlein), (c) in February 2016
  9. # Original Copyright by Andreas Kwasnik (gemx)
  10. #
  11. # Fhem is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation, either version 2 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # Fhem is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with fhem. If not, see <http://www.gnu.org/licenses/>.
  23. #
  24. ########################################################################################
  25. # Changelog
  26. # 14.03.2016
  27. # Es gibt nun ein Attribut "HeartbeatInterval", mit dem das Intervall für die Verbindungsprüfung festgelegt werden kann. Ein Wert von "0" deaktiviert die Prüfung.
  28. # Es gibt nun das Attribut "disable", mit dem das Modul deaktiviert werden kann.
  29. # 08.02.2016
  30. # Neuer MediaType "recording" hinzugefügt
  31. # 07.02.2016
  32. # In das offizielle Fhem-Release übernommen
  33. # Allgemein im Code aufgeräumt
  34. # Dokumentation hinzugefügt
  35. # Umlautproblem bei der Titelanzeige behoben
  36. # Mehr Readings befüllt, die sowieso geliefert werden. Dazu gehören z.B. Titelinformationen bei TV, Beschreibungen und die Informationen über den nächsten Titel.
  37. # $readingsFnAttributes hinzugefügt. Damit geht z.B. stateFormat oder event-on-change-reading
  38. # Fehlende Titelanzeige bei initialem Start der Wiedergabe behoben
  39. # WakeUp und Sleep hinzugefügt, damit man schnell den entsprechenden Mediaportal-Rechner hochfahren bzw. in den Hibernate-Modus schalten kann. Dazu wurde ein Attribut "macaddress" eingeführt.
  40. # Mögliche Parameter für Get und Set angegeben, sodass diese in FhemWeb entsprechend angeboten werden.
  41. # Volume umbenannt, damit das Reading die Grundlage für die Lautstärkeauswahl (Slider) ist.
  42. # Es gibt jetzt ein Attribut "generateNowPlayingUpdateEvents", mit dem man die Generierung von (bei der Wiedergabe) sekündlichen Aktualisierungen an-/abschalten kann
  43. # Die Mac-Adresse, die für das Aufwecken benötigt wird, wird nun automatisch ermittelt.
  44. # Die Read-Callbackfunktion wurde überarbeitet, da in einigen Fällen halbe Nachrichten zu einem Freeze geführt hatten.
  45. # Es gibt jetzt einen Setter "reconnect", der eine neue Verbindung zu Mediaportal aufbaut.
  46. # Wenn festgestellt wird, dass eine Verbindung zu Mediaportal nicht mehr lebendig ist, wird ein reconnect ausgeführt.
  47. #
  48. ##############################################################################
  49. package main;
  50. use strict;
  51. use warnings;
  52. use Time::HiRes qw(gettimeofday);
  53. use DevIo;
  54. use JSON;
  55. use HttpUtils;
  56. use Data::Dumper;
  57. # Forward-Declarations
  58. sub MEDIAPORTAL_Set($@);
  59. sub MEDIAPORTAL_Log($$$);
  60. my $MEDIAPORTAL_HeartbeatInterval = 15;
  61. ########################################################################################
  62. #
  63. # MEDIAPORTAL_Initialize
  64. #
  65. ########################################################################################
  66. sub MEDIAPORTAL_Initialize($) {
  67. my ($hash) = @_;
  68. require "$attr{global}{modpath}/FHEM/DevIo.pm";
  69. $hash->{ReadFn} = 'MEDIAPORTAL_Read';
  70. $hash->{ReadyFn} = 'MEDIAPORTAL_Ready';
  71. $hash->{GetFn} = 'MEDIAPORTAL_Get';
  72. $hash->{SetFn} = 'MEDIAPORTAL_Set';
  73. $hash->{DefFn} = 'MEDIAPORTAL_Define';
  74. $hash->{UndefFn} = 'MEDIAPORTAL_Undef';
  75. $hash->{AttrFn} = 'MEDIAPORTAL_Attribute';
  76. $hash->{AttrList} = 'authmethod:none,userpassword,passcode,both username password HeartbeatInterval generateNowPlayingUpdateEvents:1,0 macaddress '.$readingFnAttributes;
  77. $hash->{STATE} = 'Initialized';
  78. }
  79. ########################################################################################
  80. #
  81. # MEDIAPORTAL_Define
  82. #
  83. ########################################################################################
  84. sub MEDIAPORTAL_Define($$) {
  85. my ($hash, $def) = @_;
  86. my @a = split("[ \t][ \t]*", $def);
  87. if(@a != 3) {
  88. my $msg = 'wrong syntax: define <name> MEDIAPORTAL ip[:port]';
  89. MEDIAPORTAL_Log $hash->{NAME}, 2, $msg;
  90. return $msg;
  91. }
  92. DevIo_CloseDev($hash);
  93. my $name = $a[0];
  94. my $dev = $a[2];
  95. $dev .= ":8017" if ($dev !~ m/:/ && $dev ne "none" && $dev !~ m/\@/);
  96. $hash->{DeviceName} = $dev;
  97. $hash->{STATE} = 'Disconnected';
  98. my $ret = undef;
  99. $ret = DevIo_OpenDev($hash, 0, 'MEDIAPORTAL_DoInit') if AttrVal($hash->{NAME}, 'disable', 0);
  100. return $ret;
  101. }
  102. ########################################################################################
  103. #
  104. # MEDIAPORTAL_Undef
  105. #
  106. ########################################################################################
  107. sub MEDIAPORTAL_Undef($$) {
  108. my ($hash, $arg) = @_;
  109. RemoveInternalTimer($hash);
  110. DevIo_CloseDev($hash);
  111. return undef;
  112. }
  113. ########################################################################################
  114. #
  115. # MEDIAPORTAL_Attribute
  116. #
  117. ########################################################################################
  118. sub MEDIAPORTAL_Attribute($@) {
  119. my ($mode, $devName, $attrName, $attrValue) = @_;
  120. my $hash = $defs{$devName};
  121. my $disableChange = 0;
  122. if($mode eq 'set') {
  123. if ($attrName eq 'disable') {
  124. if ($attrValue && AttrVal($devName, $attrName, 0) != 1) {
  125. MEDIAPORTAL_Log($devName, 5, 'Neu-Disabled');
  126. $disableChange = 1;
  127. }
  128. if (!$attrValue && AttrVal($devName, $attrName, 0) != 0) {
  129. MEDIAPORTAL_Log($devName, 5, 'Neu-Enabled');
  130. $disableChange = 1;
  131. }
  132. }
  133. } elsif ($mode eq 'del') {
  134. if ($attrName eq 'disable') {
  135. if (AttrVal($devName, $attrName, 0) != 0) {
  136. MEDIAPORTAL_Log($devName, 5, 'Deleted-Disabled');
  137. $disableChange = 1;
  138. $attrValue = 0;
  139. }
  140. }
  141. }
  142. if ($disableChange) {
  143. # Wenn die Verbindung beendet werden muss...
  144. if ($attrValue) {
  145. MEDIAPORTAL_Log $devName, 5, 'Call AttributeFn: Stop Connection...';
  146. DevIo_CloseDev($hash);
  147. }
  148. # Wenn die Verbindung gestartet werden muss...
  149. if (!$attrValue) {
  150. MEDIAPORTAL_Log $devName, 5, 'Call AttributeFn: Start Connection...';
  151. DevIo_OpenDev($hash, 0, 'MEDIAPORTAL_DoInit');
  152. }
  153. }
  154. return undef;
  155. }
  156. ########################################################################################
  157. #
  158. # MEDIAPORTAL_DoInit
  159. #
  160. ########################################################################################
  161. sub MEDIAPORTAL_DoInit($) {
  162. my ($hash) = @_;
  163. $hash->{STATE} = 'Connecting...';
  164. $hash->{helper}{buffer} = '';
  165. $hash->{helper}{LastStatusTimestamp} = time();
  166. # Versuch, die MAC-Adresse des Ziels selber herauszufinden...
  167. if (AttrVal($hash->{NAME}, 'macaddress', '') eq '') {
  168. my $newmac = MEDIAPORTAL_GetMAC($hash);
  169. if (defined($newmac)) {
  170. CommandAttr(undef, $hash->{NAME}.' macaddress '.$newmac);
  171. }
  172. }
  173. RemoveInternalTimer($hash);
  174. InternalTimer(gettimeofday() + AttrVal($hash->{NAME}, 'HeartbeatInterval', $MEDIAPORTAL_HeartbeatInterval), 'MEDIAPORTAL_GetIntervalStatus', $hash, 0) if AttrVal($hash->{NAME}, 'HeartbeatInterval', $MEDIAPORTAL_HeartbeatInterval);
  175. return undef;
  176. }
  177. ########################################################################################
  178. #
  179. # MEDIAPORTAL_Ready
  180. #
  181. ########################################################################################
  182. sub MEDIAPORTAL_Ready($) {
  183. my ($hash) = @_;
  184. return DevIo_OpenDev($hash, 1, 'MEDIAPORTAL_DoInit');
  185. }
  186. ########################################################################################
  187. #
  188. # MEDIAPORTAL_Get
  189. #
  190. ########################################################################################
  191. sub MEDIAPORTAL_Get($@) {
  192. my ($hash, @a) = @_;
  193. my $cname = $a[1];
  194. my $cmd = '';
  195. return 'Module disabled!' if AttrVal($hash->{NAME}, 'disable', 0);
  196. if ($cname eq "status") {
  197. $cmd = "{\"Type\":\"requeststatus\"}\r\n";
  198. } elsif ($cname eq "nowplaying") {
  199. $cmd = "{\"Type\":\"requestnowplaying\"}\r\n";
  200. } elsif ($cname eq "notify") {
  201. $cmd = '{"Type":"properties","Properties":["#Play.Current.Title","#TV.View.title"]}'."\r\n";
  202. } else {
  203. return "Unknown command '$cname', choose one of status:noArg nowplaying:noArg";
  204. }
  205. DevIo_SimpleWrite($hash, $cmd, 0);
  206. return undef;
  207. }
  208. ########################################################################################
  209. #
  210. # MEDIAPORTAL_GetStatus
  211. #
  212. ########################################################################################
  213. sub MEDIAPORTAL_GetStatus($) {
  214. my ($hash) = @_;
  215. MEDIAPORTAL_Get($hash, ($hash->{NAME}, 'status'));
  216. }
  217. ########################################################################################
  218. #
  219. # MEDIAPORTAL_GetIntervalStatus
  220. #
  221. ########################################################################################
  222. sub MEDIAPORTAL_GetIntervalStatus($) {
  223. my ($hash) = @_;
  224. return undef if (ReadingsVal($hash->{NAME}, 'state', 'disconnected') eq 'disconnected');
  225. return undef if (!AttrVal($hash->{NAME}, 'HeartbeatInterval', $MEDIAPORTAL_HeartbeatInterval));
  226. # Prüfen, wann der letzte Status zugestellt wurde...
  227. if (time() - $hash->{helper}{LastStatusTimestamp} > (2 * $MEDIAPORTAL_HeartbeatInterval + 5)) {
  228. MEDIAPORTAL_Log $hash->{NAME}, 3, 'GetIntervalStatus hat festgestellt, dass Mediaportal sich seit '.(time() - $hash->{helper}{LastStatusTimestamp}).'s nicht zurückgemeldet hat. Die Verbindung wird neu aufgebaut!';
  229. MEDIAPORTAL_Set($hash, ($hash->{NAME}, 'reconnect'));
  230. InternalTimer(gettimeofday() + AttrVal($hash->{NAME}, 'HeartbeatInterval', $MEDIAPORTAL_HeartbeatInterval), 'MEDIAPORTAL_GetIntervalStatus', $hash, 0);
  231. return undef;
  232. }
  233. # Status anfordern...
  234. MEDIAPORTAL_Get($hash, ($hash->{NAME}, 'status'));
  235. InternalTimer(gettimeofday() + AttrVal($hash->{NAME}, 'HeartbeatInterval', $MEDIAPORTAL_HeartbeatInterval), 'MEDIAPORTAL_GetIntervalStatus', $hash, 0);
  236. }
  237. ########################################################################################
  238. #
  239. # MEDIAPORTAL_GetNowPlaying
  240. #
  241. ########################################################################################
  242. sub MEDIAPORTAL_GetNowPlaying($) {
  243. my ($hash) = @_;
  244. MEDIAPORTAL_Get($hash, ($hash->{NAME}, 'nowplaying'));
  245. }
  246. ########################################################################################
  247. #
  248. # MEDIAPORTAL_Set
  249. #
  250. ########################################################################################
  251. sub MEDIAPORTAL_Set($@) {
  252. my ($hash, @a) = @_;
  253. my $cname = $a[1];
  254. my $cmd = '';
  255. my $powermodes = 'logoff suspend hibernate reboot shutdown exit';
  256. my $mpcommands = 'stop record pause play rewind forward replay skip back info menu up down left right ok volup voldown volmute chup chdown dvdmenu 0 1 2 3 4 5 6 7 8 9 0 clear enter teletext red blue yellow green home basichome nowplaying tvguide tvrecs dvd playlists first last fullscreen subtitles audiotrack screenshot';
  257. my $playlistcommands = 'play loadlist loadlist_shuffle loadfrompath loadfrompath_shuffle';
  258. # Legacy Volume writing...
  259. $cname = 'Volume' if (lc($cname) eq 'volume');
  260. return 'Module disabled!' if AttrVal($hash->{NAME}, 'disable', 0);
  261. if ($cname eq "command") {
  262. if (!MEDIAPORTAL_isInList($a[2], split(/ /, $mpcommands))) {
  263. return "Unknown command '$a[2]'. Supported commands are: $mpcommands";
  264. }
  265. $cmd = "{\"Type\":\"command\",\"Command\":\"$a[2]\"}\r\n";
  266. } elsif ($cname eq "wakeup") {
  267. my $macaddress = AttrVal($hash->{NAME}, 'macaddress', '');
  268. if ($macaddress ne '') {
  269. MEDIAPORTAL_Wakeup($macaddress);
  270. return 'WakeUp-Signal sent!';
  271. } else {
  272. return 'No MacAddress set! No WakeUp-Signal sent!';
  273. }
  274. } elsif ($cname eq "sleep") {
  275. return MEDIAPORTAL_Set($hash, ($hash->{NAME}, 'powermode', 'hibernate'));
  276. } elsif ($cname eq "key") {
  277. $cmd = "{\"Type\":\"key\",\"Key\":\"$a[2]\"}\r\n";
  278. } elsif ($cname eq "Volume") {
  279. if (($a[2] ne $a[2]+0) || ($a[2]<0) || ($a[2]>100)) {
  280. return "the volume must be in the range 0..100";
  281. }
  282. $cmd = "{\"Type\":\"volume\",\"Volume\":$a[2]}\r\n";
  283. } elsif ($cname eq "powermode") {
  284. if (!MEDIAPORTAL_isInList($a[2], split(/ /, $powermodes))) {
  285. return "Unknown powermode '$a[2]'. Supported powermodes are: $powermodes";
  286. }
  287. $cmd = "{\"Type\":\"powermode\",\"PowerMode\":\"$a[2]\"}\r\n";
  288. } elsif ($cname eq "playfile") {
  289. $cmd = "{\"Type\":\"playfile\",\"FileType\":\"$a[2]\",\"Filepath\":\"$a[3]\"}\r\n";
  290. } elsif ($cname eq "playchannel") {
  291. if ($a[2] ne $a[2]+0) {
  292. return "playchannel needs a valid channelid of type int";
  293. }
  294. $cmd = "{\"Type\":\"playchannel\",\"ChannelId\":$a[2]}\r\n";
  295. } elsif ($cname eq "playradiochannel") {
  296. if ($a[2] ne $a[2]+0) {
  297. return "playradiochannel needs a valid channelid of type int";
  298. }
  299. $cmd = "{\"Type\":\"playradiochannel\",\"ChannelId\":$a[2]}\r\n";
  300. } elsif ($cname eq "playlist") {
  301. if (!MEDIAPORTAL_isInList($a[2], split(/ /, $playlistcommands))) {
  302. return "Unknown playlist command '$a[2]'. Supported commands are: $playlistcommands";
  303. }
  304. if ($a[2] eq "play") {
  305. if ($a[3] ne $a[3]+0) {
  306. return "playlist play needs a valid index to start of type int";
  307. }
  308. $cmd = "{\"Type\":\"playlist\",\"PlaylistAction\":\"play\",\"Index\":$a[3]}\r\n";
  309. } elsif ($a[2] eq "loadlist") {
  310. $cmd = "{\"Type\":\"playlist\",\"PlaylistAction\":\"load\",\"PlaylistName\":\"$a[3]\"}\r\n";
  311. } elsif ($a[2] eq "loadlist_shuffle") {
  312. $cmd = "{\"Type\":\"playlist\",\"PlaylistAction\":\"load\",\"PlaylistName\":\"$a[3]\",\"Shuffle\":true}\r\n";
  313. } elsif ($a[2] eq "loadfrompath") {
  314. $cmd = "{\"Type\":\"playlist\",\"PlaylistAction\":\"load\",\"PlaylistPath\":\"$a[3]\"}\r\n";
  315. } elsif ($a[2] eq "loadfrompath_shuffle") {
  316. $cmd = "{\"Type\":\"playlist\",\"PlaylistAction\":\"load\",\"PlaylistPath\":\"$a[3]\",\"Shuffle\":true}\r\n";
  317. }
  318. } elsif ($cname eq "connect") {
  319. $hash->{NEXT_OPEN} = 0; # force NEXT_OPEN used in DevIO
  320. return undef;
  321. } elsif ($cname eq "reconnect") {
  322. DevIo_CloseDev($hash);
  323. select(undef, undef, undef, 0.2);
  324. DevIo_OpenDev($hash, 0, 'MEDIAPORTAL_DoInit');
  325. return undef;
  326. } else {
  327. return "Unknown command '$cname', choose one of wakeup:noArg sleep:noArg connect:noArg reconnect:noArg command:".join(',', split(/ /, $mpcommands))." key Volume:slider,0,1,100 powermode:".join(',', split(/ /, $powermodes))." playfile playchannel playradiochannel playlist";
  328. }
  329. DevIo_SimpleWrite($hash, $cmd, 0);
  330. return undef;
  331. }
  332. ########################################################################################
  333. #
  334. # MEDIAPORTAL_Read
  335. # Receives an event and creates several readings for event triggering
  336. #
  337. ########################################################################################
  338. sub MEDIAPORTAL_Read($) {
  339. my ($hash) = @_;
  340. my $buf = DevIo_SimpleRead($hash);
  341. if(!defined($buf)) {
  342. MEDIAPORTAL_Log $hash->{NAME}, 3, 'DevIo_SimpleRead hat keine Daten geliefert, obwohl Read aufgerufen wurde! Setze Buffer zurück. Aktueller Buffer: '.$hash->{helper}{buffer};
  343. $hash->{helper}{buffer} = '';
  344. return undef;
  345. }
  346. return undef if AttrVal($hash->{NAME}, 'disable', 0);
  347. MEDIAPORTAL_Log $hash->{NAME}, 5, "RAW MSG: $buf";
  348. # Zum Buffer hinzufügen
  349. $hash->{helper}{buffer} .= $buf;
  350. # Bereits vollständige JSON-Strings verarbeiten...
  351. my @groups = $hash->{helper}{buffer} =~ m/({(?:[^{}]++|(?1))*})/xg;
  352. for my $elem (@groups) {
  353. MEDIAPORTAL_ProcessMessage($hash, $elem);
  354. }
  355. # Bereits verarbeitetes aus dem Buffer wieder entfernen...
  356. $hash->{helper}{buffer} =~ s/[ \r\n]*({(?:[^{}]++|(?1))*})[ \r\n]*//xg;
  357. return undef;
  358. }
  359. ########################################################################################
  360. #
  361. # MEDIAPORTAL_ProcessMessage
  362. #
  363. ########################################################################################
  364. sub MEDIAPORTAL_ProcessMessage($$) {
  365. my ($hash, $msg) = @_;
  366. MEDIAPORTAL_Log $hash->{NAME}, 5, "Message received: $msg";
  367. my $json = {};
  368. eval {
  369. $json = from_json($msg);
  370. };
  371. if ($@) {
  372. MEDIAPORTAL_Log $hash->{NAME}, 5, "Error during JSON-Parser with 'from_json()'-call (but just keep trying another way): $@";
  373. eval {
  374. $json = decode_json(decode('iso8859-1', $msg));
  375. };
  376. if ($@) {
  377. MEDIAPORTAL_Log $hash->{NAME}, 1, "Final Error during JSON-Parser: $@";
  378. return;
  379. }
  380. }
  381. if (defined($json->{Type})) {
  382. if ($json->{Type} eq "welcome") {
  383. MEDIAPORTAL_Log $hash->{NAME}, 4, 'WELCOME received. Sending identify message.';
  384. DevIo_SimpleWrite($hash, MEDIAPORTAL_GetMSG_identify($hash), 0);
  385. } elsif ($json->{Type} eq "authenticationresponse") {
  386. MEDIAPORTAL_Log $hash->{NAME}, 4, "AUTHRESPONSE received. SUCCESS=$json->{Success}";
  387. $hash->{STATE} = "Authenticated. Processing messages.";
  388. } elsif ($json->{Type} eq "status") {
  389. MEDIAPORTAL_Log $hash->{NAME}, 4, 'STATUS received.';
  390. my $playStatus = 'Stopped';
  391. $playStatus = 'Playing' if ($json->{IsPlaying});
  392. $playStatus = 'Paused' if ($json->{IsPaused});
  393. my $title = '';
  394. $title = $json->{Title} if (defined($json->{Title}) && $json->{Title});
  395. if (defined($json->{SelectedItem}) && $json->{SelectedItem} ne '' && $title eq '') {
  396. $title = 'Auswahl: '.$json->{SelectedItem};
  397. # Wenn der Titel während des Abspielens nicht mitgeliefert wurde, dann für später nochmal anfordern...
  398. # Das ist ein Bug in Wifiremote, das den Titel beim Start nicht immer mitliefert.
  399. if ($json->{IsPlaying}) {
  400. InternalTimer(gettimeofday() + 5, 'MEDIAPORTAL_GetNowPlaying', $hash, 0);
  401. }
  402. }
  403. readingsBeginUpdate($hash);
  404. readingsBulkUpdate($hash, 'IsPlaying', $json->{IsPlaying});
  405. readingsBulkUpdate($hash, 'IsPaused', $json->{IsPaused});
  406. readingsBulkUpdate($hash, 'playStatus', $playStatus);
  407. readingsBulkUpdate($hash, 'CurrentModule', $json->{CurrentModule});
  408. readingsBulkUpdate($hash, 'Title', $title);
  409. readingsEndUpdate($hash, 1);
  410. $hash->{helper}{LastStatusTitle} = $title;
  411. $hash->{helper}{LastStatusTimestamp} = time();
  412. } elsif ($json->{Type} eq "volume") {
  413. MEDIAPORTAL_Log $hash->{NAME}, 4, 'VOLUME received.';
  414. readingsBeginUpdate($hash);
  415. readingsBulkUpdate($hash, 'Volume', $json->{Volume});
  416. readingsBulkUpdate($hash, 'IsMuted', $json->{IsMuted});
  417. readingsEndUpdate($hash, 1);
  418. } elsif ($json->{Type} eq "nowplaying") {
  419. MEDIAPORTAL_Log $hash->{NAME}, 4, 'NOWPLAYING received.';
  420. readingsBeginUpdate($hash);
  421. readingsBulkUpdate($hash, 'Duration', MEDIAPORTAL_ConvertSecondsToTime($json->{Duration}));
  422. readingsBulkUpdate($hash, 'Position', MEDIAPORTAL_ConvertSecondsToTime($json->{Position}));
  423. readingsBulkUpdate($hash, 'File', $json->{File});
  424. readingsBulkUpdate($hash, 'Title', '');
  425. readingsBulkUpdate($hash, 'Description', '');
  426. readingsBulkUpdate($hash, 'nextTitle', '');
  427. readingsBulkUpdate($hash, 'nextDescription', '');
  428. if (defined($json->{MediaInfo})) {
  429. if ($json->{MediaInfo}{MediaType} eq 'tv') {
  430. readingsBulkUpdate($hash, 'Title', $json->{MediaInfo}{ChannelName}.' - '.$json->{MediaInfo}{CurrentProgramName});
  431. readingsBulkUpdate($hash, 'Description', $json->{MediaInfo}{CurrentProgramDescription});
  432. if (defined($json->{MediaInfo}{NextProgramName})) {
  433. readingsBulkUpdate($hash, 'nextTitle', $json->{MediaInfo}{ChannelName}.' - '.$json->{MediaInfo}{NextProgramName});
  434. readingsBulkUpdate($hash, 'nextDescription', $json->{MediaInfo}{NextProgramDescription});
  435. }
  436. } elsif ($json->{MediaInfo}{MediaType} eq 'movie') {
  437. readingsBulkUpdate($hash, 'Title', $json->{MediaInfo}{Title});
  438. readingsBulkUpdate($hash, 'Description', $json->{MediaInfo}{Summary});
  439. } elsif ($json->{MediaInfo}{MediaType} eq 'series') {
  440. readingsBulkUpdate($hash, 'Title', $json->{MediaInfo}{Series}.' '.$json->{MediaInfo}{Season}.'x'.$json->{MediaInfo}{Episode}.' - '.$json->{MediaInfo}{Title});
  441. readingsBulkUpdate($hash, 'Description', $json->{MediaInfo}{Plot});
  442. } elsif ($json->{MediaInfo}{MediaType} eq 'recording') {
  443. readingsBulkUpdate($hash, 'Title', $json->{MediaInfo}{ChannelName}.' - '.$json->{MediaInfo}{ProgramName});
  444. readingsBulkUpdate($hash, 'Description', $json->{MediaInfo}{ProgramDescription});
  445. } else {
  446. MEDIAPORTAL_Log $hash->{NAME}, 0, 'Unbekannte MediaInfo für "'.$json->{MediaInfo}{MediaType}.'" geliefert, aber nicht verarbeitet. Bitte diese komplette Information ins Forum einstellen: '.Dumper($json->{MediaInfo});
  447. }
  448. } else {
  449. # Die MediaInfos wurden nicht mitgeliefert...
  450. # Hier nochmal versuchen, den Titel zu extrahieren...
  451. my $title = '';
  452. $title = $json->{Title} if (defined($json->{Title}) && $json->{Title});
  453. if ($title eq '') {
  454. readingsBulkUpdate($hash, 'Title', $hash->{helper}{LastStatusTitle});
  455. } else {
  456. readingsBulkUpdate($hash, 'Title', $title);
  457. }
  458. }
  459. readingsEndUpdate($hash, 1);
  460. } elsif ($json->{Type} eq "nowplayingupdate") {
  461. MEDIAPORTAL_Log $hash->{NAME}, 4, 'NOWPLAYINGUPDATE received.';
  462. readingsBeginUpdate($hash);
  463. readingsBulkUpdate($hash, 'Duration', MEDIAPORTAL_ConvertSecondsToTime($json->{Duration}));
  464. readingsBulkUpdate($hash, 'Position', MEDIAPORTAL_ConvertSecondsToTime($json->{Position}));
  465. readingsEndUpdate($hash, AttrVal($hash->{NAME}, 'generateNowPlayingUpdateEvents', 0));
  466. } elsif ($json->{Type} eq "properties") {
  467. MEDIAPORTAL_Log $hash->{NAME}, 4, 'PROPERTIES received.';
  468. MEDIAPORTAL_Log undef, 4, 'JSON: '.Dumper($json);
  469. } elsif ($json->{Type} eq "facadeinfo") {
  470. MEDIAPORTAL_Log $hash->{NAME}, 4, 'FACADEINFO5 received.';
  471. } elsif ($json->{Type} eq "dialog") {
  472. MEDIAPORTAL_Log $hash->{NAME}, 4, 'DIALOG received.';
  473. } else {
  474. MEDIAPORTAL_Log $hash->{NAME}, 1, "Unhandled message received: MessageType '$json->{Type}'";
  475. }
  476. } else {
  477. MEDIAPORTAL_Log $hash->{NAME}, 1, 'Unhandled message received without any Messagetype: '.$msg;
  478. }
  479. }
  480. ########################################################################################
  481. #
  482. # MEDIAPORTAL_GetMSG_identify
  483. #
  484. ########################################################################################
  485. sub MEDIAPORTAL_GetMSG_identify($) {
  486. my ($hash) = @_;
  487. my $authmethod=AttrVal($hash->{NAME}, 'authmethod', 'none');
  488. my $uid = AttrVal($hash->{NAME}, 'username', '');
  489. my $pwd = AttrVal($hash->{NAME}, 'password', '');
  490. my $cmd = {
  491. Type => 'identify',
  492. Name => 'MP_Connector',
  493. Application => 'FHEM',
  494. Version => '1.0'
  495. };
  496. if ($authmethod ne "none") {
  497. $cmd->{Authenticate}{AuthMethod} = $authmethod;
  498. $cmd->{Authenticate}{User} = $uid;
  499. $cmd->{Authenticate}{Password} = $pwd;
  500. }
  501. my $strcmd = encode_json($cmd)."\r\n";
  502. return $strcmd;
  503. }
  504. ########################################################################################
  505. #
  506. # MEDIAPORTAL_GetMAC
  507. #
  508. ########################################################################################
  509. sub MEDIAPORTAL_GetMAC($) {
  510. my ($hash) = @_;
  511. my $mac = undef;
  512. eval {
  513. my ($host, $port) = split(/:/, $hash->{DeviceName});
  514. my $result = qx/arp -a $host/;
  515. MEDIAPORTAL_Log undef, 5, 'ARP-SysCall: '.$result;
  516. $mac = uc($1) if ($result =~ m/([0-9a-fA-F]{2}(:|-)[0-9a-fA-F]{2}(:|-)[0-9a-fA-F]{2}(:|-)[0-9a-fA-F]{2}(:|-)[0-9a-fA-F]{2}(:|-)[0-9a-fA-F]{2})/s);
  517. $mac =~ s/-/:/g if (defined($mac)); # Korrektur für Windows-Rechner
  518. if (defined($mac)) {
  519. MEDIAPORTAL_Log undef, 5, 'Found Mac: '.$mac;
  520. } else {
  521. MEDIAPORTAL_Log undef, 5, 'No Mac Found!';
  522. }
  523. };
  524. if ($@) {
  525. return undef;
  526. }
  527. return undef if (defined($mac) && ($mac eq '00:00:00:00:00:00')); # Unter Windows wird im Fehlerfall diese Adresse zurückgegeben.
  528. return $mac;
  529. }
  530. ########################################################################################
  531. #
  532. # MEDIAPORTAL_Wakeup
  533. #
  534. ########################################################################################
  535. sub MEDIAPORTAL_Wakeup($;$$) {
  536. my ($hwaddr, $ipaddr, $port) = @_;
  537. $ipaddr = '255.255.255.255' if (!defined($ipaddr));
  538. $port = getservbyname('discard', 'udp') if (!defined($port));
  539. # Zur Sicherheit zweimal senden...
  540. return MEDIAPORTAL_DoWakeup($hwaddr, $ipaddr, $port) || MEDIAPORTAL_DoWakeup($hwaddr, $ipaddr, $port);
  541. }
  542. ########################################################################################
  543. #
  544. # MEDIAPORTAL_DoWakeup
  545. #
  546. ########################################################################################
  547. sub MEDIAPORTAL_DoWakeup($;$$) {
  548. my ($hwaddr, $ipaddr, $port) = @_;
  549. $ipaddr = '255.255.255.255' if (!defined($ipaddr));
  550. $port = getservbyname('discard', 'udp') if (!defined($port));
  551. # Validate hardware address (ethernet address)
  552. my $hwaddr_re = join(':', ('[0-9A-Fa-f]{1,2}') x 6);
  553. if ($hwaddr !~ m/^$hwaddr_re$/) {
  554. warn "Invalid hardware address: $hwaddr\n";
  555. return undef;
  556. }
  557. # Generate magic sequence
  558. my $pkt = '';
  559. foreach (split /:/, $hwaddr) {
  560. $pkt .= chr(hex($_));
  561. }
  562. $pkt = chr(0xFF) x 6 . $pkt x 16;
  563. # Allocate socket and send packet
  564. my $raddr = gethostbyname($ipaddr);
  565. my $them = pack_sockaddr_in($port, $raddr);
  566. my $proto = getprotobyname('udp');
  567. socket(S, AF_INET, SOCK_DGRAM, $proto) or die "socket : $!";
  568. setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt : $!";
  569. send(S, $pkt, 0, $them) or die "send : $!";
  570. close S;
  571. return 1;
  572. }
  573. ########################################################################################
  574. #
  575. # MEDIAPORTAL_ConvertSecondsToTime
  576. #
  577. ########################################################################################
  578. sub MEDIAPORTAL_ConvertSecondsToTime($) {
  579. my ($seconds) = @_;
  580. return sprintf('%01d:%02d:%02d', $seconds / 3600, ($seconds%3600) / 60, $seconds%60) if ($seconds > 0);
  581. return '0:00:00';
  582. }
  583. ########################################################################################
  584. #
  585. # MEDIAPORTAL_isInList
  586. #
  587. ########################################################################################
  588. sub MEDIAPORTAL_isInList($@) {
  589. my($search, @list) = @_;
  590. return 1 if MEDIAPORTAL_posInList($search, @list) >= 0;
  591. return 0;
  592. }
  593. ########################################################################################
  594. #
  595. # MEDIAPORTAL_posInList
  596. #
  597. ########################################################################################
  598. sub MEDIAPORTAL_posInList($@) {
  599. my($search, @list) = @_;
  600. for (my $i = 0; $i <= $#list; $i++) {
  601. return $i if ($list[$i] && $search eq $list[$i]);
  602. }
  603. return -1;
  604. }
  605. ########################################################################################
  606. #
  607. # MEDIAPORTAL_Log - Log to the normal Log-command with the prefix 'SONOSPLAYER'
  608. #
  609. ########################################################################################
  610. sub MEDIAPORTAL_Log($$$) {
  611. my ($devicename, $level, $text) = @_;
  612. Log3 $devicename, $level, 'MEDIAPORTAL: '.$text;
  613. }
  614. 1;
  615. =pod
  616. =begin html
  617. <a name="MEDIAPORTAL"></a>
  618. <h3>MEDIAPORTAL</h3>
  619. <p>Connects to a running MediaPortal instance via the WifiRemote plugin</p>
  620. <h4>Example</h4>
  621. <p>
  622. <code>define wohnzimmer_Mediaportal MEDIAPORTAL 192.168.0.47:8017</code>
  623. </p>
  624. <a name="MEDIAPORTALdefine"></a>
  625. <h4>Define</h4>
  626. <b><code>define &lt;name&gt; MEDIAPORTAL host[:port]</code></b>
  627. <br /><br /> Define a Mediaportal interface to communicate with a Wifiremote-Plugin of a Mediaportal-System.<br />
  628. <p>
  629. <b><code>host[:port]</code></b><br />The name and port of the Mediaportal-Wifiremote-Plugin. If Port is not given, the default of <code>8017</code> will be used.</p>
  630. <a name="MEDIAPORTALset"></a>
  631. <h4>Set</h4>
  632. <ul>
  633. <li><b>Common Tasks</b><ul>
  634. <li><a name="MEDIAPORTAL_setter_connect">
  635. <b><code>connect</code></b></a>
  636. <br />Connects to Mediaportal immediately without waiting for the normal Fhem-Timeout for reconnect (30s).</li>
  637. <li><a name="MEDIAPORTAL_setter_powermode">
  638. <b><code>powermode &lt;mode&gt;</code></b></a>
  639. <br />One of (logoff, suspend, hibernate, reboot, shutdown, exit). Sets the powermode, e.g. shutdown, for shutdown the computersystem of the Mediaportal-System.</li>
  640. <li><a name="MEDIAPORTAL_setter_reconnect">
  641. <b><code>reconnect</code></b></a>
  642. <br />Re-Connects to Mediaportal immediately.</li>
  643. </ul></li>
  644. <li><b>Control-Commands</b><ul>
  645. <li><a name="MEDIAPORTAL_setter_command">
  646. <b><code>command &lt;command&gt;</code></b></a>
  647. <br />One of (stop, record, pause, play, rewind, forward, replay, skip, back, info, menu, up, down, left, right, ok, volup, voldown, volmute, chup, chdown, dvdmenu, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, clear, enter, teletext, red, blue, yellow, green, home, basichome, nowplaying, tvguide, tvrecs, dvd, playlists, first, last, fullscreen, subtitles, audiotrack, screenshot). Sends the given command to the player.</li>
  648. <li><a name="MEDIAPORTAL_setter_key">
  649. <b><code>key &lt;keyvalue&gt;</code></b></a>
  650. <br />Sends the given key to the player.</li>
  651. <li><a name="MEDIAPORTAL_setter_sleep">
  652. <b><code>sleep</code></b></a>
  653. <br />Sends the hinernate-signal to Mediaportal. This command is a shortcut for "powermode hibernate"</li>
  654. <li><a name="MEDIAPORTAL_setter_wakeup">
  655. <b><code>wakeup</code></b></a>
  656. <br />Wakes the Mediaportal-System up (WakeUp-On-LAN).</li>
  657. </ul></li>
  658. <li><b>Play-Commands</b><ul>
  659. <li><a name="MEDIAPORTAL_setter_playchannel">
  660. <b><code>playchannel &lt;channelID&gt;</code></b></a>
  661. <br />Plays the channel with the given ID.</li>
  662. <li><a name="MEDIAPORTAL_setter_playfile">
  663. <b><code>playfile &lt;fileType&gt; &lt;filePath&gt;</code></b></a>
  664. <br />Plays the given file with the given type. FileType can be one of (audio, video).</li>
  665. <li><a name="MEDIAPORTAL_setter_playlist">
  666. <b><code>playlist &lt;command&gt; &lt;param&gt;</code></b></a>
  667. <br />Sends the given playlistcommand with the given parameter. Command can be one of (play, loadlist, loadlist_shuffle, loadfrompath, loadfrompath_shuffle).</li>
  668. <li><a name="MEDIAPORTAL_setter_Volume">
  669. <b><code>Volume &lt;volumelevel&gt;</code></b></a>
  670. <br />Sets the Volume to the given value.</li>
  671. </ul></li>
  672. </ul>
  673. <a name="MEDIAPORTALget"></a>
  674. <h4>Get</h4>
  675. <ul>
  676. <li><b>Common Tasks</b><ul>
  677. <li><a name="MEDIAPORTAL_getter_status">
  678. <b><code>status</code></b></a>
  679. <br />Call for the answer of a <code>status</code>-Message. e.g. Asynchronously retrieves the information of "Title" and "PlayStatus".</li>
  680. <li><a name="MEDIAPORTAL_getter_nowplaying">
  681. <b><code>nowplaying</code></b></a>
  682. <br />Call for the answer of a <code>nowplaying</code>-Message. e.g. Asynchronously retrieves the information of "Duration", "Position" and "File"".</li>
  683. </ul></li>
  684. </ul>
  685. <a name="MEDIAPORTALattr"></a>
  686. <h4>Attributes</h4>
  687. <ul>
  688. <li><b>Common</b><ul>
  689. <li><a name="MEDIAPORTAL_attribut_disable"><b><code>disable &lt;value&gt;</code></b>
  690. </a><br />One of (0, 1). With this attribute you can disable the module.</li>
  691. <li><a name="MEDIAPORTAL_attribut_generateNowPlayingUpdateEvents"><b><code>generateNowPlayingUpdateEvents &lt;value&gt;</code></b>
  692. </a><br />One of (0, 1). With this value you can disable (or enable) the generation of <code>NowPlayingUpdate</code>-Events. If set, Fhem generates an event per second with the updated time-values for the current playing. Defaults to "0".</li>
  693. <li><a name="MEDIAPORTAL_attribut_HeartbeatInterval"><b><code>HeartbeatInterval &lt;interval&gt;</code></b>
  694. </a><br />In seconds. Defines the heartbeat interval in seconds which is used for testing the correct work of the connection to Mediaportal. A value of 0 deactivate the heartbeat-check. Defaults to "15".</li>
  695. <li><a name="MEDIAPORTAL_attribut_macaddress"><b><code>macaddress &lt;address&gt;</code></b>
  696. </a><br />Sets the MAC-Address for the Player. This is needed for WakeUp-Function. e.g. "90:E6:BA:C2:96:15"</li>
  697. </ul></li>
  698. <li><b>Authentication</b><ul>
  699. <li><a name="MEDIAPORTAL_attribut_authmethod"><b><code>authmethod &lt;value&gt;</code></b>
  700. </a><br />One of (none, userpassword, passcode, both). With this value you can set the authentication-mode.</li>
  701. <li><a name="MEDIAPORTAL_attribut_password"><b><code>password &lt;value&gt;</code></b>
  702. </a><br />With this value you can set the password for authentication.</li>
  703. <li><a name="MEDIAPORTAL_attribut_username"><b><code>username &lt;value&gt;</code></b>
  704. </a><br />With this value you can set the username for authentication.</li>
  705. </ul></li>
  706. </ul>
  707. =end html
  708. =begin html_DE
  709. <a name="MEDIAPORTAL"></a>
  710. <h3>MEDIAPORTAL</h3>
  711. <p>Verbindet sich über das Wifiremote-Plugin mit einer laufenden Mediaportal-Instanz.</p>
  712. <h4>Beispiel</h4>
  713. <p>
  714. <code>define wohnzimmer_Mediaportal MEDIAPORTAL 192.168.0.47:8017</code>
  715. </p>
  716. <a name="MEDIAPORTALdefine"></a>
  717. <h4>Define</h4>
  718. <b><code>define &lt;name&gt; MEDIAPORTAL host[:port]</code></b>
  719. <br /><br />Definiert ein Mediaportal Interface für die Kommunikation mit einem Wifiremote-Plugin einer Mediaportal Installation.<br />
  720. <p>
  721. <b><code>host[:port]</code></b><br />Der Hostname und der Port eines laufenden Mediaportal-Wifiremote-Plugins. Wenn der Port nicht angegeben wurde, wird <code>8017</code> als Standard verwendet.</p>
  722. <a name="MEDIAPORTALset"></a>
  723. <h4>Set</h4>
  724. <ul>
  725. <li><b>Grundsätzliches</b><ul>
  726. <li><a name="MEDIAPORTAL_setter_connect">
  727. <b><code>connect</code></b></a>
  728. <br />Erzwingt eine sofortige Verbindung zu Mediaportal. Normalerweise würde die normale Verbindungswiederholung von Fhem (30s) abgewartet werden. </li>
  729. <li><a name="MEDIAPORTAL_setter_powermode">
  730. <b><code>powermode &lt;mode&gt;</code></b></a>
  731. <br />Eins aus (logoff, suspend, hibernate, reboot, shutdown, exit). Setzt den powermode, z.B. shutdown, zum Herunterfahren des Computers des Mediaportal-Systems.</li>
  732. <li><a name="MEDIAPORTAL_setter_reconnect">
  733. <b><code>reconnect</code></b></a>
  734. <br />Erzwingt eine sofortige Trennung und Neuverbindung zu Mediaportal.</li>
  735. </ul></li>
  736. <li><b>Control-Befehle</b><ul>
  737. <li><a name="MEDIAPORTAL_setter_command">
  738. <b><code>command &lt;command&gt;</code></b></a>
  739. <br />Eins aus (stop, record, pause, play, rewind, forward, replay, skip, back, info, menu, up, down, left, right, ok, volup, voldown, volmute, chup, chdown, dvdmenu, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, clear, enter, teletext, red, blue, yellow, green, home, basichome, nowplaying, tvguide, tvrecs, dvd, playlists, first, last, fullscreen, subtitles, audiotrack, screenshot). Sendet das entsprechende Kommando an den Player.</li>
  740. <li><a name="MEDIAPORTAL_setter_key">
  741. <b><code>key &lt;keyvalue&gt;</code></b></a>
  742. <br />Sendet die entsprechende Taste an den Player.</li>
  743. <li><a name="MEDIAPORTAL_setter_sleep">
  744. <b><code>sleep</code></b></a>
  745. <br />Startet den Hibernate-Modus. Dieser Befehl ist ein Shortcut für "powermode hibernate"</li>
  746. <li><a name="MEDIAPORTAL_setter_wakeup">
  747. <b><code>wakeup</code></b></a>
  748. <br />Weckt den Mediaportal-Rechner auf (WakeUp-On-LAN).</li>
  749. </ul></li>
  750. <li><b>Abspielbefehle</b><ul>
  751. <li><a name="MEDIAPORTAL_setter_playchannel">
  752. <b><code>playchannel &lt;channelID&gt;</code></b></a>
  753. <br />Spielt den Kanal mit der entsprechenden ID ab.</li>
  754. <li><a name="MEDIAPORTAL_setter_playfile">
  755. <b><code>playfile &lt;fileType&gt; &lt;filePath&gt;</code></b></a>
  756. <br />Spielt die entsprechende Datei mit dem angegebenen Typ ab. FileType kann (audio, video) sein.</li>
  757. <li><a name="MEDIAPORTAL_setter_playlist">
  758. <b><code>playlist &lt;command&gt; &lt;param&gt;</code></b></a>
  759. <br />Sendet das entsprechende Playlist-Kommando mit dem gegebenen Parameter. Das Kommando kann (play, loadlist, loadlist_shuffle, loadfrompath, loadfrompath_shuffle) sein.</li>
  760. <li><a name="MEDIAPORTAL_setter_Volume">
  761. <b><code>Volume &lt;volumelevel&gt;</code></b></a>
  762. <br />Setzt die angegebene Lautstärke.</li>
  763. </ul></li>
  764. </ul>
  765. <a name="MEDIAPORTALget"></a>
  766. <h4>Get</h4>
  767. <ul>
  768. <li><b>Grundsätzliches</b><ul>
  769. <li><a name="MEDIAPORTAL_getter_status">
  770. <b><code>status</code></b></a>
  771. <br />Sendet eine Aufforderung für das Senden einer <code>status</code>-Nachricht. Liefert dann asynchron die Informationen "Title" und "PlayStatus".</li>
  772. <li><a name="MEDIAPORTAL_getter_nowplaying">
  773. <b><code>nowplaying</code></b></a>
  774. <br />Sendet eine Aufforderung für das Senden einer <code>nowplaying</code>-Nachricht. Liefert dann asynchron die Informationen "Duration", "Position" und "File"".</li>
  775. </ul></li>
  776. </ul>
  777. <a name="MEDIAPORTALattr"></a>
  778. <h4>Attribute</h4>
  779. <ul>
  780. <li><b>Grundsätzliches</b><ul>
  781. <li><a name="MEDIAPORTAL_attribut_disable"><b><code>disable &lt;value&gt;</code></b>
  782. </a><br />Eins aus (0, 1). Mit diesem Attribut kann das Modul deaktiviert werden.</li>
  783. <li><a name="MEDIAPORTAL_attribut_generateNowPlayingUpdateEvents"><b><code>generateNowPlayingUpdateEvents &lt;value&gt;</code></b>
  784. </a><br />Eins aus (0, 1). Mit diesem Attribut kann die Erzeugung eines <code>NowPlayingUpdate</code>-Events an- oder abgeschaltet werden. Wenn auf "1" gesetzt, generiert Fhem ein Event pro Sekunde mit den angepassten Zeitangaben. Standard ist "0".</li>
  785. <li><a name="MEDIAPORTAL_attribut_HeartbeatInterval"><b><code>HeartbeatInterval &lt;intervall&gt;</code></b>
  786. </a><br />In Sekunden. Legt das Intervall für die Prüfung der Verbindung zu Mediaportal fest. Mit "0" kann die Prüfung deaktiviert werden. Wenn kein Wert angeggeben wird, wird "15" verwendet.</li>
  787. <li><a name="MEDIAPORTAL_attribut_macaddress"><b><code>macaddress &lt;address&gt;</code></b>
  788. </a><br />Gibt die Mac-Adresse des Mediaportal-Rechners an. Das wird für die WakeUp-Funktionalität benötigt. z.B. "90:E6:BA:C2:96:15"</li>
  789. </ul></li>
  790. <li><b>Authentifizierung</b><ul>
  791. <li><a name="MEDIAPORTAL_attribut_authmethod"><b><code>authmethod &lt;value&gt;</code></b>
  792. </a><br />Eins aus (none, userpassword, passcode, both). Hiermit wird der Authentifizierungsmodus festgelegt.</li>
  793. <li><a name="MEDIAPORTAL_attribut_password"><b><code>password &lt;value&gt;</code></b>
  794. </a><br />Hiermit wird das Passwort für die Authentifzierung festgelegt.</li>
  795. <li><a name="MEDIAPORTAL_attribut_username"><b><code>username &lt;value&gt;</code></b>
  796. </a><br />Hiermit wird der Benutzername für die Authentifizerung festgelegt.</li>
  797. </ul></li>
  798. </ul>
  799. =end html_DE
  800. =cut