70_NEUTRINO.pm 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021
  1. # $Id: 70_NEUTRINO.pm 15133 2017-09-24 21:03:57Z michael.winkler $
  2. ############################################################################
  3. # 2017-09-11, v1.0.12
  4. #
  5. # v1.0.12
  6. # - BUFIX: $_ ersetzt durch $uResult
  7. #
  8. # v1.0.11
  9. # - BUFIX: Code Optimierungen
  10. #
  11. # v1.0.10
  12. # - BUFIX: Code Optimierungen
  13. #
  14. # v1.0.9
  15. # - BUFIX: BUG EPG Info https://forum.fhem.de/index.php/topic,54481.msg665959.html#msg665959
  16. # Change Volume
  17. # - CHANGE Readings für EPG zurücksetzen wenn keine Infos vorhanden sind
  18. #
  19. # v1.0.8
  20. # - BUFIX: Code Optimierungen
  21. # Zeilenumbruch in EPG Informationen entfernt
  22. # NEUTRINO BUG Umschalten wenn EGP und CHANNEL_ID nicht passen!
  23. # BUG leeres EPG https://forum.fhem.de/index.php/topic,54481.msg665355.html#msg665355
  24. #
  25. # v1.0.7 erste SVN Version
  26. # - FEATURE: Reading Model hinzugefügt
  27. # - CHANGE CommandRef ergänzt
  28. # - BUFIX: Optimierung Neutrino Version/Model auslesen bei
  29. # Änderung Power
  30. # Initialisierung Device
  31. #
  32. # v1.0.6
  33. # - FEATURE: CommandRef hinzugefügt (DE/EN)
  34. # - BUFIX: Optimierung Refresh Infos Senderwechsel (EPGInfos, input, Bouquetliste)
  35. # Optimierung Refresh EGPInfos (Wenn Sendung vorbei)
  36. # Optimierung Neutrino Version nur auslesen wenn sich das Reading "power" ändert!
  37. # Optimierung Reading time_now / time_raw_now (Wird vom FHEM Server verwendet/ Infos kommen nicht mehr von Neutrino)
  38. # Probleme beim Umschalten von Kanälen mit + Zeichen
  39. # Logeinträge überarbeitet
  40. # div. Codeoptimierungen
  41. # - CHANGE HTTP Standardtimout auf 2 gesetzt
  42. # NEUTRINO_HD_HandleCmdQueue hinzugefügt
  43. # NEUTRINO_HD_SendCommand hinzugefügt
  44. # Nicht verwendete Attribute entfernt
  45. # bouquet-tv
  46. # bouquet-radio
  47. # remotecontrol
  48. # lightMode
  49. # macaddr
  50. # wakeupCmd
  51. # http_method
  52. #
  53. # v1.0.5 BETA5 - 20160626
  54. # - BUGFIX: clear readings timerlist
  55. #
  56. # v1.0.4 BETA4 - 20160624
  57. # - BUGFIX: Not an ARRAY reference at ./FHEM/70_NEUTRINO.pm line 1237
  58. #
  59. # v1.0.3 BETA3 - 20160614
  60. # - FEATURE: add recordchannel reading
  61. # add recordtitel reading
  62. #
  63. # v1.0.2 BETA2 - 20160613
  64. # - FEATURE: add timer readings
  65. #
  66. # v1.0.0 BETA1 - 20160612
  67. # - FEATURE: add recordmode reading
  68. #
  69. # 70_NEUTRINO.pm
  70. # An FHEM Perl module for controlling NEUTRINO based TV receivers
  71. # via network connection.
  72. #
  73. # Copyright by Michael Winkler
  74. # e-mail: michael.winkler at online.de
  75. #
  76. # This file is part of fhem.
  77. #
  78. # Fhem is free software: you can redistribute it andor modify
  79. # it under the terms of the GNU General Public License as published by
  80. # the Free Software Foundation, either version 2 of the License, or
  81. # (at your option) any later version.
  82. #
  83. # Fhem is distributed in the hope that it will be useful,
  84. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  85. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  86. # GNU General Public License for more details.
  87. #
  88. # You should have received a copy of the GNU General Public License
  89. # along with fhem. If not, see <http://www.gnu.org/licenses/>.
  90. #
  91. ##############################################################################
  92. package main;
  93. use strict;
  94. use warnings;
  95. use HttpUtils;
  96. use Encode;
  97. use Time::Piece;
  98. no warnings "all";
  99. sub NEUTRINO_Set($@);
  100. sub NEUTRINO_Get($@);
  101. sub NEUTRINO_GetStatus($;$);
  102. sub NEUTRINO_Define($$);
  103. sub NEUTRINO_Undefine($$);
  104. ###################################
  105. sub NEUTRINO_Initialize($) {
  106. my ($hash) = @_;
  107. Log3 $hash, 5, "NEUTRINO_Initialize: Entering";
  108. $hash->{GetFn} = "NEUTRINO_Get";
  109. $hash->{AttrFn} = "NEUTRINO_Attr";
  110. $hash->{SetFn} = "NEUTRINO_Set";
  111. $hash->{DefFn} = "NEUTRINO_Define";
  112. $hash->{UndefFn} = "NEUTRINO_Undefine";
  113. $hash->{AttrList} = "https:0,1 http-method:absolete http-noshutdown:1,0 disable:0,1 timeout " . $readingFnAttributes;
  114. return;
  115. }
  116. #####################################
  117. # AttrFn
  118. #####################################
  119. sub NEUTRINO_Attr(@) {
  120. my ( $cmd, $name, $attrName, $attrVal ) = @_;
  121. my $hash = $defs{$name};
  122. my $orig = $attrVal;
  123. if( $attrName eq "bouquet-tv" || $attrName eq "bouquet-radio" || $attrName eq "remotecontrol" || $attrName eq "http-method" || $attrName eq "wakeupCmd" || $attrName eq "macaddr" || $attrName eq "lightMode" ) {
  124. if( $cmd eq "set" ) {
  125. Log3 $name, 3, "NEUTRINO $name [NEUTRINO_Attr] [$attrName] - !!! Attention, the attribut is absolete and will delete in the future";
  126. return "NEUTRINO $name [NEUTRINO_Attr] [$attrName] - !!! Attention, the attribut is absolete and will delete in the future";
  127. }
  128. }
  129. }
  130. #####################################
  131. # Get Status
  132. #####################################
  133. sub NEUTRINO_GetStatus($;$) {
  134. my ( $hash, $update ) = @_;
  135. my $name = $hash->{NAME};
  136. my $interval = $hash->{INTERVAL};
  137. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_GetStatus] called function";
  138. if ($update ne '') {Log3 $name, 5, "NEUTRINO $name [NEUTRINO_GetStatus] Update = $update";}
  139. #RemoveInternalTimer($hash);
  140. InternalTimer( gettimeofday() + $interval, "NEUTRINO_GetStatus", $hash, 0 );
  141. return if ( AttrVal( $name, "disable", 0 ) == 1 );
  142. if ( !$update ) {NEUTRINO_SendCommand( $hash, "powerstate" );}
  143. return;
  144. }
  145. ###################################
  146. sub NEUTRINO_SendCommand($$;$$) {
  147. my ( $hash, $service, $cmd, $type ) = @_;
  148. my $name = $hash->{NAME};
  149. my $address = $hash->{helper}{ADDRESS};
  150. my $port = $hash->{helper}{PORT};
  151. my $serviceurl;
  152. my $channelid = ReadingsVal( $name, "channel_id", "" );
  153. my $param;
  154. # Cannelname
  155. my $channelname = ReadingsVal( $name, "recordchannel", "" );
  156. $channelname =~ s/_/%20/g;
  157. #$cmd = ( defined($cmd) ) ? $cmd : "";
  158. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] called function CMD = $cmd ";
  159. my $http_proto;
  160. if ( $port eq "443" ) {
  161. $http_proto = "https";
  162. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] port 443 implies using HTTPS";
  163. }
  164. elsif ( AttrVal( $name, "https", "0" ) eq "1" ) {
  165. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] explicit use of HTTPS";
  166. $http_proto = "https";
  167. if ( $port eq "80" ) {
  168. $port = "443";
  169. Log3 $name, 5,
  170. "NEUTRINO $name [NEUTRINO_SendCommand] implicit change of from port 80 to 443";
  171. }
  172. }
  173. else {
  174. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] using unencrypted connection via HTTP";
  175. $http_proto = "http";
  176. }
  177. my $http_user = "";
  178. my $http_passwd = "";
  179. if ( defined( $hash->{helper}{USER} )
  180. && defined( $hash->{helper}{PASSWORD} ) )
  181. {
  182. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] using BasicAuth";
  183. $http_user = $hash->{helper}{USER};
  184. $http_passwd = $hash->{helper}{PASSWORD};
  185. }
  186. if ( defined( $hash->{helper}{USER} ) ) {
  187. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_SendCommand] using BasicAuth (username only)";
  188. $http_user = $hash->{helper}{USER};
  189. }
  190. my $URL;
  191. my $response;
  192. my $return;
  193. if ( !defined($cmd) || $cmd eq "" ) {
  194. Log3 $name, 4, "NEUTRINO $name [NEUTRINO_SendCommand] SERVICE = $service";
  195. }
  196. else {
  197. #2017-07-14 - http_method deaktiviert
  198. $cmd = "?" . $cmd;
  199. # if ( $http_method eq "GET" || $http_method eq "" );
  200. Log3 $name, 4, "NEUTRINO $name [NEUTRINO_SendCommand] SERVICE = $service/" . urlDecode($cmd);
  201. }
  202. # Check Service and change serviceurl
  203. if ($service eq "epginfo") {
  204. #2017.07.12 - $channelid entfernt! '$serviceurl = "epg?xml=true&channelid=" . $channelid . "&details=true&max=6";'
  205. $serviceurl = "epg?xml=true&details=true&max=6";
  206. }
  207. elsif ($service eq "epginforecord") {
  208. $serviceurl =
  209. "epg?xml=true&channelname="
  210. . $channelname . "&max=6";
  211. }
  212. elsif ($service eq "timerlist") {
  213. $serviceurl = "timer";
  214. }
  215. elsif ($service eq "mutestate") {
  216. $serviceurl = "volume?status";
  217. }
  218. elsif ($service eq "mute") {
  219. $serviceurl = "volume?mute";
  220. }
  221. elsif ($service eq "unmute") {
  222. $serviceurl = "volume?unmute";
  223. }
  224. elsif ($service eq "recordmode") {
  225. $serviceurl = "setmode?status";
  226. }
  227. elsif ($service eq "powerstate") {
  228. $serviceurl = "standby";
  229. }
  230. elsif ($service eq "model") {
  231. $serviceurl = "info";
  232. }
  233. elsif ($service eq "bouquet") {
  234. $serviceurl = "getbouquet?actual";
  235. }
  236. elsif ($service eq "bouquet_list") {
  237. my $bouquet = ReadingsVal( $name, "bouquetnr", "0" );
  238. my $bouquetset = ReadingsVal( $name, "bouquetnr_set", "73482423648726384726384" );
  239. my $bouquetmode = ReadingsVal( $name, "input", "tv" );
  240. if (!($bouquet eq $bouquetset)) {
  241. $serviceurl = "getbouquet?bouquet=" . $bouquet . "&mode=" . $bouquetmode;
  242. }
  243. else{
  244. return "bouguet schon vorhanden!";
  245. }
  246. }
  247. else{
  248. $serviceurl = $service;
  249. }
  250. if ( $http_user ne "" && $http_passwd ne "" ) {
  251. $URL =
  252. $http_proto . "://"
  253. . $http_user . ":"
  254. . $http_passwd . "@"
  255. . $address . ":"
  256. . $port . "/control/"
  257. . $serviceurl;
  258. #2017-07-14 - http_method deaktiviert
  259. $URL .= $cmd; #if ( $http_method eq "GET" || $http_method eq "" );
  260. }
  261. elsif ( $http_user ne "" ) {
  262. $URL =
  263. $http_proto . "://"
  264. . $http_user . "@"
  265. . $address . ":"
  266. . $port . "/control/"
  267. . $serviceurl;
  268. #2017-07-14 - http_method deaktiviert
  269. $URL .= $cmd; #if ( $http_method eq "GET" || $http_method eq "" );
  270. }
  271. else {
  272. $URL =
  273. $http_proto . "://" . $address . ":" . $port . "/control/" . $serviceurl;
  274. #2017-07-14 - http_method deaktiviert
  275. $URL .= $cmd; #if ( $http_method eq "GET" || $http_method eq "" );
  276. }
  277. #2017.07.19 - Übergabe SendCommandQuery
  278. $param = {
  279. url => $URL,
  280. service => $service,
  281. cmd => $cmd,
  282. type => $type,
  283. callback => \&NEUTRINO_ReceiveCommand,
  284. };
  285. NEUTRINO_HD_SendCommand($hash,$param);
  286. return;
  287. }
  288. #############################
  289. # pushes new command to cmd queue
  290. sub NEUTRINO_HD_SendCommand($$) {
  291. my ($hash, $param) = @_;
  292. my $name = $hash->{NAME};
  293. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_HD_SendCommand] - append to queue " .$param->{url};
  294. # In case any URL changes must be made, this part is separated in this function".
  295. push @{$hash->{helper}{CMD_QUEUE}}, $param;
  296. NEUTRINO_HD_HandleCmdQueue($hash);
  297. }
  298. #############################
  299. # starts http requests from cmd queue
  300. sub NEUTRINO_HD_HandleCmdQueue($) {
  301. my ($hash, $param) = @_;
  302. my $name = $hash->{NAME};
  303. my $http_noshutdown = AttrVal( $name, "http-noshutdown", "0" );
  304. my $http_timeout = AttrVal( $name, "timeout", "2" );
  305. if(not($hash->{helper}{RUNNING_REQUEST}) and @{$hash->{helper}{CMD_QUEUE}})
  306. {
  307. my $params = {
  308. url => $param->{url},
  309. timeout => $http_timeout,
  310. noshutdown => $http_noshutdown,
  311. keepalive => 0,
  312. hash => $hash,
  313. callback => \&NEUTRINO_ReceiveCommand
  314. };
  315. my $request = pop @{$hash->{helper}{CMD_QUEUE}};
  316. map {$hash->{helper}{HTTP_CONNECTION}{$_} = $params->{$_}} keys %{$params};
  317. map {$hash->{helper}{HTTP_CONNECTION}{$_} = $request->{$_}} keys %{$request};
  318. $hash->{helper}{RUNNING_REQUEST} = 1;
  319. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_HD_HandleCmdQueue] - send command " .$params->{url};
  320. HttpUtils_NonblockingGet($hash->{helper}{HTTP_CONNECTION});
  321. }
  322. }
  323. ###################################
  324. sub NEUTRINO_Get($@) {
  325. my ( $hash, @a ) = @_;
  326. my $name = $hash->{NAME};
  327. my $what;
  328. return "argument is missing" if ( int(@a) < 2 );
  329. $what = $a[1];
  330. #2017.07.21 - Log nur schreiben wenn get nicht initialisiert wird
  331. if ($what ne '?') {
  332. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Get] [$what] called function";
  333. }
  334. if ( $what =~
  335. /^(power|input|volume|mute|channel|currentTitle|channel_url)$/
  336. )
  337. {
  338. if ( ReadingsVal( $name, $what, "" ) ne "" ) {
  339. return ReadingsVal( $name, $what, "" );
  340. }
  341. else {
  342. return "no such reading: $what";
  343. }
  344. }
  345. else {
  346. return "Unknown argument $what, choose one of power:noArg input:noArg volume:noArg mute:noArg channel:noArg currentTitle:noArg channel_url:noArg ";
  347. }
  348. }
  349. ###################################
  350. sub NEUTRINO_Set($@) {
  351. my ( $hash, @a ) = @_;
  352. my $name = $hash->{NAME};
  353. my $state = ReadingsVal( $name, "state", "absent" );
  354. my $presence = ReadingsVal( $name, "presence", "absent" );
  355. my $input = ReadingsVal( $name, "input", "" );
  356. my $channel = ReadingsVal( $name, "channel", "" );
  357. my $channels = "";
  358. #2017.07.21 - Log nur schreiben wenn get nicht initialisiert wird
  359. if ($a[1] ne '?') {
  360. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] called function";
  361. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] set";
  362. }
  363. return "No Argument given" if ( !defined( $a[1] ) );
  364. # load channel list
  365. if (
  366. defined($input)
  367. && defined($channel)
  368. && $input ne ""
  369. && $channel ne ""
  370. && ( !defined( $hash->{helper}{channels}{$input} )
  371. || !defined( $hash->{helper}{channels}{$input} ) )
  372. )
  373. {
  374. $channels = $channel . ",";
  375. }
  376. if ( $input ne ""
  377. && defined( $hash->{helper}{channels}{$input} )
  378. && ref( $hash->{helper}{channels}{$input} ) eq "ARRAY" )
  379. {
  380. $channels = join( ',', @{ $hash->{helper}{channels}{$input} } );
  381. }
  382. my $usage = "Unknown argument " . $a[1] . ", choose one of toggle:noArg on:noArg off:noArg volume:slider,0,1,100 remoteControl showText showtextwithbutton channel:" . $channels;
  383. $usage .= " mute:-,on,off"
  384. if ( ReadingsVal( $name, "mute", "-" ) eq "-" );
  385. $usage .= " mute:on,off"
  386. if ( ReadingsVal( $name, "mute", "-" ) ne "-" );
  387. $usage .= " reboot:noArg";
  388. $usage .= " shutdown:noArg";
  389. $usage .= " statusRequest:noArg";
  390. my $cmd = '';
  391. my $result;
  392. # statusRequest
  393. if ( lc( $a[1] ) eq "statusrequest" ) {
  394. NEUTRINO_GetStatus($hash);
  395. }
  396. # toggle
  397. elsif ( lc( $a[1] ) eq "toggle" ) {
  398. if ( $state ne "on" ) {
  399. return NEUTRINO_Set( $hash, $name, "on" );
  400. }
  401. else {
  402. return NEUTRINO_Set( $hash, $name, "off" );
  403. }
  404. }
  405. # shutdown
  406. elsif ( lc( $a[1] ) eq "shutdown" ) {
  407. if ( $state ne "absent" ) {
  408. $cmd = "shutdown";
  409. $result = NEUTRINO_SendCommand( $hash, "shutdown");
  410. }
  411. else {
  412. return "Device needs to be ON to be set to standby mode.";
  413. }
  414. }
  415. # reboot
  416. elsif ( lc( $a[1] ) eq "reboot" ) {
  417. if ( $state ne "absent" ) {
  418. $result = NEUTRINO_SendCommand( $hash, "reboot");
  419. }
  420. else {
  421. return "Device needs to be reachable to be rebooted.";
  422. }
  423. }
  424. # on
  425. elsif ( lc( $a[1] ) eq "on" ) {
  426. if ( $state eq "standby" ) {
  427. $cmd = "off";
  428. $result = NEUTRINO_SendCommand( $hash, "powerstate", $cmd, "off" );
  429. }
  430. else {
  431. return "Device needs to be reachable to be set to standby mode.";
  432. }
  433. }
  434. # off
  435. elsif ( lc( $a[1] ) eq "off" ) {
  436. if ( $state ne "absent" ) {
  437. $cmd = "on";
  438. NEUTRINO_SendCommand( $hash, "powerstate", $cmd, "on" );
  439. }
  440. else {
  441. return "Device needs to be reachable to be set to standby mode.";
  442. }
  443. }
  444. # volume
  445. elsif ( lc( $a[1] ) eq "volume" ) {
  446. if ( !defined( $a[2] ) ) {return "No argument given";}
  447. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] " . $a[2];
  448. if ( $state eq "on" ) {
  449. my $uResult = $a[2];
  450. if ( $uResult =~ m/^\d+$/ && $uResult >= 0 && $uResult <= 100 ) {
  451. $cmd = $a[2];
  452. }
  453. else {
  454. return "Argument does not seem to be a valid integer between 0 and 100";
  455. }
  456. $result = NEUTRINO_SendCommand( $hash, "volume", $cmd );
  457. }
  458. else {
  459. return "Device needs to be ON to adjust volume.";
  460. }
  461. }
  462. # mute
  463. elsif ( lc( $a[1] ) eq "mute" || lc( $a[1] ) eq "mutet" ) {
  464. if ( $state eq "on" ) {
  465. if ( defined( $a[2] ) ) {
  466. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] " . $a[2];
  467. }
  468. if ( lc( $a[2] ) eq "off" ) {
  469. NEUTRINO_SendCommand( $hash, "unmute", $cmd );
  470. }
  471. elsif ( lc( $a[2] ) eq "on" ) {
  472. NEUTRINO_SendCommand( $hash, "mute", $cmd );
  473. }
  474. else {
  475. return "Unknown argument " . $a[2];
  476. }
  477. }
  478. else {
  479. return "Device needs to be ON to mute/unmute audio.";
  480. }
  481. }
  482. # remoteControl
  483. elsif ( lc( $a[1] ) eq "remotecontrol" ) {
  484. if ( !defined( $a[2] ) ){return "No argument given.";}
  485. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] " . $a[2];
  486. if ( defined( $a[2] )){
  487. $result = NEUTRINO_SendCommand( $hash, "rcem", $a[2] );
  488. return $result;
  489. }
  490. }
  491. # channel
  492. elsif ( lc( $a[1] ) eq "channel" ) {
  493. if ( !defined( $a[2] ) ) {return "No argument given, choose one of channel channelNumber servicereference ";}
  494. if ( defined( $a[2] )
  495. && $presence eq "present"
  496. && $state ne "on" )
  497. {
  498. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] indirect switching request to ON";
  499. NEUTRINO_Set( $hash, $name, "on" );
  500. }
  501. if ( defined( $a[3] ) ) {
  502. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] " . $a[2] . "+" . $a[3];
  503. }
  504. else{
  505. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Set] [" . $a[1] . "] " . $a[2];
  506. }
  507. if ( $state eq "on" ) {
  508. my $uResult = $a[2];
  509. my $channellistname;
  510. #2017.07.19 - Plus Zeichen im Name erkennen
  511. if ( defined( $a[3] ) ) {
  512. # + Zeichen im Name erkannt!
  513. $channellistname = $a[2] . "%2B" . $a[3];
  514. }
  515. else {$channellistname = $a[2];}
  516. $channellistname =~ s/_/%20/g;
  517. NEUTRINO_SendCommand( $hash, "zapto", "name=$channellistname" );
  518. }
  519. else {
  520. return
  521. "Device needs to be present to switch to a specific channel.";
  522. }
  523. }
  524. # showText
  525. elsif ( lc( $a[1] ) eq "showtext" ) {
  526. if ( $state ne "absent" ) {
  527. if ( !defined( $a[2] ) ) {return "No argument given, choose one of messagetext ";}
  528. my $i = 2;
  529. my $text = $a[$i];
  530. $i++;
  531. if ( defined( $a[$i] ) ) {
  532. my $arr_size = @a;
  533. while ( $i < $arr_size ) {
  534. $text = $text . " " . $a[$i];
  535. $i++;
  536. }
  537. }
  538. $cmd = "popup=" . urlEncode($text) ."&timeout=10";
  539. $result = NEUTRINO_SendCommand( $hash, "message", $cmd );
  540. }
  541. else {
  542. return "Device needs to be reachable to send a message to screen.";
  543. }
  544. }
  545. # showTextwithbutton
  546. elsif ( lc( $a[1] ) eq "showtextwithbutton" ) {
  547. if ( $state ne "absent" ) {
  548. if ( !defined( $a[2] ) ) {return "No argument given, choose one of messagetext";}
  549. my $i = 2;
  550. my $text = $a[$i];
  551. $i++;
  552. if ( defined( $a[$i] ) ) {
  553. my $arr_size = @a;
  554. while ( $i < $arr_size ) {
  555. $text = $text . " " . $a[$i];
  556. $i++;
  557. }
  558. }
  559. $cmd = "nmsg=" . urlEncode($text);
  560. $result = NEUTRINO_SendCommand( $hash, "message", $cmd );
  561. }
  562. else {
  563. return "Device needs to be reachable to send a message to screen.";
  564. }
  565. }
  566. # return usage hint
  567. else {
  568. return $usage;
  569. }
  570. return;
  571. }
  572. ###################################
  573. sub NEUTRINO_Define($$) {
  574. my ( $hash, $def ) = @_;
  575. my @a = split( "[ \t][ \t]*", $def );
  576. my $name = $hash->{NAME};
  577. Log3 $name, 0, "NEUTRINO $name [NEUTRINO_Define] start device";
  578. eval { require XML::Simple; };
  579. return "Please install Perl XML::Simple to use module NEUTRINO"
  580. if ($@);
  581. if ( int(@a) < 3 ) {
  582. my $msg = "Wrong syntax: define <name> NEUTRINO <ip-or-hostname> [<port>] [<poll-interval>] [<http-user] [<http-password>]";
  583. Log3 $name, 4, $msg;
  584. return $msg;
  585. }
  586. $hash->{TYPE} = "NEUTRINO";
  587. my $address = $a[2];
  588. $hash->{helper}{ADDRESS} = $address;
  589. # use port 80 if not defined
  590. my $port = $a[3] || 80;
  591. $hash->{helper}{PORT} = $port;
  592. # use interval of 45sec if not defined
  593. my $interval = $a[4] || 45;
  594. $hash->{INTERVAL} = $interval;
  595. # set http user if defined
  596. my $http_user = $a[5];
  597. $hash->{helper}{USER} = $http_user if $http_user;
  598. # set http password if defined
  599. my $http_passwd = $a[6];
  600. $hash->{helper}{PASSWORD} = $http_passwd if $http_passwd;
  601. $hash->{helper}{CMD_QUEUE} = ();
  602. delete($hash->{helper}{HTTP_CONNECTION}) if(exists($hash->{helper}{HTTP_CONNECTION}));
  603. # set default settings on first define
  604. if ($init_done) {
  605. # use http-method POST for FritzBox environment as GET does not seem to
  606. # work properly. Might restrict use to newer
  607. # NEUTRINO Webif versions or use of OWIF only.
  608. if ( exists $ENV{CONFIG_PRODUKT_NAME}
  609. && defined $ENV{CONFIG_PRODUKT_NAME} )
  610. {
  611. #2017-07-14 - http_method deaktiviert
  612. #$attr{$name}{"http-method"} = 'POST';
  613. }
  614. # default method is GET and should be compatible to most
  615. # NEUTRINO Webif versions
  616. else {
  617. #2017-07-14 - http_method deaktiviert
  618. #$attr{$name}{"http-method"} = 'GET';
  619. }
  620. $attr{$name}{webCmd} = 'channel';
  621. $attr{$name}{devStateIcon} = 'on:rc_GREEN:off off:rc_RED:on standby:rc_YELLOW:on';
  622. $attr{$name}{icon} = 'dreambox';
  623. }
  624. # start the status update timer
  625. #RemoveInternalTimer($hash);
  626. InternalTimer( gettimeofday() + 2, "NEUTRINO_GetStatus", $hash, 1 );
  627. return;
  628. }
  629. ############################################################################################################
  630. #
  631. # Begin of helper functions
  632. #
  633. ############################################################################################################
  634. ###################################
  635. sub NEUTRINO_ReceiveCommand($$$) {
  636. my ( $param, $err, $data ) = @_;
  637. my $hash = $param->{hash};
  638. my $name = $hash->{NAME};
  639. my $service = $param->{service};
  640. my $cmd = $param->{cmd};
  641. my $state = ReadingsVal( $name, "state", "off" );
  642. my $presence = ReadingsVal( $name, "presence", "absent" );
  643. my $type = ( $param->{type} ) ? $param->{type} : "";
  644. my $return;
  645. my $line;
  646. my $UnixDate = time();
  647. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] called function";
  648. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] Data = $data";
  649. $hash->{helper}{RUNNING_REQUEST} = 0;
  650. delete($hash->{helper}{HTTP_CONNECTION}) unless($param->{keepalive});
  651. readingsBeginUpdate($hash);
  652. # mute data = 0 then data = off
  653. if ($service eq "mutestate" && $data == 0){
  654. $data = "off";
  655. }
  656. # empty timerlist
  657. if ($service eq "timerlist" && $data == 0){
  658. $data = "empty";
  659. }
  660. # volume data = 0 then data = off
  661. if ($service eq "volume" && $data eq '0'){
  662. $data = "off";
  663. }
  664. # device not reachable
  665. if ($err) {
  666. # powerstate
  667. if ( $service eq "powerstate" ) {
  668. $state = "absent";
  669. if ( !defined($cmd) || $cmd eq "" ) {
  670. Log3 $name, 4, "NEUTRINO $name RCV TIMEOUT $service";
  671. }
  672. else {
  673. Log3 $name, 4,
  674. "NEUTRINO $name RCV TIMEOUT $service/" . urlDecode($cmd);
  675. }
  676. $presence = "absent";
  677. readingsBulkUpdateIfChanged( $hash, "power", "off" );
  678. readingsBulkUpdateIfChanged( $hash, "state", "off" );
  679. readingsBulkUpdateIfChanged( $hash, "presence", $presence )
  680. if ( ReadingsVal( $name, "presence", "" ) ne $presence );
  681. }
  682. }
  683. # data received
  684. elsif ($data) {
  685. $presence = "present";
  686. $state = "on";
  687. readingsBulkUpdateIfChanged( $hash, "presence", $presence )
  688. if ( ReadingsVal( $name, "presence", "" ) ne $presence );
  689. #2017.07.21 - Log anzeigen wenn $cmd befüllt ist
  690. if ($cmd ne "" ) {Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] URL = " . urlDecode($cmd);}
  691. # split date (non XML services)
  692. my @ans = split (/\n/s, $data);
  693. #######################
  694. # process return data
  695. #######################
  696. # XML services
  697. if ($service eq "epginfo" || $service eq "epginforecord") {
  698. $data = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $data;
  699. if ( $data =~ /<\?xml/ && $data !~ /<\/html>/ ) {
  700. my $parser = XML::Simple->new(
  701. NormaliseSpace => 2,
  702. KeepRoot => 0,
  703. ForceArray => 0,
  704. SuppressEmpty => 1,
  705. KeyAttr => {}
  706. );
  707. eval
  708. '$return = $parser->XMLin( Encode::encode_utf8($data) ); 1';
  709. if ($@) {
  710. if ( !defined($cmd) || $cmd eq "" ) {
  711. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] - unable to parse malformed XML: $@\n"
  712. . $data;
  713. }
  714. else {
  715. Log3 $name, 5,
  716. "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] "
  717. . urlDecode($cmd)
  718. . " - unable to parse malformed XML: $@\n"
  719. . $data;
  720. }
  721. return undef;
  722. }
  723. undef $parser;
  724. }
  725. else {
  726. if ( !defined($cmd) || $cmd eq "" ) {
  727. Log3 $name, 5,
  728. "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] - not in XML format\n"
  729. . $data;
  730. }
  731. else {
  732. Log3 $name, 5,
  733. "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] "
  734. . urlDecode($cmd)
  735. . " - not in XML format\n"
  736. . $data;
  737. }
  738. return undef;
  739. }
  740. $return = Encode::encode_utf8($data)
  741. if ( $return && ref($return) ne "HASH" );
  742. }
  743. # powerstate
  744. if ( $service eq "powerstate" ) {
  745. if (@ans[0]) {
  746. if (index(lc(@ans[0]), "on") != -1) {
  747. readingsBulkUpdateIfChanged( $hash, "power","off");
  748. readingsBulkUpdateIfChanged( $hash, "state", "standby" );
  749. $state = "off";
  750. }
  751. elsif(index(lc(@ans[0]), "off") != -1) {
  752. # 2017.07.12 - Aenderungen nur durchfuehren wenn power vorher ungleich "on" war
  753. if (ReadingsVal( $name, "power", "unbekannt" ) ne 'on' ) {
  754. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] detect change";
  755. readingsBulkUpdateIfChanged( $hash, "power","on");
  756. readingsBulkUpdateIfChanged( $hash, "state", "on" );
  757. delete($hash->{helper}{FIRSTSTART});
  758. }
  759. #2017.07.25 - Erste Start: NUTRINO Version auslesen
  760. if ($hash->{helper}{FIRSTSTART} eq '') {
  761. NEUTRINO_SendCommand( $hash, "version" );
  762. NEUTRINO_SendCommand( $hash, "model" );
  763. $hash->{helper}{FIRSTSTART} = '1';
  764. }
  765. #2017.07.12 - time_raw_now/time_now vom FHEM-Server verwenden
  766. readingsSingleUpdate( $hash, "time_raw_now", $UnixDate ,0);
  767. readingsSingleUpdate( $hash, "time_now", localtime() ,0);
  768. #2017.07.12 - Pruefen ob die bouquet_list aktualisiert werden muss
  769. if ($hash->{helper}{channels}{ReadingsVal( $name, "input", "-" )} eq '') {
  770. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] bouquet_list detect change!";
  771. NEUTRINO_SendCommand( $hash, "bouquet_list" );
  772. }
  773. #2017.07.12 - Folgendes wird alle INTERVAL abgefragt
  774. NEUTRINO_SendCommand( $hash, "zapto" ); # aktuellen channel_id auslesen
  775. NEUTRINO_SendCommand( $hash, "bouquet" ); # aktuelles Bouguet auslesen
  776. NEUTRINO_SendCommand( $hash, "volume" ); # aktuelles Volumen auslesen
  777. NEUTRINO_SendCommand( $hash, "mutestate" ); # mutestate 0 = off 1 = on
  778. NEUTRINO_SendCommand( $hash, "signal" ); # SIG, SNR und BER
  779. NEUTRINO_SendCommand( $hash, "recordmode" ); # 0 = off 1 = on
  780. NEUTRINO_SendCommand( $hash, "timerlist" ); # aktuelle Timerliste
  781. #2017.07.12 - deaktivert bzw. verschoben
  782. # MOVE --> NEUTRINO_SendCommand( $hash, "bouquet" ); #CHANGE bei Senderwechsel
  783. # MOVE --> NEUTRINO_SendCommand( $hash, "version" ); #CHANGE bei Powerstat wechsel
  784. # MOVE --> NEUTRINO_SendCommand( $hash, "build_live_url" ); #CHANGE bei Senderwechsel
  785. # MOVE --> NEUTRINO_SendCommand( $hash, "getmode" ); #CHANGE bei Senderwechsel
  786. # DEL --> NEUTRINO_SendCommand( $hash, "gettime" ); #FHEM Zeit verwenden
  787. # DEL --> NEUTRINO_SendCommand( $hash, "getrawtime" ); #FHEM Zeit verwenden
  788. }
  789. elsif(index(lc(@ans[0]), "ok") != -1) {
  790. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] TYP = $type";
  791. if (index($type, "off") != -1) {
  792. Log3 $name, 5, "NEUTRINO $name TYP = OFF";
  793. readingsBulkUpdateIfChanged( $hash, "power", "on");
  794. readingsBulkUpdateIfChanged( $hash, "state", "on" );
  795. }
  796. elsif(index($type, "on") != -1) {
  797. Log3 $name, 5, "NEUTRINO $name TYP = ON";
  798. readingsBulkUpdateIfChanged( $hash, "power", "off");
  799. readingsBulkUpdateIfChanged( $hash, "state", "standby" );
  800. }
  801. else {
  802. readingsBulkUpdateIfChanged( $hash, "power", "off");
  803. readingsBulkUpdateIfChanged( $hash, "state", "standby" );
  804. $state = "off";
  805. }
  806. NEUTRINO_SendCommand( $hash, "recordmode" );
  807. }
  808. else{
  809. readingsBulkUpdateIfChanged( $hash, "power", "undefined" );
  810. readingsBulkUpdateIfChanged( $hash, "state", "undefined" );
  811. }
  812. }
  813. else {
  814. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no powerstate could be extracted";
  815. }
  816. }
  817. # bouquet
  818. elsif ( $service eq "bouquet" ) {
  819. if (@ans[0]) {
  820. #2017.07.17 - Liste nur bei aenderung aktualisieren
  821. if (ReadingsVal( $name, "bouquetnr", "99999" ) ne @ans[0] ) {
  822. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] detect change";
  823. readingsBulkUpdateIfChanged( $hash, "bouquetnr", @ans[0] );
  824. NEUTRINO_SendCommand( $hash, "bouquet_list" );
  825. }
  826. }
  827. else {
  828. readingsBulkUpdateIfChanged( $hash, "bouquetnr", "0" );
  829. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no bouquetnr could be extracted";
  830. }
  831. }
  832. # bouquet_list
  833. elsif ( $service eq "bouquet_list" ) {
  834. my $channellistname;
  835. my $i = 0;
  836. my $input = ReadingsVal( $name, "input", "-" );
  837. #2017.07.19 - Nur durchführen wenn $input <> '-' ist
  838. if ($input ne '-') {
  839. $hash->{helper}{channels}{$input} = ();
  840. foreach $line (@ans) {
  841. if (index($line, "",6) != -1) {
  842. $channellistname = substr($line,index($line," ", 6 )+1);
  843. $channellistname =~ s/\s/_/g;
  844. if (substr($channellistname, 0, 1) ne "" && substr($channellistname, 0, 1) ne "_") {
  845. $hash->{helper}{channels}{$input}[$i] = $channellistname ;
  846. $i++;
  847. }
  848. }
  849. }
  850. }
  851. }
  852. # volume
  853. elsif ( $service eq "volume" ) {
  854. if (index(lc(@ans[0]), "ok") != -1) {
  855. #2017.07.12 - Nur bei einer Aenderung schreiben
  856. readingsBulkUpdateIfChanged( $hash, "volume", substr($cmd,1) );
  857. }
  858. elsif (index(lc(@ans[0]), "off") != -1) {
  859. #2017.07.12 - Nur bei einer Aenderung schreiben
  860. readingsBulkUpdateIfChanged( $hash, "volume", "0" );
  861. }
  862. elsif (@ans[0]) {
  863. #2017.07.12 - Nur bei einer Aenderung schreiben
  864. readingsBulkUpdateIfChanged( $hash, "volume", @ans[0] );
  865. }
  866. else {
  867. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no volume could be extracted";
  868. }
  869. }
  870. # mutestate
  871. elsif ( $service eq "mutestate" ) {
  872. if (@ans[0]) {
  873. if (index(lc(@ans[0]), "1") != -1) {
  874. #2017.07.12 - Änderung schreiben
  875. readingsBulkUpdateIfChanged( $hash, "mute","on");
  876. }
  877. else{
  878. readingsBulkUpdateIfChanged( $hash, "mute","off");
  879. }
  880. }
  881. else {
  882. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no mute could be extracted";
  883. }
  884. }
  885. # mute
  886. elsif ( $service eq "mute" ) {
  887. if (@ans[0]) {
  888. if (index(lc(@ans[0]), "ok") != -1) {
  889. readingsBulkUpdateIfChanged( $hash, "mute","on");
  890. }
  891. }
  892. else {
  893. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no mute could be extracted";
  894. }
  895. }
  896. # unmute
  897. elsif ( $service eq "unmute" ) {
  898. if (@ans[0]) {
  899. if (index(lc(@ans[0]), "ok") != -1) {
  900. readingsBulkUpdateIfChanged( $hash, "mute","off");
  901. }
  902. }
  903. else {
  904. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no mute could be extracted";
  905. }
  906. }
  907. # model
  908. elsif ( $service eq "model" ) {
  909. if (@ans[0]) {
  910. readingsBulkUpdateIfChanged( $hash, "model",@ans[0]);
  911. }
  912. else {
  913. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no model could be extracted";
  914. }
  915. }
  916. # timerlist
  917. elsif ( $service eq "timerlist" ) {
  918. my $channellistname;
  919. my $timernumber;
  920. my $timerrepeat;
  921. my $timertyp;
  922. my $timerannounceTime;
  923. my $timerstartTime;
  924. my $timerstopTime;
  925. my $timername;
  926. my $i = 0;
  927. my $c = 0;
  928. my $d = 0;
  929. my $timermaxcount = ReadingsVal( $name, "timer_maxcount", 1 );
  930. my $neutrinotime = ReadingsVal( $name, "time_raw_now", "" );
  931. if ($data ne "empty") {
  932. foreach $line (@ans) {
  933. if (index($line, "",6) != -1) {
  934. my @timerlist = split (/ /s, $line);
  935. $timernumber = @timerlist[0];
  936. $timertyp = @timerlist[1];
  937. $timerrepeat = @timerlist[2];
  938. $timerannounceTime = @timerlist[4];
  939. $timerstartTime = @timerlist[5];
  940. $timerstopTime = @timerlist[6];
  941. #2017.07.12 - Nur Änderungen schreiben
  942. if (ReadingsVal( $name, "timer$i", "0" ) ne $line ) {
  943. readingsBulkUpdateIfChanged( $hash, "timer$i", $line );
  944. readingsBulkUpdateIfChanged( $hash, "timer$i" . "number", $timernumber );
  945. # timertyp
  946. if ($timertyp eq "1") {$timertyp = "shutdown"}
  947. elsif ($timertyp eq "2") {$timertyp = "nextprogram"}
  948. elsif ($timertyp eq "3") {$timertyp = "zapto"}
  949. elsif ($timertyp eq "4") {$timertyp = "standby"}
  950. elsif ($timertyp eq "5") {$timertyp = "record"}
  951. elsif ($timertyp eq "6") {$timertyp = "remind"}
  952. elsif ($timertyp eq "7") {$timertyp = "sleeptimer"}
  953. elsif ($timertyp eq "8") {$timertyp = "exec_plugin"}
  954. else {$timertyp = "unknown"}
  955. readingsBulkUpdateIfChanged( $hash, "timer$i" . "typ", $timertyp );
  956. # timer repeat
  957. if ($timerrepeat eq "0") {$timerrepeat = "once"}
  958. elsif ($timerrepeat eq "1") {$timerrepeat = "daily"}
  959. elsif ($timerrepeat eq "2") {$timerrepeat = "weekly"}
  960. elsif ($timerrepeat eq "3") {$timerrepeat = "biweekly"}
  961. elsif ($timerrepeat eq "4") {$timerrepeat = "fourweekly"}
  962. elsif ($timerrepeat eq "5") {$timerrepeat = "monthly"}
  963. elsif ($timerrepeat eq "6") {$timerrepeat = "beeventdescription"}
  964. else {$timerrepeat = "weekdays"}
  965. readingsBulkUpdateIfChanged( $hash, "timer$i" . "repeat", $timerrepeat );
  966. # timer repcount
  967. readingsBulkUpdateIfChanged( $hash, "timer$i" . "repcount", @timerlist[3] );
  968. # announceTime
  969. if ($timerannounceTime eq "0") {readingsBulkUpdateIfChanged( $hash, "timer$i" . "manualrecord", "" );}
  970. else {
  971. my $date = localtime($timerannounceTime)->strftime('%F %T');
  972. readingsBulkUpdateIfChanged( $hash, "timer$i" . "announceTime", $date );
  973. }
  974. # startTime
  975. my $date = localtime($timerstartTime)->strftime('%F %T');
  976. readingsBulkUpdateIfChanged( $hash, "timer$i" . "startTime", $date );
  977. # stopTime
  978. my $date = localtime($timerstopTime)->strftime('%F %T');
  979. readingsBulkUpdateIfChanged( $hash, "timer$i" . "stopTime", $date );
  980. # timer name
  981. $timername = "";
  982. $c = 0;
  983. foreach (@timerlist) {
  984. if ($c > 6){
  985. if ($timername ne "") {$timername = $timername . " " . @timerlist[$c]} else {$timername = @timerlist[$c]}
  986. }
  987. $c++;
  988. }
  989. readingsBulkUpdateIfChanged( $hash, "timer$i" . "name", $timername );
  990. }
  991. # find running record
  992. if ($neutrinotime > $timerstartTime && $neutrinotime < $timerstopTime) {
  993. readingsBulkUpdateIfChanged( $hash, "recordchannel", $timername );
  994. NEUTRINO_SendCommand( $hash, "epginforecord","");
  995. }
  996. $i++;
  997. }
  998. }
  999. }
  1000. # timer count
  1001. #2017.07.12 - Nur Änderungen schreiben
  1002. readingsBulkUpdateIfChanged( $hash, "timer_count", $i );
  1003. # timer maxcount
  1004. if ($timermaxcount <= $i) {
  1005. #2017.07.12 - Nur Änderungen schreiben
  1006. readingsBulkUpdateIfChanged( $hash, "timer_maxcount", $i );
  1007. }
  1008. else {
  1009. # detele not used timer
  1010. while ($d < $timermaxcount) {
  1011. if ($d > $i -1 ) {
  1012. foreach ( "","announceTime","name","number","repcount","repeat","startTime","stopTime","typ", ) {
  1013. readingsBulkUpdateIfChanged( $hash, "timer" . $d . $_, "-" );
  1014. }
  1015. }
  1016. $d++;
  1017. }
  1018. }
  1019. }
  1020. # EPG informations (record)
  1021. elsif ( $service eq "epginforecord" ) {
  1022. my $readvalue;
  1023. my $neutrinotime = ReadingsVal( $name, "time_raw_now", "" );
  1024. my $readnumber = 0;
  1025. my $line;
  1026. if ( ref($return) eq "HASH"
  1027. && defined( $return->{channel_id} ) )
  1028. {
  1029. if (defined( $return->{prog} ) ) {
  1030. #egp stop time serach
  1031. my $arr_size = @{ $return->{prog} };
  1032. my $i = 0;
  1033. while ( $i < $arr_size ) {
  1034. $readvalue = $return->{prog}[$i]{stop_sec};
  1035. if ($readvalue > $neutrinotime){
  1036. $readnumber = $i;
  1037. last;
  1038. }
  1039. $i++;
  1040. }
  1041. # recordtitle
  1042. $readvalue = $return->{prog}[$readnumber]{description};
  1043. readingsBulkUpdateIfChanged( $hash, "recordtitle",$readvalue);
  1044. }
  1045. }
  1046. else {
  1047. Log3 $name, 5,
  1048. "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no record epg information could be found";
  1049. }
  1050. }
  1051. # channel (ID)
  1052. elsif ( $service eq "zapto" ) {
  1053. if (@ans[0]) {
  1054. if (@ans[0] eq 'ok') {
  1055. # Umschalten eines Sender erkannt / Aktuellen Sender abfragen!
  1056. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] detect switch channel";
  1057. NEUTRINO_SendCommand( $hash, "zapto" );
  1058. }
  1059. else {
  1060. # Prüfen ob div. Informationen aktualisiert werden müssen
  1061. if (ReadingsVal( $name, "channel_id", "0" ) ne @ans[0] ) {
  1062. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] detect change OLD " . ReadingsVal( $name, "channel_id", "0" );
  1063. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] detect change NEW @ans[0]";
  1064. readingsBulkUpdateIfChanged( $hash, "channel_id", @ans[0] );
  1065. NEUTRINO_SendCommand( $hash, "epginfo" );
  1066. NEUTRINO_SendCommand( $hash, "build_live_url" ); #2017.07.12 - channel_url wird nur beim Senderwechsel aktualisiert!
  1067. NEUTRINO_SendCommand( $hash, "getmode" ); #2017.07.12 - Mode wird nur beim Senderwechsel aktualisiert!
  1068. }
  1069. else {
  1070. # 2017.07.12 - EPGInfo aktualisieren wenn die aktuelle Sendeung zu ende ist
  1071. if ($UnixDate > ReadingsVal( $name, "egp_current_stop_sec", "0" ) ) {
  1072. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] epginfo detect change";
  1073. NEUTRINO_SendCommand( $hash, "epginfo" );
  1074. }
  1075. }
  1076. }
  1077. }
  1078. else {
  1079. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no ID could be extracted";
  1080. }
  1081. }
  1082. # stream URL
  1083. elsif ( $service eq "build_live_url" ) {
  1084. if (@ans[0]) {
  1085. readingsBulkUpdateIfChanged( $hash, "channel_url", @ans[0] );
  1086. }
  1087. else {
  1088. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no build_live_url could be extracted";
  1089. }
  1090. }
  1091. # Mode TV/Radio
  1092. elsif ( $service eq "getmode" ) {
  1093. if (@ans[0]) {
  1094. if (index(lc(@ans[0]), "tv") != -1) {
  1095. readingsBulkUpdateIfChanged( $hash, "input","tv");
  1096. }
  1097. elsif(index(lc(@ans[0]), "radio") != -1) {
  1098. readingsBulkUpdateIfChanged( $hash, "input","radio");
  1099. }
  1100. else{
  1101. readingsBulkUpdateIfChanged( $hash, "input", "-" )
  1102. }
  1103. }
  1104. else {
  1105. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no inputmode could be extracted";
  1106. }
  1107. }
  1108. # Mode TV/Radio
  1109. elsif ( $service eq "recordmode" ) {
  1110. if (@ans[0]) {
  1111. if (index(lc(@ans[0]), "on") != -1) {
  1112. #2017.07.12 - Nur bei einer Aenderung schreiben
  1113. readingsBulkUpdateIfChanged( $hash, "recordmode","on");
  1114. }
  1115. elsif(index(lc(@ans[0]), "off") != -1) {
  1116. #2017.07.12 - Nur bei einer Aenderung schreiben
  1117. readingsBulkUpdateIfChanged( $hash, "recordmode","off");
  1118. }
  1119. else{
  1120. readingsBulkUpdateIfChanged( $hash, "recordmode", "-" )
  1121. }
  1122. }
  1123. else {
  1124. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no recordmode could be extracted";
  1125. }
  1126. }
  1127. # EPG informations
  1128. elsif ( $service eq "epginfo" ) {
  1129. my $reading;
  1130. my $readingname;
  1131. my $readvalue;
  1132. my $neutrinotime = ReadingsVal( $name, "time_raw_now", "" );
  1133. my $readnumber = 0;
  1134. if ( ref($return) eq "HASH"
  1135. && defined( $return->{channel_id} ) )
  1136. {
  1137. # channel_Name
  1138. $readvalue = $return->{channel_name};
  1139. readingsBulkUpdateIfChanged( $hash, "channel_name",$readvalue);
  1140. # channel displayname
  1141. $readvalue =~ s/\s/_/g;
  1142. readingsBulkUpdateIfChanged( $hash, "channel",$readvalue);
  1143. if(ref($return->{prog}) eq 'ARRAY') {
  1144. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ARRAY!!!" . ref($return->{prog});
  1145. }else {Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ARRAY!!! NOT" . ref($return->{prog});}
  1146. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] Data = $data";
  1147. if (defined( $return->{prog} ) && ref($return->{prog}) eq 'ARRAY' ) {
  1148. #egp stop time serach
  1149. my $arr_size = @{ $return->{prog} };
  1150. my $i = 0;
  1151. while ( $i < $arr_size ) {
  1152. $readvalue = $return->{prog}[$i]{stop_sec};
  1153. if ($readvalue > $neutrinotime){
  1154. $readnumber = $i;
  1155. readingsBulkUpdateIfChanged( $hash, "egp_current_number", $readnumber);
  1156. last;
  1157. }
  1158. $i++;
  1159. }
  1160. # 2017.07.27 - BUG NEUTRINO / Umschalten wenn EGP und CHANNEL_ID nicht passen!
  1161. if (ReadingsVal( $name, "channel_id", "" ) ne $return->{prog}[$readnumber]{channel_id}) {
  1162. Log3 $name, 0, "NEUTRINO [BUG NEUTRINO] EPG channel_id = " . $return->{prog}[$readnumber]{channel_id} ;
  1163. NEUTRINO_SendCommand( $hash, "zapto", $return->{prog}[$readnumber]{channel_id} );
  1164. }
  1165. # currentTitel
  1166. $readvalue = $return->{prog}[$readnumber]{description};
  1167. readingsBulkUpdateIfChanged( $hash, "currentTitle",$readvalue);
  1168. foreach ( "eventid","description","info1","info2","start_t","stop_t","duration_min","date","channel_id","stop_sec","start_sec", ) {
  1169. $reading = $_;
  1170. if ($_ eq "eventid") {$readingname = $reading ;} else {$readingname = "egp_current_" . $_;}
  1171. if ( defined( $return->{prog}[$readnumber]{$reading} )
  1172. && lc( $return->{prog}[$readnumber]{$reading} ) ne "n/a" )
  1173. {
  1174. $readvalue = $return->{prog}[$readnumber]{$reading};
  1175. $readvalue =~ s/\n//g;
  1176. if ($readvalue) {
  1177. readingsBulkUpdateIfChanged( $hash, $readingname, $readvalue );
  1178. }
  1179. else {
  1180. readingsBulkUpdateIfChanged( $hash, $readingname, "-" );
  1181. }
  1182. }
  1183. else {
  1184. readingsBulkUpdateIfChanged( $hash, $readingname, "-" );
  1185. }
  1186. }
  1187. }else{
  1188. readingsBulkUpdateIfChanged( $hash, "eventid", "-" );
  1189. readingsBulkUpdateIfChanged( $hash, "egp_current_description", "-" );
  1190. readingsBulkUpdateIfChanged( $hash, "egp_current_info1", "-" );
  1191. readingsBulkUpdateIfChanged( $hash, "egp_current_info2", "-" );
  1192. readingsBulkUpdateIfChanged( $hash, "egp_current_start_t", "-" );
  1193. readingsBulkUpdateIfChanged( $hash, "egp_current_stop_t", "-" );
  1194. readingsBulkUpdateIfChanged( $hash, "egp_current_duration_min", "-" );
  1195. readingsBulkUpdateIfChanged( $hash, "egp_current_date", "-" );
  1196. readingsBulkUpdateIfChanged( $hash, "egp_current_channel_id", "-" );
  1197. readingsBulkUpdateIfChanged( $hash, "egp_current_stop_sec", "-" );
  1198. readingsBulkUpdateIfChanged( $hash, "egp_current_start_sec", "-" );
  1199. readingsBulkUpdateIfChanged( $hash, "egp_current_number", "-" );
  1200. readingsBulkUpdateIfChanged( $hash, "currentTitle", "-" );
  1201. }
  1202. }
  1203. else {
  1204. Log3 $name, 5,
  1205. "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no epg information could be found";
  1206. }
  1207. }
  1208. # signal
  1209. elsif ( $service eq "signal" ) {
  1210. my $signalvalue;
  1211. if (@ans[0]) {
  1212. foreach $line (@ans) {
  1213. foreach ("sig","snr","ber",) {
  1214. if (index(lc($line), $_) != -1) {
  1215. $signalvalue = substr($line,index($line,":")+1);
  1216. #2017.07.12 - Nur bei einer Aenderung schreiben
  1217. readingsBulkUpdateIfChanged( $hash, "$_",$signalvalue);
  1218. }
  1219. }
  1220. }
  1221. }
  1222. else {
  1223. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no signal could be extracted";
  1224. }
  1225. }
  1226. # Boxinformations
  1227. elsif ( $service eq "version" ) {
  1228. my $versionvalue;
  1229. my $versionname;
  1230. if (@ans[0]) {
  1231. foreach $line (@ans) {
  1232. if (index(lc($line), "=") != -1) {
  1233. $versionvalue = substr($line,index($line,"=")+1);
  1234. $versionname = substr($line,0,index($line,"="));
  1235. readingsBulkUpdateIfChanged( $hash, "image_" . "$versionname",$versionvalue);
  1236. }
  1237. }
  1238. }
  1239. else {
  1240. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] ERROR: no signal could be extracted";
  1241. }
  1242. }
  1243. # all other command results
  1244. else {
  1245. NEUTRINO_GetStatus( $hash, 1 );
  1246. }
  1247. }
  1248. else{
  1249. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_ReceiveCommand] [$service] no data!";
  1250. }
  1251. readingsEndUpdate( $hash, 1 );
  1252. NEUTRINO_HD_HandleCmdQueue($hash);
  1253. undef $return;
  1254. return;
  1255. }
  1256. ###################################
  1257. sub NEUTRINO_Undefine($$) {
  1258. my ( $hash, $arg ) = @_;
  1259. my $name = $hash->{NAME};
  1260. Log3 $name, 5, "NEUTRINO $name [NEUTRINO_Undefine] called function";
  1261. # Stop the internal GetStatus-Loop and exit
  1262. RemoveInternalTimer($hash);
  1263. return;
  1264. }
  1265. 1;
  1266. =pod
  1267. =item device
  1268. =item summary control for NEUTRINO based receivers via network connection
  1269. =item summary_DE Steuerung von NEUTRINO basierte Receiver &uuml;ber das Netzwerk
  1270. =begin html
  1271. <p>
  1272. <a name="NEUTRINO" id="NEUTRINO"></a>
  1273. </p>
  1274. <h3>
  1275. NEUTRINO
  1276. </h3>
  1277. <ul>
  1278. <a name="NEUTRINOdefine" id="NEUTRINOdefine"></a> <b>Define</b>
  1279. <ul>
  1280. <code>define &lt;name&gt; NEUTRINO &lt;ip-address-or-hostname&gt; [[[[&lt;port&gt;] [&lt;poll-interval&gt;]] [&lt;http-user&gt;]] [&lt;http-password&gt;]]</code><br>
  1281. <br>
  1282. This module controls NEUTRINO based devices like Coolstream receiver via network connection.<br>
  1283. <br>
  1284. Defining an NEUTRINO device will schedule an internal task (interval can be set with optional parameter &lt;poll-interval&gt; in seconds, if not set, the value is 45 seconds), which periodically reads the status of the device and triggers notify/filelog commands.<br>
  1285. <br>
  1286. Example:<br>
  1287. <ul>
  1288. <code>define SATReceiver NEUTRINO 192.168.0.10<br>
  1289. <br>
  1290. # With custom port<br>
  1291. define SATReceiver NEUTRINO 192.168.0.10 8080<br>
  1292. <br>
  1293. # With custom interval of 20 seconds<br>
  1294. define SATReceiver NEUTRINO 192.168.0.10 80 20<br>
  1295. <br>
  1296. # With HTTP user credentials<br>
  1297. define SATReceiver NEUTRINO 192.168.0.10 80 20 root secret</code>
  1298. </ul>
  1299. </ul>
  1300. <br>
  1301. <br>
  1302. <a name="NEUTRINOset" id="NEUTRINOset"></a> <b>Set</b>
  1303. <ul>
  1304. <code>set &lt;name&gt; &lt;command&gt; [&lt;parameter&gt;]</code><br>
  1305. <br>
  1306. Currently, the following commands are defined.<br>
  1307. <ul>
  1308. <li>
  1309. <b>on</b> &nbsp;&nbsp;-&nbsp;&nbsp; powers on the device (standby mode)
  1310. </li>
  1311. <li>
  1312. <b>off</b> &nbsp;&nbsp;-&nbsp;&nbsp; turns the device in standby mode
  1313. </li>
  1314. <li>
  1315. <b>toggle</b> &nbsp;&nbsp;-&nbsp;&nbsp; switch between on and off (standby mode)
  1316. </li>
  1317. <li>
  1318. <b>shutdown</b> &nbsp;&nbsp;-&nbsp;&nbsp; poweroff the device
  1319. </li>
  1320. <li>
  1321. <b>reboot</b> &nbsp;&nbsp;-&nbsp;&nbsp;reboots the device
  1322. </li>
  1323. <li>
  1324. <b>channel</b> &nbsp;&nbsp;-&nbsp;&nbsp; zap to specific channel
  1325. </li>
  1326. <li>
  1327. <b>volume</b> 0...100 &nbsp;&nbsp;-&nbsp;&nbsp; set the volume level in percentage
  1328. </li>
  1329. <li>
  1330. <b>mute</b> on,off,toggle &nbsp;&nbsp;-&nbsp;&nbsp; controls volume to mute
  1331. </li>
  1332. <li>
  1333. <b>statusRequest</b> &nbsp;&nbsp;-&nbsp;&nbsp; requests the current status of the device
  1334. </li>
  1335. <li>
  1336. <b>remoteControl</b> UP,DOWN,... &nbsp;&nbsp;-&nbsp;&nbsp; sends remote control command<br />
  1337. </li>
  1338. <li>
  1339. <b>showText</b> text &nbsp;&nbsp;-&nbsp;&nbsp; sends info messages to be displayed on screen
  1340. </li>
  1341. <li>
  1342. <b>showtextwithbutton</b> &nbsp;&nbsp;-&nbsp;&nbsp; sends info messagees to be displayed on screen with OK button
  1343. </li>
  1344. <br>
  1345. <br>
  1346. <br>
  1347. </ul>
  1348. </ul>
  1349. <a name="NEUTRINOget" id="NEUTRINOget"></a> <b>Get</b>
  1350. <ul>
  1351. <code>get &lt;name&gt; &lt;what&gt;</code><br>
  1352. <br>
  1353. Currently, the following commands are defined:<br>
  1354. <br>
  1355. <ul>
  1356. <code>channel<br>
  1357. channelurl<br>
  1358. currentTitle<br>
  1359. input<br>
  1360. mute<br>
  1361. power<br>
  1362. volume<br></code>
  1363. </ul>
  1364. </ul><br>
  1365. <br>
  1366. <a name="NEUTRINOattr" id="NEUTRINOattr"></a> <b>Attributes</b><br>
  1367. <ul>
  1368. <ul>
  1369. <li>
  1370. <b>disable</b> - Disable polling (true/false)
  1371. </li>
  1372. <li>
  1373. <b>http-noshutdown</b> - Set FHEM-internal HttpUtils connection close behaviour (defaults=0)
  1374. </li>
  1375. <li>
  1376. <b>https</b> - Access box via secure HTTP (true/false)
  1377. </li>
  1378. <li>
  1379. <b>timeout</b> - Set different polling timeout in seconds (default=2)
  1380. </li>
  1381. </ul>
  1382. </ul><br>
  1383. <br>
  1384. <br>
  1385. <b>Generated Readings:</b><br>
  1386. <ul>
  1387. <ul>
  1388. <li>
  1389. <b>ber</b> - Shows Bit Error Rate for current channel
  1390. </li>
  1391. <li>
  1392. <b>bouquetnr</b> - Shows bouquet number for current channel
  1393. </li>
  1394. <li>
  1395. <b>channel</b> - Shows the service name of current channel
  1396. </li>
  1397. <li>
  1398. <b>channel_id</b> - Shows the channel id of current channel
  1399. </li>
  1400. <li>
  1401. <b>channel_name</b> - Shows the channel name of current channel
  1402. </li>
  1403. <li>
  1404. <b>channel_url</b> - Shows the channel url of current channel (use with vlc player)
  1405. </li>
  1406. <li>
  1407. <b>currentTitle</b> - Shows the title of the running event
  1408. </li>
  1409. <li>
  1410. <b>epg_current_channel_id</b> - Shows the channel id of epg information
  1411. </li>
  1412. <li>
  1413. <b>epg_current_date</b> - Shows the date of epg information
  1414. </li>
  1415. <li>
  1416. <b>egp_current_description</b> - Shows the current description of the current program
  1417. </li>
  1418. <li>
  1419. <b>egp_current_duration_min</b> - Shows the current duration of the current program
  1420. </li>
  1421. <li>
  1422. <b>egp_current_info1</b> - Displays the current information of the current program
  1423. </li>
  1424. <li>
  1425. <b>egp_current_info2</b> - Displays the current information of the current program
  1426. </li>
  1427. <li>
  1428. <b>egp_current_number</b> - Displays the current number(epg) of the current program
  1429. </li>
  1430. <li>
  1431. <b>egp_current_start_sec</b> - Shows the current start time of the current program (ticks)
  1432. </li>
  1433. <li>
  1434. <b>egp_current_start_t</b> - Shows the current start time of the current program
  1435. </li>
  1436. <li>
  1437. <b>egp_current_stop_sec</b> - Shows the current stop time of the current program (ticks)
  1438. </li>
  1439. <li>
  1440. <b>egp_current_stop_t</b> - Shows the current stop time of the current program
  1441. </li>
  1442. <li>
  1443. <b>eventid</b> - Shows the current event id of the current program
  1444. </li>
  1445. <li>
  1446. <b>image_*</b> - Shows image information of NEUTRINO
  1447. </li>
  1448. <li>
  1449. <b>input</b> - Shows currently used input
  1450. </li>
  1451. <li>
  1452. <b>mute</b> - Reports the mute status of the device (can be "on" or "off")
  1453. </li>
  1454. <li>
  1455. <b>power</b> - Reports the power status of the device (can be "on" or "off")
  1456. </li>
  1457. <li>
  1458. <b>presence</b> - Reports the presence status of the receiver (can be "absent" or "present").
  1459. </li>
  1460. <li>
  1461. <b>recordmode</b> - Reports the record mode of the device (can be "on" or "off")
  1462. </li>
  1463. <li>
  1464. <b>recordmodetitle</b> - Reports the last record title
  1465. </li>
  1466. <li>
  1467. <b>sig</b> - Shows signal for current channel in percent
  1468. </li>
  1469. <li>
  1470. <b>snr</b> - Shows signal to noise for current channel in percent
  1471. </li>
  1472. <li>
  1473. <b>state</b> - Reports current power state and an absence of the device (can be "on", "off" or "standby")
  1474. </li>
  1475. <li>
  1476. <b>time_now</b> - Reports current time
  1477. </li>
  1478. <li>
  1479. <b>time_raw_now</b> - Reports current time (ticks)
  1480. </li>
  1481. <li>
  1482. <b>timerX</b> - Shows complete timer (Report from NEUTRINO)
  1483. </li>
  1484. <li>
  1485. <b>timerXannounceTime</b> - Shows announce time of the timer
  1486. </li>
  1487. <li>
  1488. <b>timerXname</b> - Shows channel name of the timer
  1489. </li>
  1490. <li>
  1491. <b>timerXnumber</b> - Shows timer number
  1492. </li>
  1493. <li>
  1494. <b>timerXrepcount</b> - Shows rep count of the timer
  1495. </li>
  1496. <li>
  1497. <b>timerXrepeat</b> - Shows repeat time of the timer
  1498. </li>
  1499. <li>
  1500. <b>timerXstartTime</b> - Shows start time of the timer
  1501. </li>
  1502. <li>
  1503. <b>timerXstopTime</b> - Shows stop time of the timer
  1504. </li>
  1505. <li>
  1506. <b>timerXtyp</b> - Shows type of the timer
  1507. </li>
  1508. <li>
  1509. <b>timer_count</b> - Shows the number of timers
  1510. </li>
  1511. <li>
  1512. <b>timer_count</b> - Shows the maximum number of timers
  1513. </li>
  1514. <li>
  1515. <b>volume</b> - Reports current volume level of the receiver in percentage values (between 0 and 100 %)
  1516. </li>
  1517. </ul>
  1518. </ul>
  1519. </ul>
  1520. =end html
  1521. =begin html_DE
  1522. <p>
  1523. <a name="NEUTRINO" id="NEUTRINO"></a>
  1524. </p>
  1525. <h3>
  1526. NEUTRINO
  1527. </h3>
  1528. <ul>
  1529. <a name="NEUTRINOdefine" id="NEUTRINOdefine"></a> <b>Define</b>
  1530. <ul>
  1531. <code>define &lt;name&gt; NEUTRINO &lt;ip-address-or-hostname&gt; [[[[&lt;port&gt;] [&lt;poll-interval&gt;]] [&lt;http-user&gt;]] [&lt;http-password&gt;]]</code><br>
  1532. <br>
  1533. Dieses Modul steuert NEUTRINO basierte Ger&auml;te wie die Coolstream &uuml;ber eine Netzwerkverbindung.<br>
  1534. <br>
  1535. F&uuml;r definierte NEUTRINO Ger&auml;te wird ein interner Task angelegt, welcher periodisch die Readings aktualisiert. Der Standartpollintervall ist 45 Sekunden.<br>
  1536. <br>
  1537. Beispiele:<br>
  1538. <ul>
  1539. <code>define SATReceiver NEUTRINO 192.168.0.10<br>
  1540. <br>
  1541. # Alternativer Port<br>
  1542. define SATReceiver NEUTRINO 192.168.0.10 8080<br>
  1543. <br>
  1544. # Alternativer poll intervall von 20 seconds<br>
  1545. define SATReceiver NEUTRINO 192.168.0.10 80 20<br>
  1546. <br>
  1547. # Mit HTTP Benutzer Zugangsdaten<br>
  1548. define SATReceiver NEUTRINO 192.168.0.10 80 20 root secret</code>
  1549. </ul>
  1550. </ul><br>
  1551. <br>
  1552. <a name="NEUTRINOset" id="NEUTRINOset"></a> <b>Set</b>
  1553. <ul>
  1554. <code>set &lt;name&gt; &lt;command&gt; [&lt;parameter&gt;]</code><br>
  1555. <br>
  1556. Aktuell gibt es folgende Befehle.<br>
  1557. <ul>
  1558. <li>
  1559. <b>on</b> &nbsp;&nbsp;-&nbsp;&nbsp; Schaltet das Ger&auml;t aus dem Standby wieder an
  1560. </li>
  1561. <li>
  1562. <b>off</b> &nbsp;&nbsp;-&nbsp;&nbsp; Schaltet das Ger&auml;t in den Standby
  1563. </li>
  1564. <li>
  1565. <b>toggle</b> &nbsp;&nbsp;-&nbsp;&nbsp; Ein- und Ausschalten zwischen Standby
  1566. </li>
  1567. <li>
  1568. <b>shutdown</b> &nbsp;&nbsp;-&nbsp;&nbsp; Schaltet das Ger&auml;t aus
  1569. </li>
  1570. <li>
  1571. <b>reboot</b> &nbsp;&nbsp;-&nbsp;&nbsp;Neustart des Ger&auml;tes
  1572. </li>
  1573. <li>
  1574. <b>channel</b> &nbsp;&nbsp;-&nbsp;&nbsp;Schaltet auf den angegebenen Kanal
  1575. </li>
  1576. <li>
  1577. <b>volume</b> 0...100 &nbsp;&nbsp;-&nbsp;&nbsp; &Auml;ndert die Lautst&auml;rke in Prozent
  1578. </li>
  1579. <li>
  1580. <b>mute</b> on,off,toggle &nbsp;&nbsp;-&nbsp;&nbsp; Steuert Lautst&auml;rke "stumm"
  1581. </li>
  1582. <li>
  1583. <b>statusRequest</b> &nbsp;&nbsp;-&nbsp;&nbsp; Fordert den aktuellen Status des Ger&auml;tes an
  1584. </li>
  1585. <li>
  1586. <b>remoteControl</b> UP,DOWN,... &nbsp;&nbsp;-&nbsp;&nbsp; Sendet Fernsteuerungsbefehle<br />
  1587. </li>
  1588. <li>
  1589. <b>showText</b> text &nbsp;&nbsp;-&nbsp;&nbsp; Sendet eine Textnachricht
  1590. </li>
  1591. <li>
  1592. <b>showtextwithbutton</b> &nbsp;&nbsp;-&nbsp;&nbsp; Sendet eine Textnachricht mit OK Button
  1593. </li>
  1594. <br>
  1595. </ul>
  1596. </ul>
  1597. <br>
  1598. <br>
  1599. <a name="NEUTRINOget" id="NEUTRINOget"></a> <b>Get</b>
  1600. <ul>
  1601. <code>get &lt;name&gt; &lt;what&gt;</code><br>
  1602. <br>
  1603. Aktuell gibt es folgende Befehle.<br>
  1604. <br>
  1605. <ul>
  1606. <code>channel<br>
  1607. channelurl<br>
  1608. currentTitle<br>
  1609. input<br>
  1610. mute<br>
  1611. power<br>
  1612. volume<br></code>
  1613. </ul>
  1614. </ul><br>
  1615. <br>
  1616. <a name="NEUTRINOattr" id="NEUTRINOattr"></a> <b>Attributes</b><br>
  1617. <ul>
  1618. <ul>
  1619. <li>
  1620. <b>disable</b> - Schaltet das Polling aus (true/false)
  1621. </li>
  1622. <li>
  1623. <b>http-noshutdown</b> - Setzt FHEM-internal HttpUtils Verbindung offen halten (defaults=0)
  1624. </li>
  1625. <li>
  1626. <b>https</b> - Zugriff &uuml;ber HTTPS aktivieren (true/false)
  1627. </li>
  1628. <li>
  1629. <b>timeout</b> - Setzen des Timeout der HTTP Verbindung (default=2)
  1630. </li>
  1631. </ul>
  1632. </ul><br>
  1633. <br>
  1634. <br>
  1635. <b>Generelle Readings:</b><br>
  1636. <ul>
  1637. <ul>
  1638. <li>
  1639. <b>ber</b> - Zeigt die Bit Error Rate vom aktuellen Kanal
  1640. </li>
  1641. <li>
  1642. <b>bouquetnr</b> - Zeigt die aktuelle Bouquet Nummer vom aktuellen Kanal
  1643. </li>
  1644. <li>
  1645. <b>channel</b> - Zeigt den aktuellen Servicenamen vom aktuellen Kanal
  1646. </li>
  1647. <li>
  1648. <b>channel_id</b> - Zeigt die aktuelle Kanal ID vom aktuellen Kanal
  1649. </li>
  1650. <li>
  1651. <b>channel_name</b> - Zeigt den aktuellen Kanal Namen
  1652. </li>
  1653. <li>
  1654. <b>channel_url</b> - Zeigt die aktuelle Kanal URL, welche im Vlc Player zum Streamen verwendet werden kann
  1655. </li>
  1656. <li>
  1657. <b>currentTitle</b> - Zeigt den aktuellen Titel der aktuellen Sendung an
  1658. </li>
  1659. <li>
  1660. <b>epg_current_channel_id</b> - Zeigt die Kanal ID von aktuellen EPG an
  1661. </li>
  1662. <li>
  1663. <b>epg_current_date</b> - Zeigt das Datum des aktuellen EPGs an
  1664. </li>
  1665. <li>
  1666. <b>egp_current_description</b> - Zeigt die aktuelle Beschreibung der aktuellen Sendung an
  1667. </li>
  1668. <li>
  1669. <b>egp_current_duration_min</b> - Zeigt die Dauer der aktuellen Sendung an
  1670. </li>
  1671. <li>
  1672. <b>egp_current_info1</b> - Zeigt die Information Teil 1 der aktuellen Sendung an
  1673. </li>
  1674. <li>
  1675. <b>egp_current_info2</b> - Zeigt die Information Teil 2 der aktuellen Sendung an
  1676. </li>
  1677. <li>
  1678. <b>egp_current_number</b> - Zeigt die EPG Nummer der aktuellen Sendung an
  1679. </li>
  1680. <li>
  1681. <b>egp_current_start_sec</b> - Zeigt die Startzeit der aktuellen Sendung an (ticks)
  1682. </li>
  1683. <li>
  1684. <b>egp_current_start_t</b> - Zeigt die Startzeit der aktuellen Sendung an
  1685. </li>
  1686. <li>
  1687. <b>egp_current_stop_sec</b> - Zeigt die Stopzeit der aktuellen Sendung an (ticks)
  1688. </li>
  1689. <li>
  1690. <b>egp_current_stop_t</b> - Zeigt die Stopzeit der aktuellen Sendung an
  1691. </li>
  1692. <li>
  1693. <b>eventid</b> - Zeigt die aktuelle Event ID von der aktuellen Sendung an
  1694. </li>
  1695. <li>
  1696. <b>image_*</b> - Zeigt Image Informationen von NEUTRINO
  1697. </li>
  1698. <li>
  1699. <b>input</b> - Zeigt den aktuellen Input an (TV/Radio)
  1700. </li>
  1701. <li>
  1702. <b>mute</b> - Zeigt aktuellen Mute Status ("on" oder "off")
  1703. </li>
  1704. <li>
  1705. <b>power</b> - Zeigt aktuellen Power Status ("on" oder "off")
  1706. </li>
  1707. <li>
  1708. <b>presence</b> - Zeigt den aktuellen presence Status an ("absent" oder "present").
  1709. </li>
  1710. <li>
  1711. <b>recordmode</b> - Zeigt an ob die Box gerade eine Aufnahme macht ("on" oder "off")
  1712. </li>
  1713. <li>
  1714. <b>recordmodetitle</b> - Zeigt den letzten Aufnahme Titel an
  1715. </li>
  1716. <li>
  1717. <b>sig</b> - Zeigt Signalst&auml;rke vom aktuellen Sender an
  1718. </li>
  1719. <li>
  1720. <b>snr</b> - Zeigt Singal Noise vom aktuellen Sender an
  1721. </li>
  1722. <li>
  1723. <b>state</b> - Zeigt den aktuellen Status an ("on", "off" oder "standby")
  1724. </li>
  1725. <li>
  1726. <b>time_now</b> - Aktuelle Uhrzeit
  1727. </li>
  1728. <li>
  1729. <b>time_raw_now</b> - Aktuelle Uhrzeit (ticks)
  1730. </li>
  1731. <li>
  1732. <b>timerX</b> - Zeigt den kompletten Timer an (Report from NEUTRINO)
  1733. </li>
  1734. <li>
  1735. <b>timerXannounceTime</b> - Zeigt die Ank&uuml;ndigungszeit des Timers an
  1736. </li>
  1737. <li>
  1738. <b>timerXname</b> - Zeigt den Aufnahmekanal des Timers an
  1739. </li>
  1740. <li>
  1741. <b>timerXnumber</b> - Zeigt die Timernummer an
  1742. </li>
  1743. <li>
  1744. <b>timerXrepcount</b> - Zeigt den Rep. Counter des Timers an
  1745. </li>
  1746. <li>
  1747. <b>timerXrepeat</b> - Zeigt die Wiederholungszeit an
  1748. </li>
  1749. <li>
  1750. <b>timerXstartTime</b> - Zeigt die Startzeit des Timers an
  1751. </li>
  1752. <li>
  1753. <b>timerXstopTime</b> - Zeigt die Stopzeit des Timers an
  1754. </li>
  1755. <li>
  1756. <b>timerXtyp</b> - Zeigt den Typ des Timers an
  1757. </li>
  1758. <li>
  1759. <b>timer_count</b> - Zeigt die Anzahl der aktuellen Timer an
  1760. </li>
  1761. <li>
  1762. <b>timer_count</b> - Zeitg die max. Anzahl der Timer an (wird intern verwendet)
  1763. </li>
  1764. <li>
  1765. <b>volume</b> - Zeit die aktuelle Lautst&auml;rke an (zwischen 0 und 100 %)
  1766. </li>
  1767. </ul>
  1768. </ul>
  1769. </ul>
  1770. =end html_DE
  1771. =cut