72_FRITZBOX.pm 215 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552
  1. ###############################################################
  2. # $Id: 72_FRITZBOX.pm 16285 2018-02-27 17:58:54Z tupol $
  3. #
  4. # 72_FRITZBOX.pm
  5. #
  6. # (c) 2014 Torsten Poitzsch
  7. # (c) 2014-2016 tupol http://forum.fhem.de/index.php?action=profile;u=5432
  8. #
  9. # This module handles the Fritz!Box router and the Fritz!Phone MT-F and C4
  10. #
  11. # Copyright notice
  12. #
  13. # This script is free software; you can redistribute it and/or modify
  14. # it under the terms of the GNU General Public License as published by
  15. # the Free Software Foundation; either version 2 of the License, or
  16. # (at your option) any later version.
  17. #
  18. # The GNU General Public License can be found at
  19. # http://www.gnu.org/copyleft/gpl.html.
  20. # A copy is found in the text file GPL.txt and important notices to the license
  21. # from the author is found in LICENSE.txt distributed with these scripts.
  22. #
  23. # This script is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU General Public License for more details.
  27. #
  28. # This copyright notice MUST APPEAR in all copies of the script!
  29. #
  30. ##############################################################################
  31. #
  32. # define <name> FRITZBOX
  33. #
  34. ##############################################################################
  35. package main;
  36. use strict;
  37. use warnings;
  38. use Blocking;
  39. my $missingModul = "";
  40. my $missingModulTelnet = "";
  41. my $missingModulWeb = "";
  42. my $missingModulTR064 = "";
  43. our $FRITZBOX_TR064pwd;
  44. our $FRITZBOX_TR064user;
  45. eval "use URI::Escape;1" or $missingModul .= "URI::Escape ";
  46. eval "use MIME::Base64;1" or $missingModul .= "MIME::Base64 ";
  47. use FritzBoxUtils; ## only for web access login
  48. eval "use Net::Telnet;1" or $missingModulTelnet .= "Net::Telnet ";
  49. #sudo apt-get install libjson-perl
  50. # eval "use JSON::XS;1" or $missingModulWeb .= "JSON::XS ";
  51. eval "use JSON;1" or $missingModulWeb .= "JSON ";
  52. eval "use LWP::UserAgent;1" or $missingModulWeb .= "LWP::UserAgent ";
  53. eval "use URI::Escape;1" or $missingModulTR064 .= "URI::Escape ";
  54. # sudo apt-get install libsoap-lite-perl
  55. eval "use SOAP::Lite;1" or $missingModulTR064 .= "Soap::Lite ";
  56. eval "use Data::Dumper;1" or $missingModulTR064 .= "Data::Dumper ";
  57. sub FRITZBOX_Log($$$);
  58. sub FRITZBOX_Init($);
  59. sub FRITZBOX_Set_Cmd_Start($);
  60. sub FRITZBOX_Shell_Exec($$);
  61. sub FRITZBOX_StartRadio_Shell($@);
  62. sub FRITZBOX_StartRadio_Web($@);
  63. sub FRITZBOX_Readout_Add_Reading ($$$$@);
  64. sub FRITZBOX_Readout_Process($$);
  65. sub FRITZBOX_SendMail_Shell($@);
  66. sub FRITZBOX_SetCustomerRingTone($@);
  67. sub FRITZBOX_SetMOH($@);
  68. sub FRITZBOX_TR064_Init($$);
  69. sub FRITZBOX_Wlan_Run($);
  70. sub FRITZBOX_Web_Query($$@);
  71. our $telnet;
  72. my %fonModel = (
  73. '0x01' => "MT-D"
  74. , '0x03' => "MT-F"
  75. , '0x04' => "C3"
  76. , '0x05' => "M2"
  77. , '0x08' => "C4"
  78. );
  79. my %ringTone = qw {
  80. 0 HandsetDefault 1 HandsetInternalTone
  81. 2 HandsetExternalTon 3 Standard
  82. 4 Eighties 5 Alert
  83. 6 Ring 7 RingRing
  84. 8 News 9 CustomerRingTone
  85. 10 Bamboo 11 Andante
  86. 12 ChaCha 13 Budapest
  87. 14 Asia 15 Kullabaloo
  88. 16 silent 17 Comedy
  89. 18 Funky 19 Fatboy
  90. 20 Calypso 21 Pingpong
  91. 22 Melodica 23 Minimal
  92. 24 Signal 25 Blok1
  93. 26 Musicbox 27 Blok2
  94. 28 2Jazz
  95. 33 InternetRadio 34 MusicList
  96. };
  97. my %dialPort = qw {
  98. 1 fon1 2 fon2
  99. 3 fon3
  100. 50 allFons
  101. 60 dect1 61 dect2
  102. 62 dect3 63 dect4
  103. 64 dect5 65 dect6
  104. };
  105. my %gsmNetworkState = qw {
  106. 0 disabled 1 registered_home
  107. 2 searching 3 registration_denied
  108. 4 unknown 5 registered_roaming
  109. 6 limited_service
  110. };
  111. my %gsmTechnology = qw {
  112. 0 GPRS 1 GPRS
  113. 2 UMTS
  114. 3 EDGE
  115. 4 HSPA 5 HSPA 6 HSPA
  116. };
  117. my %ringToneNumber;
  118. while (my ($key, $value) = each %ringTone) {
  119. $ringToneNumber{lc $value}=$key;
  120. }
  121. my %alarmDays = qw{1 Mo 2 Tu 4 We 8 Th 16 Fr 32 Sa 64 Su};
  122. my %userType = qw{1 IP 2 PC-User 3 Default 4 Guest};
  123. my %mohtype = (0=>"default", 1=>"sound", 2=>"customer", "err"=>"" );
  124. my %landevice = ();
  125. # FIFO Buffer for commands
  126. my @cmdBuffer=();
  127. my $cmdBufferTimeout=0;
  128. my $ttsCmdTemplate = 'wget -U Mozilla -O "[ZIEL]" "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&prev=input&tl=[SPRACHE]&q=[TEXT]"';
  129. my $ttsLinkTemplate = 'http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&prev=input&tl=[SPRACHE]&q=[TEXT]';
  130. # VoiceRSS: http://www.voicerss.org/api/documentation.aspx
  131. my $mohUpload = '/var/tmp/fhem_moh_upload';
  132. my $mohOld = '/var/tmp/fhem_fx_moh_old';
  133. my $mohNew = '/var/tmp/fhem_fx_moh_new';
  134. #######################################################################
  135. sub FRITZBOX_Log($$$)
  136. {
  137. my ( $hash, $loglevel, $text ) = @_;
  138. my $xline = ( caller(0) )[2];
  139. my $xsubroutine = ( caller(1) )[3];
  140. my $sub = ( split( ':', $xsubroutine ) )[2];
  141. $sub =~ s/FRITZBOX_//;
  142. my $instName = ( ref($hash) eq "HASH" ) ? $hash->{NAME} : $hash;
  143. Log3 $hash, $loglevel, "FRITZBOX $instName: $sub.$xline " . $text;
  144. } # End FRITZBOX_Log
  145. #######################################################################
  146. sub FRITZBOX_Initialize($)
  147. {
  148. my ($hash) = @_;
  149. $hash->{DefFn} = "FRITZBOX_Define";
  150. $hash->{UndefFn} = "FRITZBOX_Undefine";
  151. $hash->{DeleteFn} = "FRITZBOX_Delete";
  152. $hash->{RenameFn} = "FRITZBOX_Rename";
  153. $hash->{SetFn} = "FRITZBOX_Set";
  154. $hash->{GetFn} = "FRITZBOX_Get";
  155. $hash->{AttrFn} = "FRITZBOX_Attr";
  156. $hash->{AttrList} = "allowShellCommand:0,1 "
  157. ."allowTR064Command:0,1 "
  158. ."boxUser "
  159. ."disable:0,1 "
  160. ."defaultCallerName "
  161. ."defaultUploadDir "
  162. ."forceTelnetConnection:0,1 "
  163. ."fritzBoxIP "
  164. ."INTERVAL "
  165. ."m3uFileLocal "
  166. ."m3uFileURL "
  167. ."ringWithIntern:0,1,2 "
  168. ."telnetUser "
  169. ."telnetTimeOut "
  170. ."useGuiHack:0,1 "
  171. ."userTickets "
  172. # ."ttsRessource:Google,ESpeak "
  173. .$readingFnAttributes;
  174. } # end FRITZBOX_Initialize
  175. #######################################################################
  176. sub FRITZBOX_Define($$)
  177. {
  178. my ($hash, $def) = @_;
  179. my @args = split("[ \t][ \t]*", $def);
  180. return "Usage: define <name> FRITZBOX [IP address]" if(@args <2 || @args >3);
  181. my $name = $args[0];
  182. $hash->{NAME} = $name;
  183. $hash->{HOST} = "undefined";
  184. $hash->{HOST} = $args[2] if defined $args[2];
  185. $hash->{fhem}{definedHost} = $hash->{HOST}; # to cope with old attribute definitions
  186. my $msg;
  187. # stop if certain perl moduls are missing
  188. if ( $missingModul ) {
  189. $msg = "Cannot define a FRITZBOX device. Perl modul $missingModul is missing.";
  190. FRITZBOX_Log $hash, 1, $msg;
  191. return $msg;
  192. }
  193. $hash->{STATE} = "Initializing";
  194. $hash->{INTERVAL} = 300;
  195. $hash->{fhem}{modulVersion} = '$Date: 2018-02-27 18:58:54 +0100 (Tue, 27 Feb 2018) $';
  196. $hash->{fhem}{lastHour} = 0;
  197. $hash->{fhem}{LOCAL} = 0;
  198. $hash->{helper}{TimerReadout} = $name.".Readout";
  199. $hash->{helper}{TimerCmd} = $name.".Cmd";
  200. # my $tr064Port = FRITZBOX_TR064_Init ($hash);
  201. # $hash->{SECPORT} = $tr064Port if $tr064Port;
  202. # Check APIs after fhem.cfg is processed
  203. $hash->{APICHECKED} = 0;
  204. $hash->{fhem}->{is_double_wlan} = -1;
  205. $hash->{LUAQUERY} = -1;
  206. $hash->{REMOTE} = -1;
  207. $hash->{TELNET} = -1;
  208. $hash->{TR064} = -1;
  209. $hash->{WEBCM} = -1;
  210. RemoveInternalTimer($hash->{helper}{TimerReadout});
  211. InternalTimer(gettimeofday()+1 , "FRITZBOX_Readout_Start", $hash->{helper}{TimerReadout}, 0);
  212. # Inform about missing PERL modules
  213. if ( $missingModulTelnet || $missingModulWeb || $missingModulTR064 ) {
  214. my $msg = "Modul functionality limited because of missing perl modules: ".$missingModulTelnet . $missingModulWeb . $missingModulTR064;
  215. FRITZBOX_Log $hash, 2, $msg;
  216. $hash->{PERL} = $msg;
  217. }
  218. return undef;
  219. } #end FRITZBOX_Define
  220. #######################################################################
  221. sub FRITZBOX_Undefine($$)
  222. {
  223. my ($hash, $args) = @_;
  224. RemoveInternalTimer($hash->{helper}{TimerReadout});
  225. RemoveInternalTimer($hash->{helper}{TimerCmd});
  226. BlockingKill( $hash->{helper}{READOUT_RUNNING_PID} )
  227. if exists $hash->{helper}{READOUT_RUNNING_PID};
  228. BlockingKill( $hash->{helper}{CMD_RUNNING_PID} )
  229. if exists $hash->{helper}{CMD_RUNNING_PID};
  230. return undef;
  231. } # end FRITZBOX_Undefine
  232. #######################################################################
  233. sub FRITZBOX_Delete ($$)
  234. {
  235. my ( $hash, $name ) = @_;
  236. my $index = $hash->{TYPE}."_".$name."_passwd";
  237. setKeyValue($index, undef);
  238. return undef;
  239. }
  240. #######################################################################
  241. sub FRITZBOX_Rename($$)
  242. {
  243. my ($new, $old) = @_;
  244. my $old_index = "FRITZBOX_".$old."_passwd";
  245. my $new_index = "FRITZBOX_".$new."_passwd";
  246. my ($err, $old_pwd) = getKeyValue($old_index);
  247. setKeyValue($new_index, $old_pwd);
  248. setKeyValue($old_index, undef);
  249. }
  250. #######################################################################
  251. sub FRITZBOX_Attr($@)
  252. {
  253. my ($cmd,$name,$aName,$aVal) = @_;
  254. # $cmd can be "del" or "set"
  255. # $name is device name
  256. # aName and aVal are Attribute name and value
  257. my $hash = $defs{$name};
  258. if ($aName eq "fritzBoxIP") {
  259. if ($cmd eq "set") {
  260. $hash->{HOST} = $aVal;
  261. }
  262. else {
  263. $hash->{HOST} = $hash->{fhem}{definedHost};
  264. }
  265. }
  266. # Stop the sub if FHEM is not initialized yet
  267. return undef unless $init_done;
  268. if ( $aName =~ /fritzBoxIP|m3uFileLocal|m3uFileURL/ && $hash->{APICHECKED} == 1
  269. || $aName eq "disable" ) {
  270. $hash->{APICHECKED} = 0;
  271. RemoveInternalTimer($hash->{helper}{TimerReadout});
  272. InternalTimer(gettimeofday()+1, "FRITZBOX_Readout_Start", $hash->{helper}{TimerReadout}, 1);
  273. # FRITZBOX_Readout_Start($hash->{helper}{TimerReadout});
  274. }
  275. return undef;
  276. } # FRITZBOX_Attr ende
  277. #######################################################################
  278. sub FRITZBOX_Set($$@)
  279. {
  280. my ($hash, $name, $cmd, @val) = @_;
  281. my $resultStr = "";
  282. my $list = "call"
  283. . " checkAPIs:noArg"
  284. . " diversity"
  285. . " guestWlan:on,off"
  286. . " password"
  287. . " ring"
  288. . " tam"
  289. . " update:noArg"
  290. . " wlan:on,off";
  291. $list .= " wlan2.4:on,off"
  292. . " wlan5:on,off"
  293. if $hash->{fhem}->{is_double_wlan} == 1;
  294. $list .= " alarm"
  295. . " dect:on,off"
  296. . " startRadio"
  297. if $hash->{WEBCM}==1 || $hash->{TELNET}==1;
  298. $list .= " sendMail"
  299. . " customerRingTone"
  300. . " moh"
  301. if $hash->{TELNET}==1;
  302. # . " convertMOH"
  303. # . " convertRingTone"
  304. my $forceShell = ( AttrVal( $name, "forceTelnetConnection", 0 ) == 1 || defined $hash->{REMOTE} && $hash->{REMOTE} == 0 );
  305. # set alarm
  306. if ( lc $cmd eq 'alarm') {
  307. if ( int @val > 0 && $val[0] =~ /^(1|2|3)$/ ) {
  308. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  309. return "'set ... alarm' is not supported by the limited interfaces of your Fritz!Box firmware."
  310. unless $hash->{WEBCM}==1 || $forceShell;
  311. return FRITZBOX_Set_Alarm_Web ($hash, @val)
  312. unless $forceShell;
  313. return FRITZBOX_Set_Alarm_Shell ($hash, @val);
  314. }
  315. }
  316. # set call
  317. elsif ( lc $cmd eq 'call') {
  318. if (int @val > 0) {
  319. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  320. push @cmdBuffer, "call ".join(" ", @val);
  321. return FRITZBOX_Set_Cmd_Start $hash->{helper}{TimerCmd};
  322. }
  323. # } elsif ( lc $cmd eq 'convertmoh') {
  324. # if (int @val > 0)
  325. # {
  326. # Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  327. # return FRITZBOX_ConvertMOH $hash, @val;
  328. # }
  329. # } elsif ( lc $cmd eq 'convertringtone') {
  330. # if (int @val > 0)
  331. # {
  332. # Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  333. # return FRITZBOX_ConvertRingTone $hash, @val;
  334. # }
  335. }
  336. elsif ( lc $cmd eq 'checkapis') {
  337. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  338. $hash->{APICHECKED} = 0;
  339. $hash->{fhem}{sidTime} = 0;
  340. $hash->{fhem}{LOCAL} = 1;
  341. FRITZBOX_Readout_Start($hash->{helper}{TimerReadout});
  342. $hash->{fhem}{LOCAL} = 0;
  343. return undef;
  344. }
  345. elsif ( lc $cmd eq 'customerringtone') {
  346. if (int @val > 0)
  347. {
  348. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  349. return FRITZBOX_SetCustomerRingTone ($hash, @val);
  350. }
  351. }
  352. elsif ( lc $cmd eq 'dect') {
  353. if (int @val == 1 && $val[0] =~ /^(on|off)$/) {
  354. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  355. my $state = $val[0];
  356. $state =~ s/on/1/;
  357. $state =~ s/off/0/;
  358. if ($forceShell) { # Shell
  359. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w dect settings/enabled $state");
  360. }
  361. else { #webcm
  362. my @webCmdArray = ( ["dect:settings/enabled" => $state] );
  363. return "'set ... dect' is not supported by the limited interfaces of your Fritz!Box firmware."
  364. unless $hash->{WEBCM}==1;
  365. FRITZBOX_Web_CmdPost ($hash, \@webCmdArray);
  366. }
  367. readingsSingleUpdate($hash,"box_dect",$val[0], 1);
  368. return undef;
  369. }
  370. }
  371. elsif ( lc $cmd eq 'diversity') {
  372. if ( int @val == 2 && $val[1] =~ /^(on|off)$/ ) {
  373. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  374. return "Error, no diversity".$val[0]." to set."
  375. unless defined $hash->{READINGS}{"diversity".$val[0]};
  376. my $state = $val[1];
  377. $state =~ s/on/1/;
  378. $state =~ s/off/0/;
  379. if ($forceShell) { # Shell
  380. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w telcfg settings/Diversity".( $val[0] - 1 )."/Active ".$state );
  381. }
  382. elsif ( $hash->{WEBCM}==1 ) { #webcm
  383. my @webCmdArray = ( ["telcfg:settings/Diversity".( $val[0] - 1 )."/Active " => $state] );
  384. FRITZBOX_Web_CmdPost ($hash, \@webCmdArray);
  385. }
  386. elsif ( $hash->{TR064}==1 ) { #tr064
  387. my @tr064CmdArray = (["X_AVM-DE_OnTel:1", "x_contact", "SetDeflectionEnable", "NewDeflectionId", $val[0] - 1, "NewEnable", $state] );
  388. FRITZBOX_TR064_Cmd ($hash, 0, \@tr064CmdArray);
  389. }
  390. else {
  391. return "'set ... diversity' is not supported by the limited interfaces of your Fritz!Box firmware.";
  392. }
  393. readingsSingleUpdate($hash,"diversity".$val[0]."_state",$val[1], 1);
  394. return undef;
  395. }
  396. }
  397. elsif ( lc $cmd eq 'guestwlan') {
  398. if (int @val == 1 && $val[0] =~ /^(on|off)$/) {
  399. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  400. push @cmdBuffer, "guestwlan ".join(" ", @val);
  401. return FRITZBOX_Set_Cmd_Start $hash->{helper}{TimerCmd};
  402. }
  403. }
  404. elsif ( lc $cmd eq 'moh') {
  405. if (int @val > 0)
  406. {
  407. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  408. $resultStr = FRITZBOX_SetMOH $hash, @val;
  409. if ($resultStr =~ /^[012]$/ )
  410. {
  411. readingsSingleUpdate($hash,"box_guestWlan",$mohtype{$resultStr}, 1);
  412. return undef;
  413. }
  414. else
  415. {
  416. return $resultStr;
  417. }
  418. }
  419. }
  420. # set password
  421. elsif ( lc $cmd eq 'password') {
  422. if (int @val == 1)
  423. {
  424. return FRITZBOX_storePassword ( $hash, $val[0] );
  425. }
  426. }
  427. #set Ring
  428. elsif ( lc $cmd eq 'ring') {
  429. if (int @val > 0) {
  430. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  431. push @cmdBuffer, "ring ".join(" ", @val);
  432. return FRITZBOX_Set_Cmd_Start $hash->{helper}{TimerCmd};
  433. }
  434. }
  435. elsif ( lc $cmd eq 'sendmail') {
  436. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  437. return "'set ... sendMail' is not supported by the limited interfaces of your Fritz!Box firmware."
  438. unless $hash->{TELNET}==1;
  439. FRITZBOX_SendMail_Shell $hash, @val;
  440. return undef;
  441. }
  442. elsif ( lc $cmd eq 'startradio') {
  443. if (int @val > 0) {
  444. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  445. return "'set ... startRadio' is not supported by the limited interfaces of your Fritz!Box firmware."
  446. unless $hash->{WEBCM}==1 || $forceShell;
  447. return FRITZBOX_StartRadio_Web $hash, @val unless $forceShell;
  448. return FRITZBOX_StartRadio_Shell $hash, @val;
  449. }
  450. }
  451. elsif ( lc $cmd eq 'tam') {
  452. if ( int @val == 2 && defined( $hash->{READINGS}{"tam".$val[0]} ) && $val[1] =~ /^(on|off)$/ ) {
  453. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  454. my $state = $val[1];
  455. $state =~ s/on/1/;
  456. $state =~ s/off/0/;
  457. if ($forceShell) { # Shell
  458. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w tam settings/TAM".( $val[0] - 1 )."/Active ".$state );
  459. }
  460. elsif ($hash->{SECPORT}) { #TR-064
  461. my @tr064CmdArray = (["X_AVM-DE_TAM:1", "x_tam", "SetEnable", "NewIndex", $val[0] - 1 , "NewEnable", $state]);
  462. FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  463. }
  464. else { #webcm
  465. my @webCmdArray = ( ["tam:settings/TAM".( $val[0] - 1 )."/Active" => $state] );
  466. FRITZBOX_Web_CmdPost ($hash, \@webCmdArray);
  467. }
  468. readingsSingleUpdate($hash,"tam".$val[0]."_state",$val[1], 1);
  469. return undef;
  470. }
  471. }
  472. elsif ( lc $cmd eq 'update' ) {
  473. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  474. $hash->{fhem}{LOCAL}=1;
  475. FRITZBOX_Readout_Start($hash->{helper}{TimerReadout});
  476. $hash->{fhem}{LOCAL}=0;
  477. return undef;
  478. }
  479. elsif ( lc $cmd eq 'wlan') {
  480. if (int @val == 1 && $val[0] =~ /^(on|off)$/) {
  481. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  482. push @cmdBuffer, "wlan ".join(" ", @val);
  483. return FRITZBOX_Set_Cmd_Start $hash->{helper}{TimerCmd};
  484. }
  485. }
  486. elsif ( lc $cmd =~ /^wlan(2\.4|5)$/ && $hash->{fhem}->{is_double_wlan} == 1 ) {
  487. if ( int @val == 1 && $val[0] =~ /^(on|off)$/ ) {
  488. Log3 $name, 3, "FRITZBOX: set $name $cmd ".join(" ", @val);
  489. push @cmdBuffer, lc ($cmd) . " " . join(" ", @val);
  490. return FRITZBOX_Set_Cmd_Start $hash->{helper}{TimerCmd};
  491. }
  492. }
  493. return "Unknown argument $cmd or wrong parameter(s), choose one of $list";
  494. } # end FRITZBOX_Set
  495. # ctlmgr_ctl r timer settings/KidsTimerXML1/
  496. # ctlmgr_ctl r filter_profile settings/profile5/timeprofile_id
  497. # ctlmgr_ctl r filter_profile settings/profile5/name
  498. #######################################################################
  499. sub FRITZBOX_Get($@)
  500. {
  501. my ($hash, $name, $cmd, @val) = @_;
  502. my $returnStr;
  503. if( lc $cmd eq "luaquery" && AttrVal( $name, "allowTR064Command", 0 ) && defined $hash->{SECPORT}) {
  504. # get Fritzbox luaQuery inetstat:status/Today/BytesReceivedLow
  505. # get Fritzbox luaQuery telcfg:settings/AlarmClock/list(Name,Active,Time,Number,Weekdays)
  506. Log3 $name, 3, "FRITZBOX: get $name $cmd ".join(" ", @val);
  507. return "Wrong number of arguments, usage: get $name luaQuery <query>" if int @val !=1;
  508. $returnStr = "Result of query = '$val[0]'\n";
  509. $returnStr .= "----------------------------------------------------------------------\n";
  510. my $queryStr = "&result=".$val[0];
  511. my $result = FRITZBOX_Web_Query( $hash, $queryStr) ;
  512. my $tmp;
  513. if (ref $result->{result} eq "") { $tmp = $result->{result}; }
  514. else { $tmp = Dumper ($result->{result}); }
  515. return $returnStr . $tmp;
  516. }
  517. elsif( lc $cmd eq "ringtones" ) {
  518. Log3 $name, 3, "FRITZBOX: get $name $cmd ".join(" ", @val);
  519. $returnStr = "Ring tones to use with 'set <name> ring <intern> <duration> <ringTone>'\n";
  520. $returnStr .= "----------------------------------------------------------------------\n";
  521. $returnStr .= join "\n", sort values %ringTone;
  522. return $returnStr;
  523. }
  524. elsif( lc $cmd eq "shellcommand" && int @val && AttrVal( $name, "allowShellCommand", 0 ) ) {
  525. Log3 $name, 3, "FRITZBOX: get $name $cmd ".join(" ", @val);
  526. return "'get ... shellcommand' is not supported by the limited interfaces of your Fritz!Box firmware."
  527. unless $hash->{TELNET}==1;
  528. my $shCmd = join " ", @val;
  529. return FRITZBOX_Shell_Exec( $hash, $shCmd );
  530. }
  531. elsif( lc $cmd eq "tr064command" && AttrVal( $name, "allowTR064Command", 0 ) ) {
  532. # http://fritz.box:49000/tr64desc.xml
  533. #get Fritzbox tr064command DeviceInfo:1 deviceinfo GetInfo
  534. #get Fritzbox tr064command X_VoIP:1 x_voip X_AVM-DE_GetPhonePort NewIndex 1
  535. #get Fritzbox tr064command X_VoIP:1 x_voip X_AVM-DE_DialNumber NewX_AVM-DE_PhoneNumber **612
  536. #get Fritzbox tr064command X_VoIP:1 x_voip X_AVM-DE_DialHangup
  537. #get Fritzbox tr064command WLANConfiguration:3 wlanconfig3 X_AVM-DE_GetWLANExtInfo
  538. #get Fritzbox tr064command X_AVM-DE_OnTel:1 x_contact GetDECTHandsetList
  539. #get Fritzbox tr064command X_AVM-DE_OnTel:1 x_contact GetDECTHandsetInfo NewDectID 1
  540. #get Fritzbox tr064command X_AVM-DE_TAM:1 x_tam GetInfo NewIndex 0
  541. #get Fritzbox tr064command X_AVM-DE_TAM:1 x_tam SetEnable NewIndex 0 NewEnable 0
  542. #get Fritzbox tr064command InternetGatewayDevice:1 deviceinfo GetInfo
  543. #get Fritzbox tr064command LANEthernetInterfaceConfig:1 lanethernetifcfg GetStatistics
  544. Log3 $name, 3, "FRITZBOX: get $name $cmd ".join(" ", @val);
  545. my ($a, $h) = parseParams( join (" ", @val) );
  546. @val = @$a;
  547. return "Wrong number of arguments, usage: get $name tr064command service control action [argName1 argValue1] [argName2 argValue2] ..."
  548. if int @val <3 || int(@val) %2 !=1;
  549. $returnStr = "Result of TR064 call\n";
  550. $returnStr .= "----------------------------------------------------------------------\n";
  551. $returnStr = "Service='$val[0]' Control='$val[1]' Action='$val[2]'\n";
  552. for(my $i = 1; $i <= (int @val - 3)/2; $i++) {
  553. $returnStr .= "Parameter$i='$val[2*$i+1]' => '$val[2*$i+2]'\n";
  554. }
  555. $returnStr .= "----------------------------------------------------------------------\n";
  556. my @tr064CmdArray = ( \@val );
  557. my @result = FRITZBOX_TR064_Cmd( $hash, 1, \@tr064CmdArray );
  558. my $tmp = Dumper (@result);
  559. $returnStr .= $tmp;
  560. return $returnStr;
  561. }
  562. elsif( lc $cmd eq "tr064servicelist" ) {
  563. return FRITZBOX_TR064_Get_ServiceList ($hash);
  564. }
  565. my $list = "ringTones:noArg";
  566. $list .= " luaQuery" if AttrVal( $name, "allowTR064Command", 0 );
  567. $list .= " tr064Command" if AttrVal( $name, "allowTR064Command", 0 ) && defined $hash->{SECPORT};;
  568. $list .= " tr064ServiceList:noArg" if AttrVal( $name, "allowTR064Command", 0 );
  569. $list .= " shellCommand" if AttrVal( $name, "allowShellCommand", 0 ) && $hash->{TELNET}==1;
  570. return "Unknown argument $cmd, choose one of $list";
  571. } # end FRITZBOX_Get
  572. # Starts the data capturing and sets the new readout timer
  573. #######################################################################
  574. sub FRITZBOX_Readout_Start($)
  575. {
  576. my ($timerpara) = @_;
  577. # my ( $name, $func ) = split( /\./, $timerpara );
  578. my $index = rindex( $timerpara, "." ); # rechter Punkt
  579. my $func = substr $timerpara, $index + 1, length($timerpara); # function extrahieren
  580. my $name = substr $timerpara, 0, $index; # name extrahieren
  581. my $hash = $defs{$name};
  582. my $runFn;
  583. if( AttrVal( $name, "disable", 0 ) == 1 ) {
  584. RemoveInternalTimer($hash->{helper}{TimerReadout});
  585. readingsSingleUpdate( $hash, "state", "disabled", 1 );
  586. return undef;
  587. }
  588. # Set timer value (min. 60)
  589. $hash->{INTERVAL} = AttrVal( $name, "INTERVAL", $hash->{INTERVAL} );
  590. $hash->{INTERVAL} = 60 if $hash->{INTERVAL} < 60 && $hash->{INTERVAL} != 0;
  591. my $interval = $hash->{INTERVAL};
  592. # First run is an API check
  593. unless ( $hash->{APICHECKED} ) {
  594. $interval = 10;
  595. $hash->{STATE} = "Check APIs";
  596. $runFn = "FRITZBOX_API_Check_Run";
  597. }
  598. # Run shell or web api, restrict interval
  599. else {
  600. $runFn = "FRITZBOX_Readout_Run_Web";
  601. $runFn = "FRITZBOX_Readout_Run_Shell" if AttrVal( $name, "forceTelnetConnection", 0 ) == 1 || $hash->{REMOTE} == 0;
  602. }
  603. if( $interval != 0 ) {
  604. RemoveInternalTimer($hash->{helper}{TimerReadout});
  605. InternalTimer(gettimeofday()+$interval, "FRITZBOX_Readout_Start", $hash->{helper}{TimerReadout}, 1);
  606. }
  607. # Kill running process if "set update" is used
  608. if ( exists( $hash->{helper}{READOUT_RUNNING_PID} ) && $hash->{fhem}{LOCAL} == 1 ) {
  609. FRITZBOX_Log $hash, 1, "Old readout process still running. Killing old process ".$hash->{helper}{READOUT_RUNNING_PID};
  610. BlockingKill( $hash->{helper}{READOUT_RUNNING_PID} );
  611. # stop FHEM, giving a FritzBox some time to free the memory
  612. sleep 5 unless $hash->{REMOTE}==1;
  613. delete( $hash->{helper}{READOUT_RUNNING_PID} );
  614. }
  615. $hash->{fhem}{LOCAL} = 2 if $hash->{fhem}{LOCAL} == 1;
  616. unless( exists $hash->{helper}{READOUT_RUNNING_PID} ) {
  617. $hash->{helper}{READOUT_RUNNING_PID} = BlockingCall($runFn, $name,
  618. "FRITZBOX_Readout_Done", 55,
  619. "FRITZBOX_Readout_Aborted", $hash);
  620. FRITZBOX_Log $hash, 4, "Fork process $runFn";
  621. }
  622. else {
  623. FRITZBOX_Log $hash, 4, "Skip fork process $runFn";
  624. }
  625. } # end FRITZBOX_Readout_Start
  626. # Checks which API is available on the Fritzbox
  627. #######################################################################
  628. sub FRITZBOX_API_Check_Run($)
  629. {
  630. my ($name) = @_;
  631. my $hash = $defs{$name};
  632. my $fritzShell = 0;
  633. my @roReadings;
  634. my $response;
  635. my $startTime = time();
  636. my $host = $hash->{HOST};
  637. # if no FritzBoxIP is set, check if FHEM runs on a FritzBox under root user
  638. # unless (qx ( [ -f /usr/bin/ctlmgr_ctl ] && echo 1 || echo 0 ))
  639. if ( $host =~ /undefined|local/ ) {
  640. # set default host
  641. $host = "fritz.box";
  642. if ( -X "/usr/bin/ctlmgr_ctl" ) {
  643. if ( $< != 0 ) {
  644. FRITZBOX_Log $hash, 3, "FHEM is running on a Fritz!Box but not as 'root' user (currently " .
  645. ( getpwuid( $< ) )[ 0 ] . "). Cannot run in local mode.";
  646. }
  647. else {
  648. $fritzShell = 1;
  649. $host = "local"; # mark as local host
  650. FRITZBOX_Log $hash, 5, "FHEM is running on a Fritz!Box as 'root' user.";
  651. }
  652. }
  653. }
  654. # change host name if necessary
  655. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "->HOST", $host) if $host ne $hash->{HOST};
  656. # Determine local or remote mode
  657. if ($fritzShell) {
  658. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->REMOTE", 0;
  659. FRITZBOX_Log $hash, 4, "FRITZBOX modul runs in local mode.";
  660. }
  661. else {
  662. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->REMOTE", 1;
  663. FRITZBOX_Log $hash, 4, "FRITZBOX modul runs in remote mode.";
  664. }
  665. # Check if perl modules for remote APIs exists
  666. if ($missingModulWeb) {
  667. FRITZBOX_Log $hash, 3, "Cannot check for box model and APIs webcm, luaQuery and TR064 because perl modul $missingModulWeb is missing on this system.";
  668. }
  669. # Check for remote APIs
  670. else {
  671. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10);
  672. # Check if webcm exists
  673. $response = $agent->get( "http://".$host."/cgi-bin/webcm" );
  674. if ($response->is_success) {
  675. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->WEBCM", 1;
  676. FRITZBOX_Log $hash, 4, "API webcm found (".$response->code.").";
  677. }
  678. else {
  679. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->WEBCM", 0;
  680. FRITZBOX_Log $hash, 4, "API webcm does not exist (".$response->status_line.")";
  681. }
  682. # Check if query.lua exists
  683. $response = $agent->get( "http://".$host."/query.lua" );
  684. if ($response->is_success) {
  685. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->LUAQUERY", 1;
  686. FRITZBOX_Log $hash, 4, "API luaQuery found (".$response->code.").";
  687. }
  688. elsif ($response->code eq "500" || $response->code eq "403") {
  689. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->LUAQUERY", 1;
  690. FRITZBOX_Log $hash, 4, "API luaQuery found but responded with: ".$response->status_line;
  691. }
  692. else {
  693. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->LUAQUERY", 0;
  694. FRITZBOX_Log $hash, 4, "API luaQuery does not exist (".$response->status_line.")";
  695. }
  696. # Check if tr064 specification exists and determine TR064-Port
  697. $response = $agent->get( "http://".$host.":49000/tr64desc.xml" );
  698. if ($response->is_success) { #determine TR064-Port
  699. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->TR064", 1;
  700. FRITZBOX_Log $hash, 4, "API TR-064 found.";
  701. #Determine TR064-Port
  702. my $tr064Port = FRITZBOX_TR064_Init ( $hash, $host );
  703. if ($tr064Port) {
  704. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->SECPORT", $tr064Port;
  705. FRITZBOX_Log $hash, 4, "TR-064-SecurePort is $tr064Port.";
  706. }
  707. else {
  708. FRITZBOX_Log $hash, 4, "TR-064-SecurePort does not exist";
  709. }
  710. }
  711. else {
  712. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->TR064", 0;
  713. FRITZBOX_Log $hash, 4, "API TR-064 does not exist: ".$response->status_line;
  714. }
  715. # Check if m3u can be created and the URL tested
  716. my $globalModPath = AttrVal( "global", "modpath", "." );
  717. my $m3uFileLocal = AttrVal( $name, "m3uFileLocal", $globalModPath."/www/images/".$name.".m3u" );
  718. if (open my $fh, '>', $m3uFileLocal) {
  719. my $ttsText = uri_escape("Lirumlarumlöffelstielwerdasnichtkannderkannnichtviel");
  720. my $ttsLink = $ttsLinkTemplate;
  721. $ttsLink =~ s/\[TEXT\]/$ttsText/;
  722. $ttsLink =~ s/\[SPRACHE\]/fr/;
  723. print $fh $ttsLink;
  724. close $fh;
  725. FRITZBOX_Log $hash, 4, "Created m3u file '$m3uFileLocal'.";
  726. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->M3U_LOCAL", $m3uFileLocal;
  727. # Get the m3u-URL
  728. my $m3uFileURL = AttrVal( $name, "m3uFileURL", "unknown" );
  729. # if no URL and no local file defined, then try to build the correct URL
  730. if ( $m3uFileURL eq "unknown" && AttrVal( $name, "m3uFileLocal", "" ) eq "" ) {
  731. # Getting IP of FHEM host
  732. FRITZBOX_Log $hash, 4, "Try to get my IP address.";
  733. my $socket = IO::Socket::INET->new( Proto => 'tcp', PeerAddr => $host, PeerPort => 'http(80)' );
  734. my $ip;
  735. $ip = $socket->sockhost if $socket; #A side-effect of making a socket connection is that our IP address is available from the 'sockhost' method
  736. FRITZBOX_Log $hash, 4, "Could not determine my ip address" unless $ip;
  737. # Get a web port
  738. my $port;
  739. FRITZBOX_Log $hash, 4, "Try to get a FHEMWEB port.";
  740. foreach( keys %defs ) {
  741. if ( $defs{$_}->{TYPE} eq "FHEMWEB" && defined $defs{$_}->{PORT} ) {
  742. $port = $defs{$_}->{PORT};
  743. last;
  744. }
  745. }
  746. FRITZBOX_Log $hash, 4, "Could not find a FHEMWEB device." unless $port;
  747. $m3uFileURL = "http://$ip:$port/fhem/images/$name.m3u" if defined $ip && defined $port;
  748. }
  749. # Check if m3u can be accessed
  750. unless ( $m3uFileURL eq "unknown" ) {
  751. FRITZBOX_Log $hash, 4, "Try to get '$m3uFileURL'";
  752. $response = $agent->get( $m3uFileURL );
  753. if ($response->is_error) {
  754. FRITZBOX_Log $hash, 4, "Failed to get '$m3uFileURL': ".$response->status_line;
  755. $m3uFileURL = "unknown" ;
  756. }
  757. }
  758. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->M3U_URL", $m3uFileURL;
  759. }
  760. else {
  761. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->M3U_LOCAL", "undefined";
  762. FRITZBOX_Log $hash, 4, "Error: Cannot create save file '$m3uFileLocal' because $!\n";
  763. }
  764. # Box model per jason
  765. FRITZBOX_Log $hash, 5, "Read 'jason_boxinfo'";
  766. my $url = "http://".$host."/jason_boxinfo.xml";
  767. $response = $agent->get( $url );
  768. my $content = $response->content;
  769. # FRITZBOX_Log $hash, 5, "jason_boxinfo returned: $content";
  770. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "box_model", $1) if ( $content =~ /<j:Name>(.*)<\/j:Name>/ );
  771. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "box_oem", $1) if $content =~ /<j:OEM>(.*)<\/j:OEM>/;
  772. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "box_fwVersion", $1) if $content =~ /<j:Version>(.*)<\/j:Version>/;
  773. # Ansonsten Box-Model per system_status einlesen
  774. unless ($content =~ /<j:Name>/) {
  775. # Muss nochmal neu gesetzt werden, sonst gibt es einen Fehler (keine Ahnung warum)
  776. $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10);
  777. $url = "http://".$host."/cgi-bin/system_status";
  778. FRITZBOX_Log $hash, 5, "Read 'system_status'";
  779. $response = $agent->get( $url );
  780. $content = $response->content;
  781. # FRITZBOX_Log $hash, 5, "system_status returned: $content";
  782. if ($response->is_success) {
  783. $content=$1 if $content =~ /<body>(.*)<\/body>/;
  784. my @result = split /-/, $content;
  785. # http://www.tipps-tricks-kniffe.de/fritzbox-wie-lange-ist-die-box-schon-gelaufen/
  786. # 0 FritzBox-Modell
  787. # 1 Annex/Erweiterte Kennzeichnung
  788. # 2 Gesamtlaufzeit der Box in Stunden, Tage, Monate
  789. # 3 Gesamtlaufzeit der Box in Jahre, Anzahl der Neustarts
  790. # 4+5 Hashcode
  791. # 6 Status
  792. # 7 Firmwareversion
  793. # 8 Sub-Version/Unterversion der Firmware
  794. # 9 Branding, z.B. 1und1 (Provider 1&1) oder avm (direkt von AVM)
  795. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_model", $result[0];
  796. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_fwVersion", $result[7];
  797. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_oem", $result[9];
  798. }
  799. else {
  800. FRITZBOX_Log $hash, 4, "Error: ".$response->status_line;
  801. };
  802. };
  803. }
  804. # Check if telnet modul exists
  805. if ($missingModulTelnet) {
  806. FRITZBOX_Log $hash, 4, "Cannot check for telnet access because perl modul $missingModulTelnet is missing on this system.\n";
  807. }
  808. else {
  809. my $timeout = AttrVal( $name, "telnetTimeOut", "10");
  810. my $telnet = new Net::Telnet ( Host=>$host, Port => 23, Timeout=>$timeout, Errmode=>'return', Prompt=>'/# $/');
  811. if (!$telnet) {
  812. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->TELNET", 0;
  813. $telnet = undef;
  814. FRITZBOX_Log $hash, 4, "Could not open telnet connection to $host: $!";
  815. }
  816. else {
  817. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->TELNET", 1;
  818. $telnet->close;
  819. FRITZBOX_Log $hash, 4, "Telnet connection availabel.";
  820. }
  821. }
  822. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "->APICHECKED", 1;
  823. push @roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  824. my $returnStr = join('|', @roReadings );
  825. FRITZBOX_Log $hash, 4, "Captured " . @roReadings . " values";
  826. FRITZBOX_Log $hash, 5, "Handover to main process (".length ($returnStr)."): ".$returnStr;
  827. return $name."|".encode_base64($returnStr,"");
  828. } #end FRITZBOX_API_Check_Run
  829. # Starts the data capturing via Telnet and sets the new timer
  830. #######################################################################
  831. sub FRITZBOX_Readout_Run_Shell($)
  832. {
  833. my ($name) = @_;
  834. my $hash = $defs{$name};
  835. my $result;
  836. my $rName;
  837. my @cmdArray;
  838. my @readoutCmdArray;
  839. my $resultArray;
  840. my @roReadings;
  841. my %dectFonID;
  842. my $i;
  843. my $startTime = time();
  844. my $slowRun = 0;
  845. if ( int(time/3600) != $hash->{fhem}{lastHour} || $hash->{fhem}{LOCAL} != 0) {
  846. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->lastHour", int(time/3600);
  847. $slowRun = 1;
  848. FRITZBOX_Log $hash, 4, "Start update of slow changing device readings.";
  849. }
  850. else {
  851. FRITZBOX_Log $hash, 4, "Start update of fast changing device readings.";
  852. }
  853. my $returnStr;
  854. $result = FRITZBOX_Telnet_OpenCon( $hash );
  855. return $name."|".encode_base64("Error|$result","")
  856. if $result;
  857. if ($slowRun == 1) {
  858. # Init and Counters
  859. push @readoutCmdArray, ["", "ctlmgr_ctl r telcfg settings/Foncontrol" ];
  860. push @readoutCmdArray, ["", "ctlmgr_ctl r telcfg settings/Foncontrol/User/count" ];
  861. push @readoutCmdArray, ["", "ctlmgr_ctl r dect settings/Handset/count" ];
  862. push @readoutCmdArray, ["fhem->radioCount", "ctlmgr_ctl r configd settings/WEBRADIO/count" ];
  863. push @readoutCmdArray, ["", "ctlmgr_ctl r user settings/user/count" ];
  864. push @readoutCmdArray, ["", 'echo $CONFIG_AB_COUNT'];
  865. push @readoutCmdArray, ["", "ctlmgr_ctl r landevice settings/landevice/count" ];
  866. push @readoutCmdArray, ["", "ctlmgr_ctl r tam settings/TAM/count" ];
  867. push @readoutCmdArray, ["", "ctlmgr_ctl r telcfg settings/RefreshDiversity" ];
  868. push @readoutCmdArray, ["", "ctlmgr_ctl r telcfg settings/Diversity/count" ];
  869. # Box Features
  870. push @readoutCmdArray, [ "fhem->is_double_wlan", "ctlmgr_ctl r wlan settings/feature_flags/DBDC", "01" ];
  871. # Box model and firmware
  872. push @readoutCmdArray, [ "box_model", 'echo $CONFIG_PRODUKT_NAME' ];
  873. push @readoutCmdArray, [ "box_oem", 'echo $OEM' ];
  874. push @readoutCmdArray, [ "box_fwVersion", "ctlmgr_ctl r logic status/nspver" ];
  875. push @readoutCmdArray, [ "box_fwUpdate", "ctlmgr_ctl r updatecheck status/update_available_hint" ];
  876. push @readoutCmdArray, [ "box_tr069", "ctlmgr_ctl r tr069 settings/enabled", "onoff" ];
  877. # Execute commands
  878. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings);
  879. return $name."|".encode_base64("Error|No STDOUT from shell command.","")
  880. unless defined $resultArray;
  881. my $dectCount = $resultArray->[1];
  882. $dectCount = 1 unless $dectCount=~ /\d/;
  883. $dectCount--;
  884. my $handsetCount = $resultArray->[2];
  885. $handsetCount = 1 unless $dectCount=~ /\d/;
  886. $handsetCount--;
  887. my $radioCount = $resultArray->[3];
  888. $radioCount = 0 unless $radioCount=~ /\d/;
  889. my $userCount = $resultArray->[4];
  890. my $fonCount = $resultArray->[5];
  891. my $lanDeviceCount = $resultArray->[6];
  892. my $tamCount = $resultArray->[7];
  893. my $divCount = $resultArray->[9];
  894. # Internetradioliste erzeugen
  895. $i = 0;
  896. $rName = "radio00";
  897. while ( $i<$radioCount || defined $hash->{READINGS}{$rName} )
  898. {
  899. push @readoutCmdArray, [ $rName, "ctlmgr_ctl r configd settings/WEBRADIO".$i."/Name" ];
  900. $i++;
  901. $rName = sprintf ("radio%02d",$i);
  902. }
  903. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  904. my @radio = ();
  905. for (0..$radioCount-1)
  906. {
  907. if ($resultArray->[$_] ne "")
  908. {
  909. $radio[$_] = $resultArray->[$_];
  910. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->radio->".$_, $resultArray->[$_];
  911. }
  912. }
  913. # LanDevice-Liste erzeugen
  914. if ($lanDeviceCount > 0 )
  915. {
  916. for (0..$lanDeviceCount-1)
  917. {
  918. push @readoutCmdArray, [ "", "ctlmgr_ctl r landevice settings/landevice".$_."/ip" ];
  919. push @readoutCmdArray, [ "", "ctlmgr_ctl r landevice settings/landevice".$_."/name" ];
  920. }
  921. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  922. %landevice = ();
  923. for (0..$lanDeviceCount-1)
  924. {
  925. my $offset = 2 * $_;
  926. my $dIp = $resultArray->[ $offset ];
  927. my $dName = $resultArray->[ $offset +1];
  928. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->landevice->$dIp", $dName;
  929. $landevice{$dIp}=$dName;
  930. }
  931. }
  932. # Dect Telefonnummern bestimmen
  933. for (1..$dectCount)
  934. {
  935. # 0 Dect-Interne Nummer
  936. push @readoutCmdArray, [ "dect".$_."_intern", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Intern" ];
  937. # 1 Dect-Telefonname
  938. push @readoutCmdArray, [ "dect".$_, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Name" ];
  939. # 2 Internal Ring Tone Name
  940. push @readoutCmdArray, [ "dect".$_."_intRingTone", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/IntRingTone", "ringtone" ];
  941. # 3 Alarm Ring Tone Name
  942. push @readoutCmdArray, [ "dect".$_."_alarmRingTone", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/AlarmRingTone0", "ringtone" ];
  943. # 4 Radio Name
  944. push @readoutCmdArray, [ "dect".$_."_radio", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/RadioRingID", "radio" ];
  945. # 5 Background image
  946. push @readoutCmdArray, [ "dect".$_."_imagePath", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/ImagePath" ];
  947. # 6 Customer Ring Tone
  948. push @readoutCmdArray, [ "dect".$_."_custRingTone", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/G722RingTone" ];
  949. # 7 Customer Ring Tone Name
  950. push @readoutCmdArray, [ "dect".$_."_custRingToneName", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/G722RingToneName" ];
  951. # 8 UserID
  952. push @readoutCmdArray, [ "", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Id" ];
  953. }
  954. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  955. for (1..$dectCount)
  956. {
  957. my $offset = $_ * 9 - 9;
  958. my $intern = $resultArray->[$offset];
  959. my $ID = $resultArray->[ $offset + 8 ];
  960. if ($intern)
  961. {
  962. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->$intern->name", $resultArray->[ $offset + 1 ];
  963. $dectFonID{$ID}{User} = $_;
  964. $dectFonID{$ID}{Intern} = $intern;
  965. }
  966. }
  967. # Assign data of DECT handset to DECT numbers
  968. for (0..$handsetCount) {
  969. # 0 Handset FonUser
  970. push @readoutCmdArray, [ "", "ctlmgr_ctl r dect settings/Handset".$_."/User", "" ];
  971. # 1 Handset manufacturer
  972. push @readoutCmdArray, [ "", "ctlmgr_ctl r dect settings/Handset".$_."/Manufacturer" ];
  973. # 2 Phone Model
  974. push @readoutCmdArray, [ "", "ctlmgr_ctl r dect settings/Handset".$_."/Model", "model" ];
  975. # 3 Firmware Version
  976. push @readoutCmdArray, [ "", "ctlmgr_ctl r dect settings/Handset".$_."/FWVersion" ];
  977. }
  978. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  979. # Handset and DECT user can be in different orders
  980. for (0..$handsetCount) {
  981. my $offset = $_ * 4;
  982. my $dectUserID = $resultArray->[$offset];
  983. if ($dectUserID) {
  984. my $dectUser = $dectFonID{$dectUserID}{User};
  985. push @roReadings, "dect".$dectUser."_manufacturer|" . $resultArray->[ $offset + 1 ];
  986. FRITZBOX_Log $hash, 5, "dect".$dectUser."_manufacturer: " . $resultArray->[ $offset + 1 ];
  987. push @roReadings, "dect".$dectUser."_model|" . $resultArray->[ $offset + 2 ];
  988. FRITZBOX_Log $hash, 5, "dect".$dectUser."_model: " . $resultArray->[ $offset + 2 ];
  989. push @roReadings, "dect".$dectUser."_fwVersion|" . $resultArray->[ $offset + 3 ];
  990. FRITZBOX_Log $hash, 5, "dect".$dectUser."_fwVersion: " . $resultArray->[ $offset + 3 ];
  991. my $intern = $dectFonID{$dectUserID}{Intern};
  992. push @roReadings, "fhem->$intern->brand|" . $resultArray->[ $offset + 1 ];
  993. push @roReadings, "fhem->$intern->model|" . $resultArray->[ $offset + 2 ];;
  994. }
  995. }
  996. # Analog Fons Name
  997. for (1..$fonCount) {
  998. push @readoutCmdArray, ["fon".$_, "ctlmgr_ctl r telcfg settings/MSN/Port".($_-1)."/Name" ];
  999. push @readoutCmdArray, ["fon".$_."_out", "ctlmgr_ctl r telcfg settings/MSN/Port".($_-1)."/MSN" ];
  1000. }
  1001. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  1002. # Number of analog Fons
  1003. for (1..$fonCount) {
  1004. push @roReadings, "fon".$_."_intern|".$_
  1005. if $resultArray->[($_-1)*2];
  1006. }
  1007. # Prepare new command array
  1008. # Check if TAM is displayed
  1009. for (0..$tamCount-1) {
  1010. push @readoutCmdArray, [ "", "ctlmgr_ctl r tam settings/TAM".$_."/Display" ];
  1011. }
  1012. # Check if user (parent control) is not completely blocked
  1013. for (0..$userCount-1)
  1014. {
  1015. push @readoutCmdArray, ["", "ctlmgr_ctl r user settings/user".$_."/filter_profile_UID" ];
  1016. }
  1017. #!!! Execute commands !!!
  1018. $resultArray = FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  1019. # Prepare new command array
  1020. #Get TAM readings
  1021. for (0..$tamCount-1) {
  1022. $rName = "tam".($_+1);
  1023. if ($resultArray->[$_] eq "1" || defined $hash->{READINGS}{$rName} )
  1024. {
  1025. push @readoutCmdArray, [ $rName, "ctlmgr_ctl r tam settings/TAM". $_ ."/Name" ];
  1026. push @readoutCmdArray, [ $rName."_state", "ctlmgr_ctl r tam settings/TAM".$_."/Active", "onoff" ];
  1027. push @readoutCmdArray, [ $rName."_newMsg", "ctlmgr_ctl r tam settings/TAM".$_."/NumNewMessages" ];
  1028. push @readoutCmdArray, [ $rName."_oldMsg", "ctlmgr_ctl r tam settings/TAM".$_."/NumOldMessages" ];
  1029. }
  1030. }
  1031. # user profiles
  1032. $i=0;
  1033. $rName = "user01";
  1034. while ($i<$userCount || defined $hash->{READINGS}{$rName})
  1035. {
  1036. # do not show data for unlimited, blocked or default access rights
  1037. if ($resultArray->[$i+$tamCount] !~ /^filtprof[134]$/ || defined $hash->{READINGS}{$rName} )
  1038. {
  1039. push @readoutCmdArray, [$rName, "ctlmgr_ctl r user settings/user".$i."/name", "deviceip" ];
  1040. push @readoutCmdArray, [$rName."_thisMonthTime", "ctlmgr_ctl r user settings/user".$i."/this_month_time", "secondsintime" ];
  1041. push @readoutCmdArray, [$rName."_todayTime", "ctlmgr_ctl r user settings/user".$i."/today_time", "secondsintime" ];
  1042. push @readoutCmdArray, [$rName."_todaySeconds", "ctlmgr_ctl r user settings/user".$i."/today_time" ];
  1043. push @readoutCmdArray, [$rName."_type", "ctlmgr_ctl r user settings/user".$i."/type", "usertype" ];
  1044. }
  1045. $i++;
  1046. $rName = sprintf ("user%02d",$i+1);
  1047. }
  1048. # Diversity
  1049. $i=0;
  1050. $rName = "diversity1";
  1051. while ( $i < $divCount || defined $hash->{READINGS}{$rName} )
  1052. {
  1053. # Diversity number
  1054. push @readoutCmdArray, [$rName, "ctlmgr_ctl r telcfg settings/Diversity".$i."/MSN" ];
  1055. # Diversity state
  1056. push @readoutCmdArray, [$rName."_state", "ctlmgr_ctl r telcfg settings/Diversity".$i."/Active", "onoff" ];
  1057. # Diversity destination
  1058. push @readoutCmdArray, [$rName."_dest", "ctlmgr_ctl r telcfg settings/Diversity".$i."/Destination"];
  1059. $i++;
  1060. $rName = "diversity".($i+1);
  1061. }
  1062. # !!! Execute commands !!!
  1063. FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  1064. }
  1065. # WLAN
  1066. push @readoutCmdArray, [ "box_wlan_2.4GHz", "ctlmgr_ctl r wlan settings/ap_enabled", "onoff" ];
  1067. # 2nd WLAN
  1068. push @readoutCmdArray, [ "box_wlan_5GHz", "ctlmgr_ctl r wlan settings/ap_enabled_scnd", "onoff" ];
  1069. # Gäste WLAN
  1070. push @readoutCmdArray, [ "box_guestWlan", "ctlmgr_ctl r wlan settings/guest_ap_enabled", "onoff" ];
  1071. push @readoutCmdArray, [ "box_guestWlanRemain", "ctlmgr_ctl r wlan settings/guest_time_remain", ];
  1072. # Dect
  1073. push @readoutCmdArray, [ "box_dect", "ctlmgr_ctl r dect settings/enabled", "onoff" ];
  1074. # Music on Hold
  1075. push @readoutCmdArray, [ "box_moh", "ctlmgr_ctl r telcfg settings/MOHType", "mohtype" ];
  1076. # Power Rate
  1077. push @readoutCmdArray, [ "box_powerRate", "ctlmgr_ctl r power status/rate_sumact"];
  1078. # Alarm clock
  1079. for (0..2)
  1080. {
  1081. # Alarm clock name
  1082. push @readoutCmdArray, ["alarm".($_+1), "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Name" ];
  1083. # Alarm clock state
  1084. push @readoutCmdArray, ["alarm".($_+1)."_state", "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Active", "onoff" ];
  1085. # Alarm clock time
  1086. push @readoutCmdArray, ["alarm".($_+1)."_time", "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Time", "altime" ];
  1087. # Alarm clock number
  1088. push @readoutCmdArray, ["alarm".($_+1)."_target", "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Number", "alnumber" ];
  1089. # Alarm clock weekdays
  1090. push @readoutCmdArray, ["alarm".($_+1)."_wdays", "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Weekdays", "aldays" ];
  1091. }
  1092. FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings );
  1093. push @roReadings, "readoutTime|" . sprintf( "%.2f", time()-$startTime);
  1094. $returnStr .= join('|', @roReadings );
  1095. FRITZBOX_Telnet_CloseCon ( $hash );
  1096. FRITZBOX_Log $hash, 4, "Captured " . @roReadings . " values";
  1097. FRITZBOX_Log $hash, 5, "Handover to main process (".length ($returnStr)."): ".$returnStr;
  1098. return $name."|".encode_base64($returnStr,"");
  1099. } # End FRITZBOX_Readout_Run_Shell
  1100. # http://fritz.box/cgi-bin/webcm?wlan:settings/guest_ap_enabled=1&sid=
  1101. # FRITZBOX_Log $hash, 3, "Web connection established with $sid";
  1102. # my $urlcgi = 'http://'.$host.'/cgi-bin/webcm';
  1103. # my $response = $agent->post( $urlcgi,
  1104. # [
  1105. # "sid" => $sid,
  1106. # "getpage"=>"../html/query.txt",
  1107. # "var:cnt"=>"1",
  1108. # "var:n[0]"=>"wlan:settings/ap_enabled"
  1109. # "getpage" => "../html/de/menus/menu2.html",
  1110. # "errorpage" => "../html/index.html",
  1111. # "var:lang" => "de",
  1112. # "var:pagename" => "home",
  1113. # "var:menu" => "home",
  1114. # "wlan:settings/guest_ap_enabled" => "1"
  1115. # ],
  1116. # );
  1117. # FRITZBOX_Log $hash, 3, "Debug: ".$response->content;
  1118. # Starts the data capturing via query.lua and sets the new timer
  1119. #######################################################################
  1120. sub FRITZBOX_Readout_Run_Web($)
  1121. {
  1122. my ($name) = @_;
  1123. my $hash = $defs{$name};
  1124. my $result;
  1125. my $rName;
  1126. my @roReadings;
  1127. my %dectFonID;
  1128. my %resultHash;
  1129. my $startTime = time();
  1130. my $runNo;
  1131. my $sid;
  1132. #Start update
  1133. FRITZBOX_Log $hash, 4, "Prepare query string for luaQuery.";
  1134. my $queryStr = "&radio=configd:settings/WEBRADIO/list(Name)"; # Webradio
  1135. $queryStr .= "&box_dect=dect:settings/enabled"; # DECT Sender
  1136. $queryStr .= "&handset=dect:settings/Handset/list(User,Manufacturer,Model,FWVersion)"; # DECT Handsets
  1137. $queryStr .= "&wlanList=wlan:settings/wlanlist/list(mac,speed,speed_rx,rssi)"; # WLAN devices
  1138. $queryStr .= "&wlanListNew=wlan:settings/wlanlist/list(mac,speed,rssi)"; # WLAN devices fw>=6.69
  1139. #wlan:settings/wlanlist/list(hostname,mac,UID,state,rssi,quality,is_turbo,cipher,wmm_active,powersave,is_ap,ap_state,is_repeater,flags,flags_set,mode,is_guest,speed,speed_rx,channel_width,streams) #wlan:settings/wlanlist/list(hostname,mac,UID,state,rssi,quality,is_turbo,wmm_active,cipher,powersave,is_repeater,flags,flags_set,mode,is_guest,speed,speed_rx,speed_rx_max,speed_tx_max,channel_width,streams,mu_mimo_group,is_fail_client)
  1140. $queryStr .= "&lanDevice=landevice:settings/landevice/list(mac,ip,ethernet,ethernet_port,guest,name,active,online,wlan,speed,UID)"; # LAN devices
  1141. $queryStr .= "&lanDeviceNew=landevice:settings/landevice/list(mac,ip,ethernet,guest,name,active,online,wlan,speed,UID)"; # LAN devices fw>=6.69
  1142. #landevice:settings/landevice/list(name,ip,mac,UID,dhcp,wlan,ethernet,active,static_dhcp,manu_name,wakeup,deleteable,source,online,speed,wlan_UIDs,auto_wakeup,guest,url,wlan_station_type,vendorname)
  1143. #landevice:settings/landevice/list(name,ip,mac,parentname,parentuid,ethernet_port,wlan_show_in_monitor,plc,ipv6_ifid,parental_control_abuse,plc_UIDs) #landevice:settings/landevice/list(name,ip,mac,UID,dhcp,wlan,ethernet,active,static_dhcp,manu_name,wakeup,deleteable,source,online,speed,wlan_UIDs,auto_wakeup,guest,url,wlan_station_type,vendorname,parentname,parentuid,ethernet_port,wlan_show_in_monitor,plc,ipv6_ifid,parental_control_abuse,plc_UIDs)
  1144. $queryStr .= "&init=telcfg:settings/Foncontrol"; # Init
  1145. $queryStr .= "&box_stdDialPort=telcfg:settings/DialPort"; #Dial Port
  1146. $queryStr .= "&dectUser=telcfg:settings/Foncontrol/User/list(Id,Name,Intern,IntRingTone,AlarmRingTone0,RadioRingID,ImagePath,G722RingTone,G722RingToneName)"; # DECT Numbers
  1147. $queryStr .= "&fonPort=telcfg:settings/MSN/Port/list(Name,MSN)"; # Fon ports
  1148. $queryStr .= "&alarmClock=telcfg:settings/AlarmClock/list(Name,Active,Time,Number,Weekdays)"; # Alarm Clock
  1149. $queryStr .= "&diversity=telcfg:settings/Diversity/list(MSN,Active,Destination)"; # Diversity (Rufumleitung)
  1150. $queryStr .= "&box_moh=telcfg:settings/MOHType"; # Music on Hold
  1151. $queryStr .= "&box_fwVersion=logic:status/nspver"; # FW Version #uimodlogic:status/nspver
  1152. $queryStr .= "&box_fwVersion_neu=uimodlogic:status/nspver"; # FW Version
  1153. $queryStr .= "&box_powerRate=power:status/rate_sumact"; # Power Rate
  1154. $queryStr .= "&tam=tam:settings/TAM/list(Name,Display,Active,NumNewMessages,NumOldMessages)"; # TAM
  1155. $queryStr .= "&box_cpuTemp=power:status/act_temperature"; # Box CPU Temperatur
  1156. $queryStr .= "&box_ipExtern=connection0:status/ip"; # Externe IP-Adresse
  1157. $queryStr .= "&box_connect=connection0:status/connect"; # Internet connection state
  1158. $queryStr .= "&box_tr064=tr064:settings/enabled"; # TR064
  1159. $queryStr .= "&box_tr069=tr069:settings/enabled"; # TR069
  1160. $queryStr .= "&box_fwUpdate=updatecheck:status/update_available_hint";
  1161. $queryStr .= "&userProfil=user:settings/user/list(name,filter_profile_UID,this_month_time,today_time,type)"; # User profiles
  1162. $queryStr .= "&userProfilNew=user:settings/user/list(name,type)"; # User profiles fw>=6.69
  1163. $queryStr .= "&is_double_wlan=wlan:settings/feature_flags/DBDC"; # Box Feature
  1164. $queryStr .= "&box_wlan_24GHz=wlan:settings/ap_enabled"; # WLAN
  1165. $queryStr .= "&box_wlan_5GHz=wlan:settings/ap_enabled_scnd"; # 2nd WLAN
  1166. $queryStr .= "&box_guestWlan=wlan:settings/guest_ap_enabled"; # Gäste WLAN
  1167. $queryStr .= "&box_guestWlanRemain=wlan:settings/guest_time_remain";
  1168. $queryStr .= "&box_guestWlanRemain=wlan:settings/guest_time_remain";
  1169. $queryStr .= "&TodayBytesReceivedHigh=inetstat:status/Today/BytesReceivedHigh";
  1170. $queryStr .= "&TodayBytesReceivedLow=inetstat:status/Today/BytesReceivedLow";
  1171. $queryStr .= "&TodayBytesSentHigh=inetstat:status/Today/BytesSentHigh";
  1172. $queryStr .= "&TodayBytesSentLow=inetstat:status/Today/BytesSentLow";
  1173. $queryStr .= "&GSM_RSSI=gsm:settings/RSSI";
  1174. $queryStr .= "&GSM_NetworkState=gsm:settings/NetworkState";
  1175. $queryStr .= "&GSM_AcT=gsm:settings/AcT";
  1176. $queryStr .= "&UMTS_enabled=umts:settings/enabled";
  1177. $queryStr .= "&userTicket=userticket:settings/ticket/list(id)";
  1178. # $queryStr .= "&GSM_MaxUL=gsm:settings/MaxUL";
  1179. # $queryStr .= "&GSM_MaxDL=gsm:settings/MaxDL";
  1180. # $queryStr .= "&GSM_CurrentUL=gsm:settings/CurrentUL";
  1181. # $queryStr .= "&GSM_CurrentDL=gsm:settings/CurrentDL";
  1182. # $queryStr .= "&GSM_Established=gsm:settings/Established";
  1183. # $queryStr .= "&GSM_BER=gsm:settings/BER";
  1184. # $queryStr .= "&GSM_Manufacturer=gsm:settings/Manufacturer";
  1185. # $queryStr .= "&GSM_Model=gsm:settings/Model";
  1186. # $queryStr .= "&GSM_Operator=gsm:settings/Operator";
  1187. # $queryStr .= "&GSM_PIN_State=gsm:settings/PIN_State";
  1188. # $queryStr .= "&GSM_Trycount=gsm:settings/Trycount";
  1189. # $queryStr .= "&GSM_ModemPresent=gsm:settings/ModemPresent";
  1190. # $queryStr .= "&GSM_AllowRoaming=gsm:settings/AllowRoaming";
  1191. # $queryStr .= "&GSM_VoiceStatus=gsm:settings/VoiceStatus";
  1192. # $queryStr .= "&GSM_SubscriberNumber=gsm:settings/SubscriberNumber";
  1193. # $queryStr .= "&GSM_InHomeZone=gsm:settings/InHomeZone";
  1194. # $queryStr .= "&UMTS_enabled=umts:settings/enabled";
  1195. # $queryStr .= "&UMTS_name=umts:settings/name";
  1196. # $queryStr .= "&UMTS_provider=umts:settings/provider";
  1197. # $queryStr .= "&UMTS_idle=umts:settings/idle";
  1198. # $queryStr .= "&UMTS_backup_enable=umts:settings/backup_enable";
  1199. # $queryStr .= "&UMTS_backup_downtime=umts:settings/backup_downtime";
  1200. # $queryStr .= "&UMTS_backup_reverttime=umts:settings/backup_reverttime";
  1201. $result = FRITZBOX_Web_Query( $hash, $queryStr) ;
  1202. # Abbruch wenn Fehler beim Lesen der Fritzbox-Antwort
  1203. if ( defined $result->{Error} ) {
  1204. FRITZBOX_Log $hash, 2, "Error: ".$result->{Error};
  1205. my $returnStr = "Error|" . $result->{Error};
  1206. $returnStr .= "|fhem->sidTime|0" if defined $result->{ResetSID};
  1207. $returnStr .= "|" . join('|', @roReadings ) if int @roReadings;
  1208. return $name."|".encode_base64($returnStr,"");
  1209. }
  1210. if ( defined $result->{AuthorizationRequired} ) {
  1211. FRITZBOX_Log $hash, 2, "Error: AuthorizationRequired=".$result->{AuthorizationRequired};
  1212. my $returnStr = "Error|Authorization required";
  1213. $returnStr .= "|fhem->sidTime|0" if defined $result->{ResetSID};
  1214. $returnStr .= "|" . join('|', @roReadings ) if int @roReadings;
  1215. return $name."|".encode_base64($returnStr,"");
  1216. }
  1217. # !!! copes with fw 6.69 !!!
  1218. if ( ref $result->{wlanList} ne 'ARRAY' ) {
  1219. FRITZBOX_Log $hash, 4, "Recognized query answer of firmware 6.69";
  1220. my $result2;
  1221. my $newQueryPart;
  1222. # gets WLAN speed for fw>=6.69
  1223. $queryStr="";
  1224. foreach ( @{ $result->{wlanListNew} } ) {
  1225. $newQueryPart = "&".$_->{_node}."=wlan:settings/".$_->{_node}."/speed_rx";
  1226. if (length($queryStr.$newQueryPart) < 4050) {
  1227. $queryStr .= $newQueryPart;
  1228. }
  1229. else {
  1230. $result2 = FRITZBOX_Web_Query( $hash, $queryStr );
  1231. %{$result} = ( %{$result}, %{$result2 } );
  1232. $queryStr = $newQueryPart;
  1233. }
  1234. }
  1235. # gets LAN-Port for fw>=6.69
  1236. foreach ( @{ $result->{lanDeviceNew} } ) {
  1237. $newQueryPart = "&".$_->{_node}."=landevice:settings/".$_->{_node}."/ethernet_port";
  1238. if (length($queryStr.$newQueryPart) < 4050) {
  1239. $queryStr .= $newQueryPart;
  1240. }
  1241. else {
  1242. $result2 = FRITZBOX_Web_Query( $hash, $queryStr );
  1243. %{$result} = ( %{$result}, %{$result2 } );
  1244. $queryStr = $newQueryPart;
  1245. }
  1246. }
  1247. # get missing user-fields for fw>=6.69
  1248. foreach ( @{ $result->{userProfilNew} } ) {
  1249. $newQueryPart = "&".$_->{_node}."_filter=user:settings/".$_->{_node}."/filter_profile_UID";
  1250. $newQueryPart .= "&".$_->{_node}."_month=user:settings/".$_->{_node}."/this_month_time";
  1251. $newQueryPart .= "&".$_->{_node}."_today=user:settings/".$_->{_node}."/today_time";
  1252. if (length($queryStr.$newQueryPart) < 4050) {
  1253. $queryStr .= $newQueryPart;
  1254. }
  1255. else {
  1256. $result2 = FRITZBOX_Web_Query( $hash, $queryStr );
  1257. %{$result} = ( %{$result}, %{$result2 } );
  1258. $queryStr = $newQueryPart;
  1259. }
  1260. }
  1261. # Final Web-Query
  1262. $result2 = FRITZBOX_Web_Query( $hash, $queryStr );
  1263. %{$result} = ( %{$result}, %{$result2 } );
  1264. # create fields for wlanList-Entries (for fw 6.69)
  1265. $result->{wlanList} = $result->{wlanListNew};
  1266. foreach ( @{ $result->{wlanList} } ) {
  1267. $_->{speed_rx} = $result->{ $_->{_node} };
  1268. }
  1269. # Create fields for lanDevice-Entries (for fw 6.69)
  1270. $result->{lanDevice} = $result->{lanDeviceNew};
  1271. foreach ( @{ $result->{lanDevice} } ) {
  1272. $_->{ethernet_port} = $result->{ $_->{_node} };
  1273. }
  1274. # Create fields for user-Entries (for fw 6.69)
  1275. $result->{userProfil} = $result->{userProfilNew};
  1276. foreach ( @{ $result->{userProfil} } ) {
  1277. $_->{filter_profile_UID} = $result->{ $_->{_node}."_filter" };
  1278. $_->{this_month_time} = $result->{ $_->{_node}."_month" };
  1279. $_->{today_time} = $result->{ $_->{_node}."_today" };
  1280. }
  1281. }
  1282. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sid", $result->{sid};
  1283. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sidTime", time();
  1284. # Dect-Geräteliste erstellen
  1285. $runNo = 0;
  1286. foreach ( @{ $result->{dectUser} } ) {
  1287. my $intern = $_->{Intern};
  1288. my $id = $_->{Id};
  1289. if ($intern)
  1290. {
  1291. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo, $_->{Name} ;
  1292. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_intern", $intern ;
  1293. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_alarmRingTone", $_->{AlarmRingTone0}, "ringtone" ;
  1294. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_intRingTone", $_->{IntRingTone}, "ringtone" ;
  1295. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_radio", $_->{RadioRingID}, "radio" ;
  1296. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_custRingTone", $_->{G722RingTone} ;
  1297. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_custRingToneName", $_->{G722RingToneName} ;
  1298. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$runNo."_imagePath", $_->{ImagePath} ;
  1299. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->$intern->id", $id ;
  1300. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->$intern->userId", $runNo;
  1301. $dectFonID{$id}{Intern} = $intern;
  1302. $dectFonID{$id}{User} = $runNo;
  1303. }
  1304. $runNo++;
  1305. }
  1306. # Handset der internen Nummer zuordnen
  1307. foreach ( @{ $result->{handset} } ) {
  1308. my $dectUserID = $_->{User};
  1309. my $dectUser = $dectFonID{$dectUserID}{User};
  1310. my $intern = $dectFonID{$dectUserID}{Intern};
  1311. if ($dectUser) {
  1312. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$dectUser."_manufacturer", $_->{Manufacturer};
  1313. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$dectUser."_model", $_->{Model}, "model";
  1314. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "dect".$dectUser."_fwVersion", $_->{FWVersion};
  1315. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->$intern->brand", $_->{Manufacturer};
  1316. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->$intern->model", $_->{Model}, "model";
  1317. }
  1318. }
  1319. # Analog Fons Name
  1320. $runNo=1;
  1321. foreach ( @{ $result->{fonPort} } ) {
  1322. if ( $_->{Name} )
  1323. {
  1324. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fon".$runNo, $_->{Name};
  1325. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fon".$runNo."_out", $_->{MSN};
  1326. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fon".$runNo."_intern", $runNo;
  1327. }
  1328. $runNo++;
  1329. }
  1330. # Internetradioliste erzeugen
  1331. $runNo = 0;
  1332. $rName = "radio00";
  1333. foreach ( @{ $result->{radio} } ) {
  1334. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $_->{Name};
  1335. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->radio->".$runNo, $_->{Name};
  1336. $runNo++;
  1337. $rName = sprintf ("radio%02d",$runNo);
  1338. }
  1339. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->radioCount", $runNo;
  1340. # Create WLAN-List
  1341. my %wlanList;
  1342. #to keep compatibility with firmware <= v3.67
  1343. if ( ref $result->{wlanList} eq 'ARRAY' ) {
  1344. foreach ( @{ $result->{wlanList} } ) {
  1345. my $mac = $_->{mac};
  1346. $mac =~ s/:/_/g;
  1347. $wlanList{$mac}{speed} .= $_->{speed};
  1348. $wlanList{$mac}{speed_rx} .= $_->{speed_rx};
  1349. #$wlanList{$mac}{speed_rx} = $result_lan->{$_->{_node}};
  1350. $wlanList{$mac}{rssi} .= $_->{rssi};
  1351. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->wlanDevice->".$mac."->speed", $_->{speed};
  1352. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->wlanDevice->".$mac."->speed_rx", $wlanList{$mac}{speed_rx};
  1353. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->wlanDevice->".$mac."->rssi", $_->{rssi};
  1354. }
  1355. }
  1356. # Create LanDevice list and delete inactive devices
  1357. my %oldLanDevice;
  1358. #collect current mac-readings (to delete the ones that are inactive or disappeared)
  1359. foreach (keys %{ $hash->{READINGS} }) {
  1360. $oldLanDevice{$_} = $hash->{READINGS}{$_}{VAL} if $_ =~ /^mac_/ && defined $hash->{READINGS}{$_}{VAL};
  1361. }
  1362. %landevice = ();
  1363. my $wlanCount = 0;
  1364. my $gWlanCount = 0;
  1365. if ( ref $result->{lanDevice} eq 'ARRAY' ) {
  1366. foreach ( @{ $result->{lanDevice} } ) {
  1367. my $dIp = $_->{ip};
  1368. my $UID = $_->{UID};
  1369. my $dName = $_->{name};
  1370. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->landevice->$dIp", $dName;
  1371. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->landevice->$UID", $dName;
  1372. $landevice{$dIp}=$dName;
  1373. $landevice{$UID}=$dName;
  1374. # Create a reading if a landevice is connected
  1375. if ( $_->{active} ) {
  1376. my $mac = $_->{mac};
  1377. $mac =~ s/:/_/g;
  1378. if ( !$_->{ethernet} && $_->{wlan} ) {
  1379. $dName .= " (";
  1380. $dName .= "g" if $_->{guest};
  1381. $dName .= "WLAN";
  1382. $dName .= ", " . $wlanList{$mac}{speed} . " / " . $wlanList{$mac}{speed_rx} . " Mbit/s, ". $wlanList{$mac}{rssi}
  1383. if defined $wlanList{$mac};
  1384. $dName .= ")";
  1385. }
  1386. if ( $_->{ethernet_port} ) {
  1387. $dName .= " (";
  1388. $dName .= "g" if $_->{guest};
  1389. $dName .= "LAN" . $_->{ethernet_port};
  1390. #$dName .= "LAN" . $result_lan->{$_->{_node}};
  1391. $dName .= ", 1 Gbit/s" if $_->{speed} eq "1000";
  1392. $dName .= ", " . $_->{speed} . " Mbit/s" if $_->{speed} ne "1000" && $_->{speed} ne "0";
  1393. $dName .= ")";
  1394. }
  1395. my $rName = "mac_".$mac;
  1396. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $dName;
  1397. $wlanCount++ if $_->{wlan} ;
  1398. $gWlanCount++ if $_->{wlan} && $_->{guest} ;
  1399. # Remove mac address from oldLanDevice-List
  1400. delete $oldLanDevice{$rName} if exists $oldLanDevice{$rName};
  1401. }
  1402. }
  1403. }
  1404. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "box_wlanCount", $wlanCount);
  1405. FRITZBOX_Readout_Add_Reading ($hash, \@roReadings, "box_guestWlanCount", $gWlanCount);
  1406. # Remove inactive or non existing mac-readings in two steps
  1407. foreach ( keys %oldLanDevice ) {
  1408. # set the mac readings to 'inactive' and delete at next readout
  1409. if ( $oldLanDevice{$_} ne "inactive" ) {
  1410. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $_, "inactive";
  1411. }
  1412. else {
  1413. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $_, "";
  1414. }
  1415. }
  1416. # WLANs
  1417. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_2.4GHz", $result->{box_wlan_24GHz}, "onoff";
  1418. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_5GHz", $result->{box_wlan_5GHz}, "onoff";
  1419. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlan", $result->{box_guestWlan}, "onoff";
  1420. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlanRemain", $result->{box_guestWlanRemain};
  1421. # Dect
  1422. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_dect", $result->{box_dect}, "onoff";
  1423. # Music on Hold
  1424. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_moh", $result->{box_moh}, "mohtype";
  1425. # Power Rate
  1426. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_powerRate", $result->{box_powerRate};
  1427. # Box Features
  1428. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->is_double_wlan", $result->{is_double_wlan}, "01";
  1429. # Box model and firmware
  1430. if ($result->{box_fwVersion}) {
  1431. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_fwVersion", $result->{box_fwVersion};
  1432. } else { # Ab Version 6.90
  1433. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_fwVersion", $result->{box_fwVersion_neu};
  1434. }
  1435. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_fwUpdate", $result->{box_fwUpdate};
  1436. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_tr064", $result->{box_tr064}, "onoff";
  1437. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_tr069", $result->{box_tr069}, "onoff";
  1438. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_stdDialPort", $result->{box_stdDialPort}, "dialport";
  1439. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_ipExtern", $result->{box_ipExtern};
  1440. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_connect", $result->{box_connect};
  1441. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_cpuTemp", $result->{box_cpuTemp};
  1442. # GSM
  1443. #FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_modem", $result->{GSM_ModemPresent};
  1444. if (defined $result->{GSM_NetworkState} && $result->{GSM_NetworkState} ne "0") {
  1445. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_rssi", $result->{GSM_RSSI};
  1446. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_state", $result->{GSM_NetworkState}, "gsmnetstate";
  1447. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_technology", $result->{GSM_AcT}, "gsmact";
  1448. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_internet", $result->{UMTS_enabled};
  1449. }
  1450. else {
  1451. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_rssi", "";
  1452. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_state", "";
  1453. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_technology", "";
  1454. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "gsm_internet", "";
  1455. }
  1456. # Alarm clock
  1457. $runNo = 1;
  1458. foreach ( @{ $result->{alarmClock} } ) {
  1459. next if $_->{Name} eq "er";
  1460. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "alarm".$runNo, $_->{Name};
  1461. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "alarm".$runNo."_state", $_->{Active}, "onoff";
  1462. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "alarm".$runNo."_time", $_->{Time}, "altime";
  1463. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "alarm".$runNo."_target", $_->{Number}, "alnumber";
  1464. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "alarm".$runNo."_wdays", $_->{Weekdays}, "aldays";
  1465. $runNo++;
  1466. }
  1467. #Get TAM readings
  1468. $runNo = 1;
  1469. foreach ( @{ $result->{tam} } ) {
  1470. $rName = "tam".$runNo;
  1471. if ($_->{Display} eq "1")
  1472. {
  1473. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $_->{Name};
  1474. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_state", $_->{Active}, "onoff";
  1475. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_newMsg", $_->{NumNewMessages};
  1476. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_oldMsg", $_->{NumOldMessages};
  1477. }
  1478. # Löschen ausgeblendeter TAMs
  1479. elsif (defined $hash->{READINGS}{$rName} )
  1480. {
  1481. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName,"";
  1482. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_state", "";
  1483. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_newMsg","";
  1484. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_oldMsg","";
  1485. }
  1486. $runNo++;
  1487. }
  1488. # user profiles
  1489. $runNo = 1;
  1490. $rName = "user01";
  1491. if ( ref $result->{userProfil} eq 'ARRAY' ) {
  1492. foreach ( @{ $result->{userProfil} } ) {
  1493. # do not show data for unlimited, blocked or default access rights
  1494. if ($_->{filter_profile_UID} !~ /^filtprof[134]$/ || defined $hash->{READINGS}{$rName} ) {
  1495. if ( $_->{type} eq "1" && $_->{name} =~ /\(landev(.*)\)/ ) {
  1496. my $UID = "landevice".$1;
  1497. $_->{name} = $landevice{$UID};
  1498. }
  1499. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $_->{name}, "deviceip";
  1500. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_thisMonthTime", $_->{this_month_time}, "secondsintime";
  1501. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_todayTime", $_->{today_time}, "secondsintime";
  1502. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_todaySeconds", $_->{today_time};
  1503. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_type", $_->{type}, "usertype";
  1504. }
  1505. $runNo++;
  1506. $rName = sprintf ("user%02d",$runNo);
  1507. }
  1508. }
  1509. # user ticket (extension of online time)
  1510. if ( ref $result->{userTicket} eq 'ARRAY' ) {
  1511. $runNo=1;
  1512. my $maxTickets = AttrVal( $name, "userTickets", 1 );
  1513. $rName = "userTicket01";
  1514. foreach ( @{ $result->{userTicket} } ) {
  1515. last if $runNo > $maxTickets;
  1516. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $_->{id};
  1517. $runNo++;
  1518. $rName = sprintf ("userTicket%02d",$runNo);
  1519. }
  1520. }
  1521. # Diversity
  1522. $runNo=1;
  1523. $rName = "diversity1";
  1524. foreach ( @{ $result->{diversity} } ) {
  1525. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName, $_->{MSN};
  1526. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_state", $_->{Active}, "onoff" ;
  1527. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, $rName."_dest", $_->{Destination};
  1528. $runNo++;
  1529. $rName = "diversity".$runNo;
  1530. }
  1531. # statistics
  1532. # attr global showInternalValues 0
  1533. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, ".box_TodayBytesReceivedHigh", $result->{TodayBytesReceivedHigh};
  1534. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, ".box_TodayBytesReceivedLow", $result->{TodayBytesReceivedLow};
  1535. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, ".box_TodayBytesSentHigh", $result->{TodayBytesSentHigh};
  1536. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, ".box_TodayBytesSentLow", $result->{TodayBytesSentLow};
  1537. push @roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  1538. my $returnStr = join('|', @roReadings );
  1539. FRITZBOX_Log $hash, 4, "Captured " . @roReadings . " values";
  1540. FRITZBOX_Log $hash, 5, "Handover to main process (".length ($returnStr)."): ".$returnStr;
  1541. return $name."|".encode_base64($returnStr,"");
  1542. } # End FRITZBOX_Readout_Run_Web
  1543. #######################################################################
  1544. sub FRITZBOX_Readout_Done($)
  1545. {
  1546. my ($string) = @_;
  1547. unless (defined $string)
  1548. {
  1549. Log 1, "Fatal Error: no parameter handed over";
  1550. return;
  1551. }
  1552. my ($name,$string2) = split("\\|", $string, 2);
  1553. my $hash = $defs{$name};
  1554. FRITZBOX_Log $hash, 4, "Back at main process";
  1555. # delete the marker for RUNNING_PID process
  1556. delete($hash->{helper}{READOUT_RUNNING_PID});
  1557. $string2 = decode_base64($string2);
  1558. FRITZBOX_Readout_Process ($hash, $string2);
  1559. }
  1560. #######################################################################
  1561. sub FRITZBOX_Readout_Process($$)
  1562. {
  1563. my ($hash,$string) = @_;
  1564. # Fatal Error: no hash parameter handed over
  1565. unless (defined $hash) {
  1566. Log 1, "Fatal Error: no hash parameter handed over";
  1567. return;
  1568. }
  1569. my $name = $hash->{NAME};
  1570. my (%values) = split("\\|", $string);
  1571. FRITZBOX_Log $hash, 4, "Processing ". keys(%values)." readouts.";
  1572. readingsBeginUpdate($hash);
  1573. if ( defined $values{Error} ) {
  1574. readingsBulkUpdate( $hash, "lastReadout", $values{Error} );
  1575. readingsBulkUpdate( $hash, "state", $values{Error} );
  1576. if (defined $values{"fhem->sidTime"}) {
  1577. $hash->{fhem}{sidTime} = $values{"fhem->sidTime"};
  1578. FRITZBOX_Log $hash, 4, "Reset SID";
  1579. }
  1580. }
  1581. else {
  1582. # Statistics
  1583. if ( defined $values{".box_TodayBytesReceivedLow"} && defined $hash->{READINGS}{".box_TodayBytesReceivedLow"}) {
  1584. my $valueHigh = $values{".box_TodayBytesReceivedHigh"} - $hash->{READINGS}{".box_TodayBytesReceivedHigh"}{VAL};
  1585. my $valueLow = $values{".box_TodayBytesReceivedLow"} - $hash->{READINGS}{".box_TodayBytesReceivedLow"}{VAL};
  1586. # Consider reset of day counter
  1587. if ($valueHigh < 0 || $valueHigh == 0 && $valueLow < 0) {
  1588. $valueLow = $values{".box_TodayBytesReceivedLow"};
  1589. $valueHigh = $values{".box_TodayBytesReceivedHigh"};
  1590. }
  1591. $valueHigh *= 2**22;
  1592. $valueLow /= 2**10;
  1593. my $time = time()-time_str2num($hash->{READINGS}{".box_TodayBytesReceivedLow"}{TIME});
  1594. $values{ "box_rateDown" } = sprintf ("%.3f", ($valueHigh+$valueLow) / $time );
  1595. }
  1596. if ( defined $values{".box_TodayBytesSentLow"} && defined $hash->{READINGS}{".box_TodayBytesSentLow"} ) {
  1597. my $valueHigh = $values{".box_TodayBytesSentHigh"} - $hash->{READINGS}{".box_TodayBytesSentHigh"}{VAL};
  1598. my $valueLow = $values{".box_TodayBytesSentLow"} - $hash->{READINGS}{".box_TodayBytesSentLow"}{VAL};
  1599. # Consider reset of day counter
  1600. if ($valueHigh < 0 || $valueHigh == 0 && $valueLow < 0) {
  1601. $valueLow = $values{".box_TodayBytesSentLow"};
  1602. $valueHigh = $values{".box_TodayBytesSentHigh"};
  1603. }
  1604. $valueHigh *= 2**22;
  1605. $valueLow /= 2**10;
  1606. my $time = time()-time_str2num($hash->{READINGS}{".box_TodayBytesSentLow"}{TIME});
  1607. $values{ "box_rateUp" } = sprintf ("%.3f", ($valueHigh+$valueLow) / $time );
  1608. }
  1609. # Fill all handed over readings
  1610. my $x = 0;
  1611. while (my ($rName, $rValue) = each(%values) ) {
  1612. #hash values
  1613. if ($rName =~ /->/) {
  1614. # 4 levels
  1615. my ($rName1,$rName2,$rName3,$rName4) = split /->/, $rName;
  1616. # 4th level (Internal Value)
  1617. if ($rName1 ne "" && defined $rName4) {
  1618. $hash->{$rName1}{$rName2}{$rName3}{$rName4} = $rValue;
  1619. }
  1620. # 3rd level (Internal Value)
  1621. elsif ($rName1 ne "" && defined $rName3) {
  1622. $hash->{$rName1}{$rName2}{$rName3} = $rValue;
  1623. }
  1624. # 1st level (Internal Value)
  1625. elsif ($rName1 eq "") {
  1626. $hash->{$rName2} = $rValue;
  1627. }
  1628. # 2nd levels
  1629. else {
  1630. $hash->{$rName1}{$rName2} = $rValue;
  1631. }
  1632. }
  1633. elsif ($rName eq "box_fwVersion" && defined $values{box_fwUpdate}) {
  1634. $rValue .= " (old)" if $values{box_fwUpdate} eq "1";
  1635. }
  1636. elsif ($rName eq "box_model") {
  1637. $hash->{MODEL} = $rValue;
  1638. $rValue .= " [".$values{box_oem}."]" if $values{box_oem};
  1639. }
  1640. if ($rName !~ /->|box_fwUpdate|box_oem|readoutTime/) {
  1641. if ($rValue ne "") {
  1642. readingsBulkUpdate( $hash, $rName, $rValue );
  1643. FRITZBOX_Log $hash, 5, "SET $rName = '$rValue'";
  1644. }
  1645. elsif ( exists $hash->{READINGS}{$rName} ) {
  1646. delete $hash->{READINGS}{$rName};
  1647. FRITZBOX_Log $hash, 5, "Delete reading $rName.";
  1648. }
  1649. else {
  1650. FRITZBOX_Log $hash, 5, "Ignore reading $rName.";
  1651. }
  1652. }
  1653. }
  1654. # Create state with wlan states
  1655. if ( defined $values{"box_wlan_2.4GHz"} ) {
  1656. my $newState = "WLAN: ";
  1657. if ( $values{"box_wlan_2.4GHz"} eq "on" ) {
  1658. $newState .= "on";
  1659. }
  1660. elsif ( $values{box_wlan_5GHz} ) {
  1661. if ( $values{box_wlan_5GHz} eq "on") {
  1662. $newState .= "on";
  1663. } else {
  1664. $newState .= "off";
  1665. }
  1666. }
  1667. else {
  1668. $newState .= "off";
  1669. }
  1670. $newState .=" gWLAN: ".$values{box_guestWlan} ;
  1671. $newState .=" (Remain: ".$values{box_guestWlanRemain}." min)"
  1672. if $values{box_guestWlan} eq "on" && $values{box_guestWlanRemain} > 0;
  1673. readingsBulkUpdate( $hash, "state", $newState);
  1674. FRITZBOX_Log $hash, 5, "SET state = '$newState'";
  1675. }
  1676. # adapt TR064-Mode
  1677. if ( defined $values{box_tr064} ) {
  1678. if ( $values{box_tr064} eq "off" && defined $hash->{SECPORT} ) {
  1679. FRITZBOX_Log $hash, 3, "TR-064 is switched off";
  1680. delete $hash->{SECPORT};
  1681. }
  1682. elsif ( $values{box_tr064} eq "on" && not defined $hash->{SECPORT} ) {
  1683. FRITZBOX_Log $hash, 3, "TR-064 is switched on";
  1684. my $tr064Port = FRITZBOX_TR064_Init ($hash, $hash->{HOST});
  1685. $hash->{SECPORT} = $tr064Port if $tr064Port;
  1686. }
  1687. }
  1688. my $msg = keys( %values )." values captured in ".$values{readoutTime}." s";
  1689. readingsBulkUpdate( $hash, "lastReadout", $msg );
  1690. FRITZBOX_Log $hash, 4, $msg;
  1691. }
  1692. readingsEndUpdate( $hash, 1 );
  1693. }
  1694. #######################################################################
  1695. sub FRITZBOX_Readout_Aborted($)
  1696. {
  1697. my ($hash) = @_;
  1698. delete($hash->{helper}{READOUT_RUNNING_PID});
  1699. my $msg = "Error: Timeout when reading Fritz!Box data.";
  1700. readingsSingleUpdate($hash, "lastReadout", $msg, 1);
  1701. readingsSingleUpdate($hash, "state", $msg, 1);
  1702. FRITZBOX_Log $hash, 1, $msg;
  1703. }
  1704. #######################################################################
  1705. sub FRITZBOX_Readout_Format($$$)
  1706. {
  1707. my ($hash, $format, $readout) = @_;
  1708. $readout = "" unless defined $readout;
  1709. return $readout unless defined( $format ) && $format ne "";
  1710. # return $readout unless $readout ne "" && $format ne "" ; #Funktioniert nicht bei $format "01"
  1711. if ($format eq "01" && $readout ne "1") {
  1712. $readout = "0";
  1713. }
  1714. return $readout unless $readout ne "";
  1715. if ($format eq "aldays") {
  1716. if ($readout eq "0") {
  1717. $readout = "once";
  1718. }
  1719. elsif ($readout >= 127) {
  1720. $readout = "daily";
  1721. }
  1722. else {
  1723. my $bitStr = $readout;
  1724. $readout = "";
  1725. foreach (sort {$a <=> $b} keys %alarmDays) {
  1726. $readout .= (($bitStr & $_) == $_) ? $alarmDays{$_}." " : "";
  1727. }
  1728. chop $readout;
  1729. }
  1730. }
  1731. elsif ($format eq "alnumber") {
  1732. my $intern = $readout;
  1733. if (1 <= $readout && $readout <=2) {
  1734. $readout = "FON $intern";
  1735. } elsif ($readout == 9) {
  1736. $readout = "all DECT";
  1737. } elsif (60 <= $readout && $readout <=65) {
  1738. $intern = $readout + 550;
  1739. $readout = "DECT $intern";
  1740. } elsif ($readout == 50) {
  1741. $readout = "all";
  1742. }
  1743. $readout .= " (".$hash->{fhem}{$intern}{name}.")"
  1744. if defined $hash->{fhem}{$intern}{name};
  1745. }
  1746. elsif ($format eq "altime") {
  1747. $readout =~ s/(\d\d)(\d\d)/$1:$2/;
  1748. }
  1749. elsif ($format eq "deviceip") {
  1750. $readout = $landevice{$readout}." ($readout)"
  1751. if defined $landevice{$readout};
  1752. }
  1753. elsif ($format eq "dialport") {
  1754. $readout = $dialPort{$readout} if $dialPort{$readout};
  1755. }
  1756. elsif ($format eq "gsmnetstate") {
  1757. $readout = $gsmNetworkState{$readout} if defined $gsmNetworkState{$readout};
  1758. }
  1759. elsif ($format eq "gsmact") {
  1760. $readout = $gsmTechnology{$readout} if defined $gsmTechnology{$readout};
  1761. }
  1762. elsif ($format eq "model") {
  1763. $readout = $fonModel{$readout} if defined $fonModel{$readout};
  1764. }
  1765. elsif ($format eq "mohtype") {
  1766. $readout = $mohtype{$readout} if defined $mohtype{$readout};
  1767. }
  1768. elsif ($format eq "nounderline") {
  1769. $readout =~ s/_/ /g;
  1770. }
  1771. elsif ($format eq "onoff") {
  1772. $readout =~ s/er//;
  1773. $readout =~ s/no-emu//;
  1774. $readout =~ s/0/off/;
  1775. $readout =~ s/1/on/;
  1776. }
  1777. elsif ($format eq "radio") {
  1778. if (defined $hash->{fhem}{radio}{$readout}) {
  1779. $readout = $hash->{fhem}{radio}{$readout};
  1780. }
  1781. else {
  1782. $readout .= " (unknown)";
  1783. }
  1784. }
  1785. elsif ($format eq "ringtone") {
  1786. $readout = $ringTone{$readout} if $ringTone{$readout};
  1787. }
  1788. elsif ($format eq "secondsintime") {
  1789. if ($readout < 243600) {
  1790. $readout = sprintf "%d:%02d", int $readout/3600, int( ($readout %3600) / 60);
  1791. }
  1792. else {
  1793. $readout = sprintf "%dd %d:%02d", int $readout/24/3600, int ($readout%24*3600)/3600, int( ($readout %3600) / 60);
  1794. }
  1795. }
  1796. elsif ($format eq "usertype") {
  1797. $readout = $userType{$readout};
  1798. }
  1799. return $readout;
  1800. }
  1801. #######################################################################
  1802. sub FRITZBOX_Readout_Add_Reading ($$$$@)
  1803. {
  1804. my ($hash, $roReadings, $rName, $rValue, $rFormat) = @_;
  1805. $rFormat = "" unless defined $rFormat;
  1806. $rValue = FRITZBOX_Readout_Format ($hash, $rFormat, $rValue);
  1807. push @{$roReadings}, $rName."|" . $rValue;
  1808. FRITZBOX_Log $hash, 5, "$rName: $rValue";
  1809. }
  1810. ##############################################################################################################################################
  1811. sub FRITZBOX_Set_Cmd_Start($)
  1812. {
  1813. my ($timerpara) = @_;
  1814. # my ( $name, $func ) = split( /\./, $timerpara );
  1815. my $index = rindex( $timerpara, "." ); # rechter punkt
  1816. my $func = substr $timerpara, $index + 1, length($timerpara); # function extrahieren
  1817. my $name = substr $timerpara, 0, $index; # name extrahieren
  1818. my $hash = $defs{$name};
  1819. my $cmdFunction;
  1820. my $timeout;
  1821. my $handover;
  1822. return unless int @cmdBuffer;
  1823. # kill old process if timeout + 10s is reached
  1824. if ( exists( $hash->{helper}{CMD_RUNNING_PID}) && time()> $cmdBufferTimeout + 10 ) {
  1825. FRITZBOX_Log $hash, 1, "Old command still running. Killing old command: ".$cmdBuffer[0];
  1826. shift @cmdBuffer;
  1827. BlockingKill( $hash->{helper}{CMD_RUNNING_PID} );
  1828. # stop FHEM, giving FritzBox some time to free the memory
  1829. sleep 5 unless $hash->{REMOTE}==1;
  1830. delete $hash->{helper}{CMD_RUNNING_PID};
  1831. return unless int @cmdBuffer;
  1832. }
  1833. # (re)start timer if command buffer is still filled
  1834. if (int @cmdBuffer >1) {
  1835. RemoveInternalTimer($hash->{helper}{TimerCmd});
  1836. InternalTimer(gettimeofday()+1, "FRITZBOX_Set_Cmd_Start", $hash->{helper}{TimerCmd}, 1);
  1837. }
  1838. # do not continue until running command has finished or is aborted
  1839. return if exists $hash->{helper}{CMD_RUNNING_PID};
  1840. my @val = split / /, $cmdBuffer[0];
  1841. my $forceShell = (AttrVal( $name, "forceTelnetConnection", 0 ) == 1 || $hash->{REMOTE} == 0);
  1842. # Preparing SET Call
  1843. if ($val[0] eq "call") {
  1844. shift @val;
  1845. $timeout = 60;
  1846. $timeout = $val[2] if defined $val[2] && $val[2] =~/^\d+$/;
  1847. $timeout += 30;
  1848. $cmdBufferTimeout = time() + $timeout;
  1849. $handover = $name . "|" . join( "|", @val );
  1850. $cmdFunction = "FRITZBOX_Call_Run_Web";
  1851. $cmdFunction = "FRITZBOX_Call_Run_Shell" if $forceShell;
  1852. }
  1853. # Preparing SET guestWLAN
  1854. elsif ($val[0] eq "guestwlan") {
  1855. shift @val;
  1856. $timeout = 20;
  1857. $cmdBufferTimeout = time() + $timeout;
  1858. $handover = $name . "|" . join( "|", @val );
  1859. $cmdFunction = "FRITZBOX_GuestWlan_Run_Web";
  1860. $cmdFunction = "FRITZBOX_GuestWlan_Run_Shell" if $forceShell;
  1861. }
  1862. # Preparing SET RING
  1863. elsif ($val[0] eq "ring") {
  1864. shift @val;
  1865. $timeout = 20;
  1866. if ($val[2]) {
  1867. $timeout = $val[2] if $val[2] =~/^\d+$/;
  1868. }
  1869. $timeout += 30;
  1870. $cmdBufferTimeout = time() + $timeout;
  1871. $handover = $name . "|" . join( "|", @val );
  1872. $cmdFunction = "FRITZBOX_Ring_Run_Web";
  1873. $cmdFunction = "FRITZBOX_Ring_Run_Shell" if $forceShell;
  1874. }
  1875. # Preparing SET WLAN
  1876. elsif ($val[0] eq "wlan") {
  1877. $timeout = 10;
  1878. $cmdBufferTimeout = time() + $timeout;
  1879. $handover = $name . "|" . join( "|", @val );
  1880. $cmdFunction = "FRITZBOX_Wlan_Run_Web";
  1881. $cmdFunction = "FRITZBOX_Wlan_Run_Shell" if $forceShell;
  1882. }
  1883. # Preparing SET WLAN2.4
  1884. elsif ( $val[0] =~ /^wlan(2\.4|5)$/ ) {
  1885. $timeout = 10;
  1886. $cmdBufferTimeout = time() + $timeout;
  1887. $handover = $name . "|" . join( "|", @val );
  1888. $cmdFunction = "FRITZBOX_Wlan_Run_Web";
  1889. }
  1890. # No valid set operation
  1891. else {
  1892. my $msg = "Unknown command '".join( " ", @val )."'";
  1893. FRITZBOX_Log $hash, 1, $msg;
  1894. return $msg;
  1895. }
  1896. # Starting new command
  1897. FRITZBOX_Log $hash, 4, "Fork process $cmdFunction";
  1898. $hash->{helper}{CMD_RUNNING_PID} = BlockingCall($cmdFunction, $handover,
  1899. "FRITZBOX_Set_Cmd_Done", $timeout,
  1900. "FRITZBOX_Set_Cmd_Aborted", $hash);
  1901. return undef;
  1902. } # end FRITZBOX_Set_Cmd_Start
  1903. #######################################################################
  1904. sub FRITZBOX_Set_Cmd_Done($)
  1905. {
  1906. my ($string) = @_;
  1907. unless (defined $string)
  1908. {
  1909. Log 1, "Fatal Error: no parameter handed over";
  1910. return;
  1911. }
  1912. my ($name, $success, $result) = split("\\|", $string,3);
  1913. my $hash = $defs{$name};
  1914. FRITZBOX_Log $hash, 4, "Back at main process";
  1915. shift (@cmdBuffer);
  1916. delete($hash->{helper}{CMD_RUNNING_PID});
  1917. if ( $success !~ /1|2/ )
  1918. {
  1919. FRITZBOX_Log $hash, 1, $result;
  1920. FRITZBOX_Readout_Process ( $hash, "Error|".$result );
  1921. }
  1922. elsif ( $success == 1 )
  1923. {
  1924. FRITZBOX_Log $hash, 4, $result;
  1925. }
  1926. elsif ($success == 2 )
  1927. {
  1928. $result = decode_base64($result);
  1929. FRITZBOX_Readout_Process ( $hash, $result );
  1930. }
  1931. }
  1932. #######################################################################
  1933. sub FRITZBOX_Set_Cmd_Aborted($)
  1934. {
  1935. my ($hash) = @_;
  1936. my $lastCmd = shift (@cmdBuffer);
  1937. delete($hash->{helper}{CMD_RUNNING_PID});
  1938. FRITZBOX_Log $hash, 1, "Timeout reached for: $lastCmd";
  1939. }
  1940. #######################################################################
  1941. sub FRITZBOX_Call_Run_Shell($)
  1942. {
  1943. my ($string) = @_;
  1944. my ($name, @val) = split "\\|", $string;
  1945. my $hash = $defs{$name};
  1946. return "$name|0|Error: At least one parameter must be defined."
  1947. unless int @val;
  1948. my $result;
  1949. my @cmdArray;
  1950. my $duration = 60;
  1951. my $extNo = $val[0];
  1952. my %field;
  1953. my $lastField;
  1954. my $ttsLink;
  1955. # Check if 1st parameter is a valid number
  1956. return $name."|0|Error: Parameter '$extNo' not a valid phone number"
  1957. unless $extNo =~ /^[\d\*\#+,]+$/;
  1958. $extNo =~ s/#$//;
  1959. # Check if 2nd parameter is the duration
  1960. shift @val;
  1961. if (int @val)
  1962. {
  1963. if ($val[0] =~ /^\d+$/ && int $val[0] > 0)
  1964. {
  1965. $duration = $val[0];
  1966. FRITZBOX_Log $hash, 5, "Extracted call duration of $duration s.";
  1967. shift @val;
  1968. }
  1969. }
  1970. # Extract text to say or play
  1971. foreach (@val)
  1972. {
  1973. if ($_ =~ /^(say|play):/i)
  1974. {
  1975. $lastField = $1;
  1976. $_ =~ s/^$1://;
  1977. }
  1978. $field{$lastField} .= $_." "
  1979. if $lastField;
  1980. }
  1981. # Create tts link to say as moh
  1982. if ( $field{say} )
  1983. {
  1984. unless ($hash->{READINGS}{box_moh})
  1985. {
  1986. FRITZBOX_Log $hash, 2, "Cannot do Text2Speech because box has no music on hold";
  1987. }
  1988. else
  1989. {
  1990. chop $field{say};
  1991. # http://translate.google.com/translate_tts?ie=UTF-8&tl=[SPRACHE]&q=[TEXT];
  1992. $ttsLink = $ttsLinkTemplate;
  1993. my $ttsText = substr $field{say},0,100;
  1994. my $ttsLang = "de";
  1995. if ($ttsText =~ /^\((en|es|fr|nl)\)/i )
  1996. {
  1997. $ttsLang = $1;
  1998. $ttsText =~ s/^\($1\)\s*//i;
  1999. }
  2000. $ttsLink =~ s/\[SPRACHE\]/$ttsLang/;
  2001. $ttsText = uri_escape($ttsText);
  2002. $ttsLink =~ s/\[TEXT\]/$ttsText/;
  2003. FRITZBOX_Log $hash, 5, "Created Text2Speech internet link: $ttsLink";
  2004. }
  2005. }
  2006. if ($field{play})
  2007. {
  2008. unless ($hash->{READINGS}{box_moh})
  2009. {
  2010. FRITZBOX_Log $hash, 2, "Cannot play mp3 because box has no music on hold";
  2011. }
  2012. elsif ($ttsLink)
  2013. {
  2014. FRITZBOX_Log $hash, 3, "Ignore 'play:' because Text2Speech already defined.";
  2015. }
  2016. else
  2017. {
  2018. chop $field{play};
  2019. $ttsLink = $field{play};
  2020. FRITZBOX_Log $hash, 5, "Extracted MP3 ring tone: $ttsLink";
  2021. }
  2022. }
  2023. $result = FRITZBOX_Telnet_OpenCon( $hash );
  2024. return "$name|0|$result"
  2025. if $result;
  2026. @cmdArray = ();
  2027. # Creation fhemRadioStation for ttsLink
  2028. if ($ttsLink) {
  2029. #Preparing 1st command array
  2030. push @cmdArray, '[ -f "'.$mohUpload.'" ] && rm "'.$mohUpload.'"';
  2031. push @cmdArray, '[ -f "'.$mohOld.'" ] && rm "'.$mohOld.'"';
  2032. push @cmdArray, '[ -f "'.$mohNew.'" ] && rm "'.$mohNew.'"';
  2033. push @cmdArray, 'wget -U Mozilla -O "'.$mohUpload.'" "'.$ttsLink.'"';
  2034. push @cmdArray, '[ -f "'.$mohUpload.'" ] && echo 1 || echo 0';
  2035. push @cmdArray, '[ -e /var/flash/fx_moh ] && echo 1 || echo 0';
  2036. # Execute 1st command array
  2037. $result = FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  2038. return "$name|0|Could not access '$ttsLink'"
  2039. unless $result->[4] eq "1";
  2040. return "$name|0|Could locate '/var/flash/fx_moh'"
  2041. unless $result->[5] eq "1";
  2042. #Prepare 2nd command array
  2043. push @cmdArray, 'if [ ! -f "/var/tmp/ffmpeg_mp3.tables" ]; then playerd_tables; fi';
  2044. push @cmdArray, 'ffmpegconv -i "'.$mohUpload.'" -o "'.$mohNew.'" --limit 32 --type 6';
  2045. push @cmdArray, '[ -f "'.$mohNew.'" ] && echo 1 || echo 0';
  2046. # Execute 2nd command array
  2047. $result = FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  2048. return "Could not convert '$ttsLink'"
  2049. unless $result->[2] eq "1";
  2050. #Execute 3rd command array
  2051. FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  2052. #Prepare 4th command array
  2053. push @cmdArray, 'cat /var/flash/fx_moh >"'.$mohOld.'"';
  2054. push @cmdArray, 'cat "'.$mohNew.'" >/var/flash/fx_moh';
  2055. push @cmdArray, 'killall -sigusr1 telefon';
  2056. push @cmdArray, 'rm "'.$mohUpload.'"';
  2057. push @cmdArray, 'rm "'.$mohNew.'"';
  2058. # Execute 4th command array
  2059. FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  2060. }
  2061. #Preparing 4th command array
  2062. # switch to (dial port 1-3) to avoid ringing of internal phone
  2063. my $ringWithIntern = AttrVal( $name, "ringWithIntern", 1 );
  2064. # push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort 60";
  2065. push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort $ringWithIntern"
  2066. if $ringWithIntern =~ /^([1-3])$/ ;
  2067. FRITZBOX_Log $hash, 4, "Call $extNo for $duration seconds";
  2068. push @cmdArray, "ctlmgr_ctl w telcfg command/Dial ".$extNo."#";
  2069. push @cmdArray, "sleep ".($duration+1); # 1s added because it takes sometime until it starts ringing
  2070. push @cmdArray, "ctlmgr_ctl w telcfg command/Hangup $ringWithIntern";
  2071. push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort 50";
  2072. if ($ttsLink)
  2073. {
  2074. push @cmdArray, 'cat "'.$mohOld.'" >/var/flash/fx_moh';
  2075. push @cmdArray, 'killall -sigusr1 telefon';
  2076. push @cmdArray, 'rm "'.$mohOld.'"';
  2077. }
  2078. # Execute command array
  2079. FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  2080. FRITZBOX_Telnet_CloseCon( $hash );
  2081. return $name."|1|Calling done";
  2082. } # End FRITZBOX_Call_Run_Shell
  2083. #######################################################################
  2084. sub FRITZBOX_Call_Run_Web($)
  2085. {
  2086. my ($string) = @_;
  2087. my ($name, @val) = split "\\|", $string;
  2088. my $hash = $defs{$name};
  2089. return "$name|0|Error: At least one parameter must be defined."
  2090. unless int @val;
  2091. my $result;
  2092. my @shellCmdArray;
  2093. my @webCmdArray;
  2094. my @tr064CmdArray;
  2095. my $duration = 60;
  2096. my $extNo = $val[0];
  2097. my %field;
  2098. my $lastField;
  2099. my $ttsLink;
  2100. # Check if 1st parameter is a valid number
  2101. return $name."|0|Error: Parameter '$extNo' not a valid phone number"
  2102. unless $extNo =~ /^[\d\*\#+,]+$/;
  2103. $extNo =~ s/#$//;
  2104. # Check if 2nd parameter is the duration
  2105. shift @val;
  2106. if (int @val) {
  2107. if ($val[0] =~ /^\d+$/ && int $val[0] > 0) {
  2108. $duration = $val[0];
  2109. FRITZBOX_Log $hash, 5, "Extracted call duration of $duration s.";
  2110. shift @val;
  2111. }
  2112. }
  2113. # Extract text to say or play
  2114. foreach (@val) {
  2115. if ($_ =~ /^(say|play):/i) {
  2116. $lastField = $1;
  2117. $_ =~ s/^$1://;
  2118. }
  2119. $field{$lastField} .= $_." " if $lastField;
  2120. }
  2121. # Create tts link to say as moh
  2122. if ( $field{say} ) {
  2123. unless ($hash->{READINGS}{box_moh}) {
  2124. FRITZBOX_Log $hash, 2, "Cannot do Text2Speech because box has no music on hold";
  2125. }
  2126. else {
  2127. chop $field{say};
  2128. # http://translate.google.com/translate_tts?ie=UTF-8&tl=[SPRACHE]&q=[TEXT];
  2129. $ttsLink = $ttsLinkTemplate;
  2130. my $ttsText = substr $field{say},0,100;
  2131. my $ttsLang = "de";
  2132. if ($ttsText =~ /^\((en|es|fr|nl)\)/i ) {
  2133. $ttsLang = $1;
  2134. $ttsText =~ s/^\($1\)\s*//i;
  2135. }
  2136. $ttsLink =~ s/\[SPRACHE\]/$ttsLang/;
  2137. $ttsText = uri_escape($ttsText);
  2138. $ttsLink =~ s/\[TEXT\]/$ttsText/;
  2139. FRITZBOX_Log $hash, 5, "Created Text2Speech internet link: $ttsLink";
  2140. }
  2141. }
  2142. if ($field{play}) {
  2143. unless ($hash->{READINGS}{box_moh}) {
  2144. FRITZBOX_Log $hash, 2, "Cannot play mp3 because box has no music on hold";
  2145. }
  2146. elsif ($ttsLink) {
  2147. FRITZBOX_Log $hash, 3, "Ignore 'play:' because Text2Speech already defined.";
  2148. }
  2149. else {
  2150. chop $field{play};
  2151. $ttsLink = $field{play};
  2152. FRITZBOX_Log $hash, 5, "Extracted MP3 ring tone: $ttsLink";
  2153. }
  2154. }
  2155. if ( $hash->{TELNET} == 1 && $ttsLink ) {
  2156. $result = FRITZBOX_Telnet_OpenCon( $hash );
  2157. return "$name|0|$result" if $result;
  2158. @shellCmdArray = ();
  2159. # Creation MOH for ttsLink
  2160. if ($ttsLink) {
  2161. #Preparing 1st command array
  2162. push @shellCmdArray, '[ -f "'.$mohUpload.'" ] && rm "'.$mohUpload.'"';
  2163. push @shellCmdArray, '[ -f "'.$mohOld.'" ] && rm "'.$mohOld.'"';
  2164. push @shellCmdArray, '[ -f "'.$mohNew.'" ] && rm "'.$mohNew.'"';
  2165. push @shellCmdArray, 'wget -U Mozilla -O "'.$mohUpload.'" "'.$ttsLink.'"';
  2166. push @shellCmdArray, '[ -f "'.$mohUpload.'" ] && echo 1 || echo 0';
  2167. push @shellCmdArray, '[ -e /var/flash/fx_moh ] && echo 1 || echo 0';
  2168. # Execute 1st command array
  2169. $result = FRITZBOX_Shell_Exec ( $hash, \@shellCmdArray );
  2170. return "$name|0|Could not access '$ttsLink'"
  2171. unless $result->[4] eq "1";
  2172. return "$name|0|Could locate '/var/flash/fx_moh'"
  2173. unless $result->[5] eq "1";
  2174. #Prepare 2nd command array
  2175. push @shellCmdArray, 'if [ ! -f "/var/tmp/ffmpeg_mp3.tables" ]; then playerd_tables; fi';
  2176. push @shellCmdArray, 'ffmpegconv -i "'.$mohUpload.'" -o "'.$mohNew.'" --limit 32 --type 6';
  2177. push @shellCmdArray, '[ -f "'.$mohNew.'" ] && echo 1 || echo 0';
  2178. # Execute 2nd command array
  2179. $result = FRITZBOX_Shell_Exec ( $hash, \@shellCmdArray );
  2180. return "Could not convert '$ttsLink'"
  2181. unless $result->[2] eq "1";
  2182. #Execute 3rd command array
  2183. FRITZBOX_Shell_Exec( $hash, \@shellCmdArray );
  2184. #Prepare 4th command array
  2185. push @shellCmdArray, 'cat /var/flash/fx_moh >"'.$mohOld.'"';
  2186. push @shellCmdArray, 'cat "'.$mohNew.'" >/var/flash/fx_moh';
  2187. push @shellCmdArray, 'killall -sigusr1 telefon';
  2188. push @shellCmdArray, 'rm "'.$mohUpload.'"';
  2189. push @shellCmdArray, 'rm "'.$mohNew.'"';
  2190. # Execute 4th command array
  2191. FRITZBOX_Shell_Exec ( $hash, \@shellCmdArray );
  2192. }
  2193. }
  2194. elsif ( $hash->{TELNET} != 1 && $ttsLink ) {
  2195. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. Parameter 'play:' and 'say:' ignored.";
  2196. }
  2197. # Preparing 4th command array to switch to (dial port 1-3) to avoid ringing of internal phone
  2198. my $ringWithIntern = AttrVal( $name, "ringWithIntern", 1 );
  2199. if ($ringWithIntern =~ /^([1-3])$/ && $hash->{WEBCM} == 1 ) {
  2200. push @webCmdArray, "telcfg:settings/DialPort" => $ringWithIntern;
  2201. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2202. }
  2203. #Preparing 5th command array to ring
  2204. FRITZBOX_Log $hash, 4, "Call $extNo for $duration seconds";
  2205. if ( $hash->{WEBCM} == 1 ) { # ring with webcm
  2206. push @webCmdArray, "telcfg:command/Dial" => $extNo."#";
  2207. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2208. }
  2209. elsif ($hash->{SECPORT}) { #or ring with TR-064
  2210. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialNumber", "NewX_AVM-DE_PhoneNumber", $extNo."#"];
  2211. $result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2212. }
  2213. else {
  2214. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. You cannot use call.";
  2215. }
  2216. sleep $duration; #+1; # 1s added because it takes sometime until it starts ringing
  2217. #Preparing 5th and 6th command array to stop ringing and reset dial port
  2218. if ( $hash->{WEBCM} == 1 ) { # hangup with webcm
  2219. push (@webCmdArray, "telcfg:command/Hangup" => "") unless $hash->{SECPORT};
  2220. push @webCmdArray, "telcfg:settings/DialPort" => 50;
  2221. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2222. }
  2223. elsif ($hash->{SECPORT}) { #or hangup with TR-064
  2224. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialHangup"];
  2225. $result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray ) if $hash->{SECPORT};
  2226. }
  2227. #Preparing 7th command array to reset everything
  2228. if ( $hash->{TELNET} == 1 && $ttsLink ) {
  2229. push @shellCmdArray, 'cat "'.$mohOld.'" >/var/flash/fx_moh';
  2230. push @shellCmdArray, 'killall -sigusr1 telefon';
  2231. push @shellCmdArray, 'rm "'.$mohOld.'"';
  2232. # Execute command array
  2233. FRITZBOX_Shell_Exec( $hash, \@shellCmdArray );
  2234. FRITZBOX_Telnet_CloseCon( $hash );
  2235. }
  2236. return $name."|1|Calling done";
  2237. } # End FRITZBOX_Call_Run_Web
  2238. #######################################################################
  2239. sub FRITZBOX_GuestWlan_Run_Shell($)
  2240. {
  2241. my ($string) = @_;
  2242. my ($name, @val) = split "\\|", $string;
  2243. my $hash = $defs{$name};
  2244. my $result;
  2245. my @readoutCmdArray;
  2246. my @roReadings;
  2247. my $startTime = time();
  2248. my $state = $val[0];
  2249. $state =~ s/on/1/;
  2250. $state =~ s/off/0/;
  2251. $result = FRITZBOX_Telnet_OpenCon( $hash );
  2252. return "$name|0|$result"
  2253. if $result;
  2254. my $returnStr;
  2255. $result = FRITZBOX_Shell_Exec $hash, "[ -n `ctlmgr_ctl r wlan settings/guest_pskvalue` ] && echo 1 || echo 0";
  2256. return "$name|0|Error: No password defined for guest WLAN."
  2257. unless $result;
  2258. # Set WLAN on if guestWLAN on
  2259. push @readoutCmdArray, [ "", "ctlmgr_ctl w wlan settings/wlan_enable 1"]
  2260. if $state == 1;
  2261. # Set guestWLAN
  2262. push @readoutCmdArray, [ "", "ctlmgr_ctl w wlan settings/guest_ap_enabled $state"];
  2263. # Read WLAN
  2264. push @readoutCmdArray, [ "box_wlan_2.4GHz", "ctlmgr_ctl r wlan settings/ap_enabled", "onoff" ];
  2265. # Read 2nd WLAN
  2266. push @readoutCmdArray, [ "box_wlan_5GHz", "ctlmgr_ctl r wlan settings/ap_enabled_scnd", "onoff" ];
  2267. # Read Gäste WLAN
  2268. push @readoutCmdArray, [ "box_guestWlan", "ctlmgr_ctl r wlan settings/guest_ap_enabled", "onoff" ];
  2269. push @readoutCmdArray, [ "box_guestWlanRemain", "ctlmgr_ctl r wlan settings/guest_time_remain", ];
  2270. # Execute commands
  2271. FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings);
  2272. FRITZBOX_Telnet_CloseCon ( $hash );
  2273. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  2274. $returnStr .= join('|', @roReadings );
  2275. FRITZBOX_Log $hash, 5, "Handover to main process: ".$returnStr;
  2276. return $name."|2|".encode_base64($returnStr,"");
  2277. } # end FRITZBOX_GuestWlan_Run_Shell
  2278. #######################################################################
  2279. sub FRITZBOX_GuestWlan_Run_Web($)
  2280. {
  2281. my ($string) = @_;
  2282. my ($name, @val) = split "\\|", $string;
  2283. my $hash = $defs{$name};
  2284. my $result;
  2285. my @webCmdArray;
  2286. my @tr064CmdArray;
  2287. my @roReadings;
  2288. my $startTime = time();
  2289. my $state = $val[0];
  2290. $state =~ s/on/1/;
  2291. $state =~ s/off/0/;
  2292. # $result = FRITZBOX_Shell_Exec $hash, "[ -n `ctlmgr_ctl r wlan settings/guest_pskvalue` ] && echo 1 || echo 0";
  2293. # return "$name|0|Error: No password defined for guest WLAN."
  2294. # unless $result;
  2295. # Set guestWLAN, if necessary set also WLAN
  2296. if ( $hash->{WEBCM}==1 ) { #webcm
  2297. push @webCmdArray, "wlan:settings/wlan_enable" => "1" if $state == 1;
  2298. # push @webCmdArray, "active" => "on";
  2299. # FRITZBOX_Web_CmdPost ($hash, \@webCmdArray, '/wlan/wlan_settings.lua');
  2300. push @webCmdArray, "wlan:settings/guest_ap_enabled" => $state;
  2301. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2302. }
  2303. elsif ( $hash->{SECPORT} ) { #TR-064
  2304. if ($state == 1) { # WLAN on when Guest WLAN on
  2305. push @tr064CmdArray, ["WLANConfiguration:2", "wlanconfig2", "SetEnable", "NewEnable", "1"]
  2306. if $hash->{fhem}->{is_double_wlan} == 1;
  2307. push @tr064CmdArray, ["WLANConfiguration:1", "wlanconfig1", "SetEnable", "NewEnable", "1"];
  2308. }
  2309. my $gWlanNo = 2;
  2310. $gWlanNo = 3
  2311. if $hash->{fhem}->{is_double_wlan} == 1;
  2312. push @tr064CmdArray, ["WLANConfiguration:".$gWlanNo, "wlanconfig".$gWlanNo, "SetEnable", "NewEnable", $state];
  2313. $result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2314. }
  2315. else { #no API
  2316. FRITZBOX_Log $hash, 2, "Error: No API available to switch WLAN.";
  2317. }
  2318. # push @webCmdArray, "autoupdate" => "on";
  2319. # push @webCmdArray, "activate_guest_access" => $val[0];
  2320. # FRITZBOX_Web_CmdPost ($hash, \@webCmdArray, '/wlan/guest_access.lua');
  2321. #POSTDATA=autoupdate=on&activate_guest_access=on&guest_ssid=Gast-WLAN&sec_mode=3&wpa_key=Baby%2412sitter&push_service=on&group_access=on&down_time_activ=on&down_time_value=240&disconnect_guest_access=on&apply=
  2322. # Read WLAN-Status
  2323. my $queryStr = "&box_wlan_24GHz=wlan:settings/ap_enabled"; # WLAN
  2324. $queryStr .= "&box_wlan_5GHz=wlan:settings/ap_enabled_scnd"; # 2nd WLAN
  2325. $queryStr .= "&box_guestWlan=wlan:settings/guest_ap_enabled"; # Gäste WLAN
  2326. $queryStr .= "&box_guestWlanRemain=wlan:settings/guest_time_remain";
  2327. $result = FRITZBOX_Web_Query( $hash, $queryStr) ;
  2328. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_2.4GHz", $result->{box_wlan_24GHz}, "onoff";
  2329. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_5GHz", $result->{box_wlan_5GHz}, "onoff";
  2330. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlan", $result->{box_guestWlan}, "onoff";
  2331. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlanRemain", $result->{box_guestWlanRemain};
  2332. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sid", $result->{sid};
  2333. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sidTime", time();
  2334. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  2335. my $returnStr = join('|', @roReadings );
  2336. FRITZBOX_Log $hash, 5, "Handover to main process: ".$returnStr;
  2337. return $name."|2|".encode_base64($returnStr,"");
  2338. } # end FRITZBOX_GuestWlan_Run_Web
  2339. #######################################################################
  2340. sub FRITZBOX_Wlan_Run_Shell($)
  2341. {
  2342. my ($string) = @_;
  2343. my ($name, $cmd, @val) = split "\\|", $string;
  2344. my $hash = $defs{$name};
  2345. my $result;
  2346. my @readoutCmdArray;
  2347. my @roReadings;
  2348. my $startTime = time();
  2349. my $state = $val[0];
  2350. $state =~ s/on/1/;
  2351. $state =~ s/off/0/;
  2352. $result = FRITZBOX_Telnet_OpenCon( $hash );
  2353. return "$name|0|$result"
  2354. if $result;
  2355. my $returnStr;
  2356. # Set WLAN
  2357. push @readoutCmdArray, [ "", "ctlmgr_ctl w wlan settings/wlan_enable $state"];
  2358. # Read WLAN
  2359. push @readoutCmdArray, [ "box_wlan_2.4GHz", "ctlmgr_ctl r wlan settings/ap_enabled", "onoff" ];
  2360. # Read 2nd WLAN
  2361. push @readoutCmdArray, [ "box_wlan_5GHz", "ctlmgr_ctl r wlan settings/ap_enabled_scnd", "onoff" ];
  2362. # Read Gäste WLAN
  2363. push @readoutCmdArray, [ "box_guestWlan", "ctlmgr_ctl r wlan settings/guest_ap_enabled", "onoff" ];
  2364. push @readoutCmdArray, [ "box_guestWlanRemain", "ctlmgr_ctl r wlan settings/guest_time_remain", ];
  2365. # Execute commands
  2366. FRITZBOX_Shell_Query( $hash, \@readoutCmdArray, \@roReadings);
  2367. FRITZBOX_Telnet_CloseCon ( $hash );
  2368. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  2369. $returnStr .= join('|', @roReadings );
  2370. FRITZBOX_Log $hash, 5, "Handover to main process: ".$returnStr;
  2371. return $name."|2|".encode_base64($returnStr,"");
  2372. } # end FRITZBOX_Wlan_Run_Shell
  2373. #######################################################################
  2374. sub FRITZBOX_Wlan_Run_Web($)
  2375. {
  2376. my ($string) = @_;
  2377. my ($name, $cmd, @val) = split "\\|", $string;
  2378. my $hash = $defs{$name};
  2379. my $result;
  2380. my @webCmdArray;
  2381. my @tr064CmdArray;
  2382. my @roReadings;
  2383. my $startTime = time();
  2384. my $state = $val[0];
  2385. $state =~ s/on/1/;
  2386. $state =~ s/off/0/;
  2387. # Set WLAN
  2388. if ($hash->{WEBCM}) { #webcm
  2389. push @webCmdArray, "wlan:settings/wlan_enable" => $state if $cmd eq "wlan";
  2390. push @webCmdArray, "wlan:settings/ap_enabled" => $state if $cmd eq "wlan2.4";
  2391. push @webCmdArray, "wlan:settings/ap_enabled_scnd" => $state if $cmd eq "wlan5";
  2392. FRITZBOX_Web_CmdPost ($hash, \@webCmdArray);
  2393. # push @webCmdArray, "active" => "on" if $val[0] eq "on";
  2394. # FRITZBOX_Web_CmdPost ($hash, \@webCmdArray, '/wlan/wlan_settings.lua');
  2395. }
  2396. elsif ($hash->{SECPORT}) { #TR-064
  2397. push @tr064CmdArray, ["WLANConfiguration:2", "wlanconfig2", "SetEnable", "NewEnable", $state]
  2398. if $hash->{fhem}->{is_double_wlan} == 1 && $cmd ne "wlan2.4";
  2399. push @tr064CmdArray, ["WLANConfiguration:1", "wlanconfig1", "SetEnable", "NewEnable", $state]
  2400. if $cmd =~ /^(wlan|wlan2\.4)$/;
  2401. $result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2402. }
  2403. else { #no API
  2404. FRITZBOX_Log $hash, 2, "Error: No API available to switch WLAN.";
  2405. }
  2406. # Read WLAN-Status
  2407. my $queryStr = "&box_wlan_24GHz=wlan:settings/ap_enabled"; # WLAN
  2408. $queryStr .= "&box_wlan_5GHz=wlan:settings/ap_enabled_scnd"; # 2nd WLAN
  2409. $queryStr .= "&box_guestWlan=wlan:settings/guest_ap_enabled"; # Gäste WLAN
  2410. $queryStr .= "&box_guestWlanRemain=wlan:settings/guest_time_remain";
  2411. $result = FRITZBOX_Web_Query( $hash, $queryStr) ;
  2412. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_2.4GHz", $result->{box_wlan_24GHz}, "onoff";
  2413. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_wlan_5GHz", $result->{box_wlan_5GHz}, "onoff";
  2414. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlan", $result->{box_guestWlan}, "onoff";
  2415. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "box_guestWlanRemain", $result->{box_guestWlanRemain};
  2416. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sid", $result->{sid};
  2417. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sidTime", time();
  2418. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  2419. my $returnStr = join('|', @roReadings );
  2420. FRITZBOX_Log $hash, 5, "Handover to main process: ".$returnStr;
  2421. return $name."|2|".encode_base64($returnStr,"");
  2422. } # end FRITZBOX_Wlan_Run_Web
  2423. #######################################################################
  2424. sub FRITZBOX_Ring_Run_Shell($)
  2425. {
  2426. my ($string) = @_;
  2427. my ($name, @val) = split "\\|", $string;
  2428. my $hash = $defs{$name};
  2429. return "$name|0|Error: At least one parameter must be defined."
  2430. unless int @val;
  2431. my $result;
  2432. my $curCallerName;
  2433. my @cmdArray;
  2434. my $duration = 5;
  2435. my $intNo = $val[0];
  2436. my @FritzFons;
  2437. my $ringTone;
  2438. my %field;
  2439. my $lastField;
  2440. my $ttsLink;
  2441. my $fhemRadioStation;
  2442. # Check if 1st parameter are comma separated numbers
  2443. return $name."|0|Error: Parameter '$intNo' not a number (only commas (,) are allowed to separate numbers)"
  2444. unless $intNo =~ /^[\d,]+$/;
  2445. $intNo =~ s/#$//;
  2446. # Create a hash for the DECT devices whose ring tone (or radio station) can be changed
  2447. foreach ( split( /,/, $intNo ) ) {
  2448. if (defined $hash->{fhem}{$_}{brand} && "AVM" eq $hash->{fhem}{$_}{brand}) {
  2449. FRITZBOX_Log $hash, 5, "Internal number $_ seems to be a Fritz!Fon.";
  2450. push @FritzFons, $_ - 609;
  2451. }
  2452. }
  2453. # Check if 2nd parameter is the duration
  2454. shift @val;
  2455. if (int @val)
  2456. {
  2457. if ($val[0] =~ /^\d+$/ && int $val[0] > 0)
  2458. {
  2459. $duration = $val[0];
  2460. FRITZBOX_Log $hash, 5, "Extracted ring duration of $duration s.";
  2461. shift @val;
  2462. }
  2463. }
  2464. # Check if next parameter is a valid ring tone
  2465. if (int @val)
  2466. {
  2467. if ($val[0] !~ /^(msg|show|say|play):/i)
  2468. {
  2469. $ringTone = $val[0];
  2470. $ringTone = $ringToneNumber{lc $val[0]};
  2471. return $name."|0|Error: Ring tone '".$val[0]."' not valid"
  2472. unless defined $ringTone;
  2473. FRITZBOX_Log $hash, 5, "Ring tone $ringTone will be used.";
  2474. shift @val;
  2475. }
  2476. }
  2477. # Extract text to say, play or show
  2478. foreach (@val)
  2479. {
  2480. if ($_ =~ /^(show|msg|say|play):/i)
  2481. {
  2482. $lastField = $1;
  2483. $_ =~ s/^$1://;
  2484. }
  2485. $field{$lastField} .= $_." "
  2486. if $lastField;
  2487. }
  2488. my $msg = AttrVal( $name, "defaultCallerName", "FHEM" );
  2489. if ( $field{show} ) {
  2490. chop $field{show};
  2491. $msg = $field{show};
  2492. } elsif ( $field{msg} ) {
  2493. chop $field{msg};
  2494. $msg = $field{msg};
  2495. }
  2496. $msg = substr($msg, 0, 30);
  2497. # Determine number of Internet Radio to play mp3 or say tts
  2498. if ( $field{say} || $field{play} ) {
  2499. foreach (keys %{$hash->{fhem}{radio}})
  2500. {
  2501. if ($hash->{fhem}{radio}{$_} eq "FHEM")
  2502. {
  2503. $fhemRadioStation = $_;
  2504. last;
  2505. }
  2506. }
  2507. if ( not defined $fhemRadioStation && $hash->{fhem}{radioCount} )
  2508. {
  2509. $fhemRadioStation = $hash->{fhem}{radioCount}-1;
  2510. }
  2511. }
  2512. # Create tts link to play as internet radio
  2513. if ( $field{say} )
  2514. {
  2515. if ($fhemRadioStation)
  2516. {
  2517. $ringTone = 33;
  2518. chop $field{say};
  2519. # http://translate.google.com/translate_tts?ie=UTF-8&tl=[SPRACHE]&q=[TEXT];
  2520. $ttsLink = $ttsLinkTemplate;
  2521. my $ttsText = substr $field{say},0,100;
  2522. my $ttsLang = "de";
  2523. if ($ttsText =~ /^\((en|es|fr|nl)\)/i )
  2524. {
  2525. $ttsLang = $1;
  2526. $ttsText =~ s/^\($1\)\s*//i;
  2527. }
  2528. $ttsLink =~ s/\[SPRACHE\]/$ttsLang/;
  2529. $ttsText = uri_escape($ttsText);
  2530. $ttsLink =~ s/\[TEXT\]/$ttsText/;
  2531. FRITZBOX_Log $hash, 5, "Created Text2Speech internet link: $ttsLink";
  2532. }
  2533. else
  2534. {
  2535. FRITZBOX_Log $hash, 2, "Cannot do Text2Speech because box has no internet radio";
  2536. }
  2537. }
  2538. if ($field{play})
  2539. {
  2540. unless ($fhemRadioStation)
  2541. {
  2542. FRITZBOX_Log $hash, 2, "Cannot play mp3 because box has no internet radio";
  2543. }
  2544. elsif ($ttsLink)
  2545. {
  2546. FRITZBOX_Log $hash, 3, "Ignore 'play:' because Text2Speech already defined.";
  2547. }
  2548. else
  2549. {
  2550. $ringTone = 33;
  2551. chop $field{play};
  2552. $ttsLink = $field{play};
  2553. FRITZBOX_Log $hash, 5, "Extracted MP3 ring tone: $ttsLink";
  2554. }
  2555. }
  2556. $result = FRITZBOX_Telnet_OpenCon( $hash );
  2557. return "$name|0|$result"
  2558. if $result;
  2559. #Preparing 1st command array
  2560. @cmdArray = ();
  2561. # Creation fhemRadioStation for ttsLink
  2562. if (int (@FritzFons) == 0 && $ttsLink)
  2563. {
  2564. FRITZBOX_Log $hash, 3, "No Fritz!Fon identified, parameter 'say:' will be ignored."
  2565. }
  2566. elsif (int (@FritzFons) && $ttsLink && $hash->{fhem}{radio}{$fhemRadioStation} ne "FHEM")
  2567. {
  2568. FRITZBOX_Log $hash, 3, "Create new internet radio station $fhemRadioStation: 'FHEM' for ringing with text-to-speech";
  2569. push @cmdArray, "ctlmgr_ctl w configd settings/WEBRADIO".$fhemRadioStation."/Name FHEM";
  2570. push @cmdArray, "ctlmgr_ctl w configd settings/WEBRADIO".$fhemRadioStation."/Bitmap 1023";
  2571. #Execute command array
  2572. FRITZBOX_Shell_Exec( $hash, \@cmdArray )
  2573. }
  2574. #Preparing 2nd command array
  2575. # Change ring tone of Fritz!Fons
  2576. if ($ringTone)
  2577. {
  2578. FRITZBOX_Log $hash, 3, "No Fritz!Fon identified, ring tone will be ignored."
  2579. unless @FritzFons;
  2580. foreach (@FritzFons)
  2581. {
  2582. push @cmdArray, "ctlmgr_ctl r telcfg settings/Foncontrol/User$_/IntRingTone";
  2583. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User$_/IntRingTone $ringTone";
  2584. FRITZBOX_Log $hash, 4, "Change temporarily internal ring tone of Fritz!Fon DECT $_ to $ringTone";
  2585. if ($ttsLink)
  2586. {
  2587. push @cmdArray, "ctlmgr_ctl r telcfg settings/Foncontrol/User$_/RadioRingID";
  2588. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User$_/RadioRingID ".$fhemRadioStation;
  2589. FRITZBOX_Log $hash, 4, "Change temporarily radio station of Fritz!Fon DECT $_ to $fhemRadioStation (FHEM)";
  2590. }
  2591. }
  2592. }
  2593. # uses name of port 0-3 (dial port 1-4) to show messages on ringing phone
  2594. my $ringWithIntern = AttrVal( $name, "ringWithIntern", 0 );
  2595. if ( $ringWithIntern =~ /^([1-3])$/ )
  2596. {
  2597. push @cmdArray, "ctlmgr_ctl r telcfg settings/MSN/Port".($ringWithIntern-1)."/Name";
  2598. push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '$msg'";
  2599. FRITZBOX_Log $hash, 4, "Change temporarily name of calling number $ringWithIntern to '$msg'";
  2600. push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort $ringWithIntern"
  2601. }
  2602. elsif ($field{show})
  2603. {
  2604. FRITZBOX_Log $hash, 3, "Parameter 'show:' ignored because attribute 'ringWithIntern' not defined."
  2605. }
  2606. # Set tts-Message
  2607. push @cmdArray, 'ctlmgr_ctl w configd settings/WEBRADIO'.$fhemRadioStation.'/URL "'.$ttsLink.'"'
  2608. if $ttsLink;
  2609. #Execute command array
  2610. $result = FRITZBOX_Shell_Exec( $hash, \@cmdArray )
  2611. if int( @cmdArray ) > 0;
  2612. $intNo =~ s/,/#/g;
  2613. #Preparing 3rd command array to ring and reset everything
  2614. FRITZBOX_Log $hash, 4, "Ringing $intNo for $duration seconds";
  2615. push @cmdArray, "ctlmgr_ctl w telcfg command/Dial **".$intNo."#";
  2616. push @cmdArray, "sleep ".($duration+1); # 1s added because it takes sometime until it starts ringing
  2617. push @cmdArray, "ctlmgr_ctl w telcfg command/Hangup **".$intNo;
  2618. push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort 50"
  2619. if $ringWithIntern != 0 ;
  2620. # Reset internal ring tones for the Fritz!Fons
  2621. if ($ringTone)
  2622. {
  2623. for (0 .. $#FritzFons)
  2624. {
  2625. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$FritzFons[$_]."/IntRingTone ".$result->[2*$_];
  2626. # Reset internet station for the Fritz!Fons
  2627. if ($ttsLink)
  2628. {
  2629. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$FritzFons[$_]."/RadioRingID ".$result->[2*(int(@FritzFons)+$_)];
  2630. }
  2631. }
  2632. }
  2633. # Reset name of calling number
  2634. if ($ringWithIntern =~ /^([1-2])$/)
  2635. {
  2636. if ($ttsLink) {
  2637. push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '".$result->[4*int(@FritzFons)]."'";
  2638. push @cmdArray, "ctlmgr_ctl w telcfg command/Dial **".$intNo;
  2639. push @cmdArray, "ctlmgr_ctl w telcfg command/Hangup **".$intNo;
  2640. } elsif ($ringTone) {
  2641. push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '".$result->[2*int(@FritzFons)]."'";
  2642. } else {
  2643. push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '".$result->[0]."'";
  2644. }
  2645. }
  2646. # Execute command array
  2647. FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  2648. FRITZBOX_Telnet_CloseCon( $hash );
  2649. return $name."|1|Ringing done";
  2650. } # End FRITZBOX_Ring_Run_Shell
  2651. #######################################################################
  2652. sub FRITZBOX_Ring_Run_Web($)
  2653. {
  2654. my ($string) = @_;
  2655. my ($name, @val) = split "\\|", $string;
  2656. my $hash = $defs{$name};
  2657. return "$name|0|Error: At least one parameter must be defined."
  2658. unless int @val;
  2659. my $result;
  2660. my @tr064Result;
  2661. my $curCallerName;
  2662. my @webCmdArray;
  2663. my @getCmdArray;
  2664. my @tr064CmdArray;
  2665. my @roReadings;
  2666. my $duration = -1;
  2667. my $intNo = $val[0];
  2668. my @FritzFons;
  2669. my $ringTone;
  2670. my %field;
  2671. my $lastField;
  2672. my $ttsLink;
  2673. my $fhemRadioStation;
  2674. my $startValue;
  2675. my $startTime = time();
  2676. my $useGuiHack = AttrVal( $name, "useGuiHack", 0 );
  2677. # Check if 1st parameter are comma separated numbers
  2678. return $name."|0|Error (set ring): Parameter '$intNo' not a number (only commas (,) are allowed to separate phone numbers)"
  2679. unless $intNo =~ /^[\d,]+$/;
  2680. $intNo =~ s/#$//;
  2681. # Create a hash for the DECT devices whose ring tone (or radio station) can be changed
  2682. foreach ( split( /,/, $intNo ) ) {
  2683. if (defined $hash->{fhem}{$_}{brand} && "AVM" eq $hash->{fhem}{$_}{brand}) {
  2684. my $userId = $hash->{fhem}{$_}{userId};
  2685. FRITZBOX_Log $hash, 5, "Internal number $_ (dect$userId) seems to be a Fritz!Fon.";
  2686. push @FritzFons, $hash->{fhem}{$_}{userId};
  2687. }
  2688. }
  2689. # Check if 2nd parameter is the duration
  2690. shift @val;
  2691. if (int @val) {
  2692. if ($val[0] =~ /^\d+$/ && int $val[0] >= 0) {
  2693. $duration = $val[0];
  2694. FRITZBOX_Log $hash, 5, "Extracted ring duration of $duration s.";
  2695. shift @val;
  2696. }
  2697. }
  2698. # Check if next parameter is a valid ring tone
  2699. if (int @val) {
  2700. if ($val[0] !~ /^(msg|show|say|play):/i) {
  2701. $ringTone = $val[0];
  2702. $ringTone = $ringToneNumber{lc $val[0]};
  2703. return $name."|0|Error (set ring): Ring tone '".$val[0]."' not valid"
  2704. unless defined $ringTone;
  2705. FRITZBOX_Log $hash, 5, "Ring tone $ringTone will be used.";
  2706. shift @val;
  2707. }
  2708. }
  2709. # Extract text to say, play or show
  2710. foreach (@val) {
  2711. if ($_ =~ /^(show|msg|say|play):/i) {
  2712. $lastField = $1;
  2713. $_ =~ s/^$1://;
  2714. }
  2715. $field{$lastField} .= $_." " if $lastField;
  2716. }
  2717. # build message to show
  2718. my $msg = AttrVal( $name, "defaultCallerName", "FHEM" );
  2719. if ( $field{show} ) {
  2720. chop $field{show};
  2721. $msg = $field{show};
  2722. }
  2723. elsif ( $field{msg} ) {
  2724. chop $field{msg};
  2725. $msg = $field{msg};
  2726. }
  2727. $msg = substr($msg, 0, 30);
  2728. # no webcm no Message
  2729. unless ( $hash->{WEBCM}==1 ) {
  2730. $msg = "";
  2731. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. Parameter 'show:' ignored."
  2732. if $field{msg} || $field{show};
  2733. }
  2734. # Determine number of Internet Radio to play mp3 or say tts
  2735. if ( $field{say} || $field{play} ) {
  2736. foreach (keys %{$hash->{fhem}{radio}}) {
  2737. if ($hash->{fhem}{radio}{$_} eq "FHEM") {
  2738. $fhemRadioStation = $_;
  2739. last;
  2740. }
  2741. }
  2742. # FHEM Radiostation needs to be created at last radio position
  2743. $fhemRadioStation = $hash->{fhem}{radioCount}-1
  2744. if not defined $fhemRadioStation && $hash->{fhem}{radioCount};
  2745. }
  2746. # Create tts link to play as internet radio
  2747. if ( $field{say} ) {
  2748. if ($fhemRadioStation) {
  2749. $ringTone = 33;
  2750. chop $field{say};
  2751. # my $ttsRessource = AttrVal( $name, "ttsRessource", "Google" );
  2752. # Speak with espeak # sudo apt-get install espeak
  2753. # if ($ttsRessource eq "ESpeak"){
  2754. # $cmd = "sudo espeak -vde+f3 -k5 -s150 \"" . $ttsText . "\"";
  2755. # Log3 $hash, 4, "Text2Speech:" .$cmd;
  2756. # system($cmd);
  2757. # }
  2758. # speak with Translate.Google
  2759. # http://translate.google.com/translate_tts?ie=UTF-8&tl=[SPRACHE]&q=[TEXT];
  2760. $ttsLink = $ttsLinkTemplate;
  2761. my $ttsText = substr $field{say},0,100;
  2762. my $ttsLang = "de";
  2763. if ($ttsText =~ /^\((en|es|fr|nl)\)/i ) {
  2764. $ttsLang = $1;
  2765. $ttsText =~ s/^\($1\)\s*//i;
  2766. }
  2767. $ttsLink =~ s/\[SPRACHE\]/$ttsLang/;
  2768. $ttsText = uri_escape($ttsText);
  2769. $ttsLink =~ s/\[TEXT\]/$ttsText/;
  2770. FRITZBOX_Log $hash, 5, "Created Text2Speech internet link: $ttsLink";
  2771. }
  2772. else {
  2773. FRITZBOX_Log $hash, 2, "Cannot do Text2Speech because box has no internet radio";
  2774. }
  2775. }
  2776. # Extract play link
  2777. if ( $field{play} ) {
  2778. unless ($fhemRadioStation)
  2779. {
  2780. FRITZBOX_Log $hash, 3, "Cannot play mp3 because box has no internet radio";
  2781. }
  2782. elsif ($ttsLink)
  2783. {
  2784. FRITZBOX_Log $hash, 3, "Ignore 'play:' because Text2Speech already defined.";
  2785. }
  2786. else
  2787. {
  2788. $ringTone = 33;
  2789. chop $field{play};
  2790. $ttsLink = $field{play};
  2791. FRITZBOX_Log $hash, 5, "Extracted MP3 ring tone: $ttsLink";
  2792. }
  2793. }
  2794. # Store current values for fon and dect port
  2795. my $queryStr = "&dectUser=telcfg:settings/Foncontrol/User/list(Id,Intern,IntRingTone,RadioRingID)"; # DECT Numbers
  2796. $queryStr .= "&fonPort=telcfg:settings/MSN/Port/list(Name,MSN)"; # Fon ports
  2797. $queryStr .= "&dialPort=telcfg:settings/DialPort"; #Dial Port
  2798. $queryStr .= "&useClickToDial=telcfg:settings/UseClickToDial"; # Use Click2Dial
  2799. FRITZBOX_Log $hash, 4, "Read current dect and fon port values from box";
  2800. $startValue = FRITZBOX_Web_Query( $hash, $queryStr, 'UTF-8') ;
  2801. #Preparing 1st command array
  2802. @webCmdArray = ();
  2803. # Check ClickToDial
  2804. unless ($startValue->{useClickToDial}) {
  2805. if ($hash->{WEBCM}) { # mit webcm
  2806. push @webCmdArray, "telcfg:settings/UseClickToDial" => 1;
  2807. push @webCmdArray, "telcfg:settings/DialPort" => 50;
  2808. $startValue->{dialPort}=50;
  2809. FRITZBOX_Log $hash, 3, "Switch ClickToDial on, set dial port 50";
  2810. }
  2811. elsif ($hash->{SECPORT}) { # oder mit TR064
  2812. # get port name
  2813. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_GetPhonePort", "NewIndex", "1"];
  2814. @tr064Result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2815. return $name."|0|Error (set ring): ".$tr064Result[0]->{Error} if $tr064Result[0]->{Error};
  2816. my $portName = $tr064Result[0]->{'X_AVM-DE_GetPhonePortResponse'}->{'NewX_AVM-DE_PhoneName'};
  2817. # set click to dial
  2818. if ($portName) {
  2819. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialSetConfig", "NewX_AVM-DE_PhoneName", $portName];
  2820. @tr064Result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2821. FRITZBOX_Log $hash, 3, "Switch ClickToDial on, set dial port '$portName'";
  2822. }
  2823. }
  2824. else { #oder Pech gehabt
  2825. my $msg = "Error (set ring): Cannot ring because ClickToDial (Waehlhilfe) is off.";
  2826. FRITZBOX_Log $hash, 2, $msg;
  2827. return $name."|0|".$msg
  2828. }
  2829. }
  2830. if (int (@FritzFons) == 0 && $ttsLink) {
  2831. FRITZBOX_Log $hash, 3, "No Fritz!Fon identified, parameter 'say:' will be ignored.";
  2832. }
  2833. # Creation fhemRadioStation for ttsLink
  2834. elsif (int (@FritzFons) && $ttsLink && $hash->{fhem}{radio}{$fhemRadioStation} ne "FHEM") {
  2835. push @webCmdArray, "configd:settings/WEBRADIO".$fhemRadioStation."/Name" => "FHEM";
  2836. push @webCmdArray, "configd:settings/WEBRADIO".$fhemRadioStation."/Bitmap" => "1023";
  2837. if (int @webCmdArray) {
  2838. FRITZBOX_Log $hash, 3, "Create new internet radio station $fhemRadioStation: 'FHEM' for ringing with text-to-speech"
  2839. }
  2840. else {
  2841. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. Cannot create radio station 'FHEM' for ringing with text-to-speech."
  2842. }
  2843. }
  2844. #Execute command array
  2845. FRITZBOX_Web_CmdPost( $hash, \@webCmdArray ) if int @webCmdArray;
  2846. #Preparing 2nd command array to set ring parameters
  2847. # Change ring tone of Fritz!Fons
  2848. if ( $ringTone && $hash->{WEBCM}==0 && $useGuiHack == 0 ) {
  2849. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. Ring tone cannot be changed."
  2850. }
  2851. elsif ($ringTone && @FritzFons == 0) {
  2852. FRITZBOX_Log $hash, 3, "No Fritz!Fon identified, ring tone will be ignored.";
  2853. }
  2854. elsif ($ringTone) {
  2855. foreach (@FritzFons) {
  2856. push @webCmdArray, "telcfg:settings/Foncontrol/User".$_."/IntRingTone" => $ringTone
  2857. unless $useGuiHack;
  2858. my $getCmdStr = "&start_ringtest=1&idx=".$_."&ringtone=".$ringTone;
  2859. FRITZBOX_Log $hash, 4, "Change temporarily internal ring tone of dect".$_." to $ringTone";
  2860. if ($ttsLink) {
  2861. push @webCmdArray, "telcfg:settings/Foncontrol/User".$_."/RadioRingID" => $fhemRadioStation
  2862. unless $useGuiHack;
  2863. $getCmdStr .= "&ring_tone_radio_test=".$fhemRadioStation;
  2864. FRITZBOX_Log $hash, 4, "Change temporarily radio station of dect".$_." to $fhemRadioStation (FHEM)";
  2865. }
  2866. push @getCmdArray, [ "fon_devices/edit_dect_ring_tone.lua" => $getCmdStr]
  2867. if $useGuiHack;
  2868. }
  2869. }
  2870. # Change dial port and its name (dial port 1-3) to show messages on ringing phones
  2871. my $ringWithIntern = AttrVal( $name, "ringWithIntern", 0 );
  2872. if ( $ringWithIntern =~ /^([1-3])$/ && $msg) {
  2873. if ($startValue->{fonPort}->[$ringWithIntern-1]->{Name}) {
  2874. push @webCmdArray, "telcfg:settings/MSN/Port".($ringWithIntern-1)."/Name" => $msg;
  2875. FRITZBOX_Log $hash, 4, "Change temporarily name of dial port 'fon$ringWithIntern' to '$msg'";
  2876. }
  2877. else {
  2878. FRITZBOX_Log $hash, 2, "Error: Current name of dial port 'fon$ringWithIntern' could not be determined -> Did not change the name.";
  2879. my $temp = Dumper( $startValue );
  2880. FRITZBOX_Log $hash, 3, "Debug info: \n".$temp;
  2881. }
  2882. push @webCmdArray, "telcfg:settings/DialPort" => $ringWithIntern;
  2883. FRITZBOX_Log $hash, 4, "Set dial port to '" . $dialPort{$ringWithIntern} . "' (MSN: ".$startValue->{fonPort}->[$ringWithIntern-1]{MSN} .").";
  2884. }
  2885. # set dial port to 50 (all Fons)
  2886. elsif ($msg) {
  2887. FRITZBOX_Log $hash, 3, "Parameter 'show:' ignored because attribute 'ringWithIntern' not defined."
  2888. if $field{show};
  2889. push @webCmdArray, "telcfg:settings/DialPort" => 50;
  2890. FRITZBOX_Log $hash, 4, "Set dial port to 50 (all fons)";
  2891. }
  2892. # Set tts-Message
  2893. if ($ttsLink) {
  2894. # Create m3u-file (if ring tone and radio station cannot be changed because of missing interfaces)
  2895. if ( $hash->{M3U_LOCAL} ne "undefined" ) {
  2896. if (open my $fh, '>', $hash->{M3U_LOCAL}) {
  2897. print $fh $ttsLink."\n";
  2898. close $fh;
  2899. FRITZBOX_Log $hash, 4, "Filled m3u file '".$hash->{M3U_LOCAL}."' with '$ttsLink'.";
  2900. $ttsLink = $hash->{M3U_URL} if $hash->{M3U_URL} ne "undefined";
  2901. }
  2902. else {
  2903. my $msg = "Error: Cannot create file '".$hash->{M3U_LOCAL}."' because: ".$!."\n";
  2904. FRITZBOX_Log $hash, 4, $msg;
  2905. }
  2906. }
  2907. push @webCmdArray, 'configd:settings/WEBRADIO'.$fhemRadioStation.'/URL' => $ttsLink;
  2908. }
  2909. #Execute command array
  2910. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray )
  2911. if $hash->{WEBCM}==1 && int( @webCmdArray ) > 0;
  2912. $result = FRITZBOX_Web_CmdGet( $hash, \@getCmdArray )
  2913. if int( @getCmdArray ) > 0;
  2914. $intNo =~ s/,/#/g;
  2915. #Preparing 3rd command array to ring
  2916. FRITZBOX_Log $hash, 4, "Ringing $intNo for $duration seconds";
  2917. if ( $hash->{WEBCM}==1 ) {
  2918. push @webCmdArray, "telcfg:command/Dial" => "**".$intNo."#";
  2919. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2920. }
  2921. elsif ($hash->{SECPORT}) {
  2922. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialNumber", "NewX_AVM-DE_PhoneNumber", "**".$intNo."#"];
  2923. @tr064Result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  2924. return $name."|0|Error (set ring): ".$tr064Result[0]->{Error} if $tr064Result[0]->{Error};
  2925. }
  2926. else {
  2927. FRITZBOX_Log $hash, 3, "Your Fritz!OS version has limited interfaces. You cannot ring.";
  2928. }
  2929. sleep 5 if $duration <= 0; # always wait before reseting everything
  2930. sleep $duration if $duration > 0 ; #+1; # 1s added because it takes some time until it starts ringing
  2931. #Preparing 4th command array to stop ringing (but not when duration is 0 or play: and say: is used without duration)
  2932. unless ( $duration == 0 || $duration == -1 && $ttsLink ) {
  2933. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialHangup"];
  2934. $result = FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray ) if $hash->{SECPORT} && $hash->{WEBCM} != 1;
  2935. push( @webCmdArray, "telcfg:command/Hangup" => "" ) if $hash->{WEBCM}==1;
  2936. }
  2937. #Preparing 5th command array to reset everything
  2938. push @webCmdArray, "telcfg:settings/DialPort" => $startValue->{dialPort} if defined $startValue->{dialPort};
  2939. FRITZBOX_Log $hash, 4, "Reset dial port to '".$dialPort{$startValue->{dialPort}}."'.";
  2940. # Reset internal ring tones for the Fritz!Fons
  2941. if ($ringTone) {
  2942. foreach (@FritzFons) {
  2943. my $value = $startValue->{dectUser}->[$_]->{IntRingTone};
  2944. push @webCmdArray, "telcfg:settings/Foncontrol/User".$_."/IntRingTone" => $value
  2945. unless $useGuiHack;
  2946. my $getCmdStr = "&ring_tone_radio_test=1&idx=".$_."&start_ringtest=1&ringtone=".$value;
  2947. FRITZBOX_Log $hash, 4, "Reset ring tone of dect$_ to $value";
  2948. # Reset internet station for the Fritz!Fons
  2949. if ($ttsLink) {
  2950. $value = $startValue->{dectUser}->[$_]->{RadioRingID};
  2951. push @webCmdArray, "telcfg:settings/Foncontrol/User".$_."/RadioRingID" => $value
  2952. unless $useGuiHack;
  2953. $getCmdStr .= "&ring_tone_radio_test=".$value;
  2954. FRITZBOX_Log $hash, 4, "Reset radio station of dect$_ to $value";
  2955. }
  2956. push @getCmdArray, [ "fon_devices/edit_dect_ring_tone.lua" => $getCmdStr ]
  2957. if $useGuiHack ;
  2958. }
  2959. }
  2960. # Reset name of calling number
  2961. if ($ringWithIntern =~ /^([1-2])$/) {
  2962. my $fonName = $startValue->{fonPort}->[$ringWithIntern-1]->{Name};
  2963. if ($fonName) {# darf nie leer sein
  2964. push( @webCmdArray, "telcfg:settings/MSN/Port".($ringWithIntern-1)."/Name" => $fonName ) ;
  2965. FRITZBOX_Log $hash, 4, "Reset name of dial port fon$ringWithIntern to '$fonName'";
  2966. }
  2967. }
  2968. # ??? Switch of Internet Radio stations
  2969. # if (!$ttsLink && defined $ringTone && $ringTone ==33 ) {
  2970. # push @webCmdArray, "telcfg:command/Dial **".$intNo;
  2971. # push @webCmdArray, "telcfg:command/Hangup **".$intNo;
  2972. # }
  2973. #set Fritzbox ring 612 show:test test say:test test
  2974. # Execute command array
  2975. $result = FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  2976. $result = FRITZBOX_Web_CmdGet( $hash, \@getCmdArray )
  2977. if int( @getCmdArray ) > 0;
  2978. if ( $result->[0] == 1 ) {
  2979. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sid", $result->[1];
  2980. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "fhem->sidTime", time();
  2981. }
  2982. FRITZBOX_Readout_Add_Reading $hash, \@roReadings, "readoutTime", sprintf( "%.2f", time()-$startTime);
  2983. my $returnStr = join('|', @roReadings );
  2984. FRITZBOX_Log $hash, 5, "Handover to main process: ".$returnStr;
  2985. return $name."|2|".encode_base64($returnStr,"");
  2986. # return $name."|1|Ringing done";
  2987. } # End FRITZBOX_Ring_Run_Web
  2988. #######################################################################
  2989. sub FRITZBOX_Set_Alarm_Shell($@)
  2990. {
  2991. my ($hash, @val) = @_;
  2992. my $name = $hash->{NAME};
  2993. my $alarm = $val[0];
  2994. shift @val;
  2995. my $para = " ".join(" ", @val);
  2996. my $state = 1;
  2997. my $stateTxt = "on";
  2998. if ($para =~ /off/i)
  2999. {
  3000. $state = 0;
  3001. $stateTxt = "off";
  3002. }
  3003. my $time;
  3004. my $timeTxt;
  3005. if ($para =~ /([0-2]?\d):([0-5]\d)/ )
  3006. {
  3007. if ($1<10)
  3008. {
  3009. $time = 0;
  3010. $timeTxt = "0";
  3011. }
  3012. $time .= $1.$2;
  3013. $timeTxt .= $1.":".$2;
  3014. $time = undef if $time > 2359;
  3015. }
  3016. my $day; my $dayTxt;
  3017. my %alDayValues = %alarmDays;
  3018. $alDayValues{0} = "once";
  3019. $alDayValues{127} = "daily";
  3020. while (my ($key, $value) = each(%alDayValues) )
  3021. {
  3022. if ($para =~ /$value/i)
  3023. {
  3024. $day += $key ;
  3025. $dayTxt .= $value." ";
  3026. }
  3027. }
  3028. my $result = FRITZBOX_Telnet_OpenCon( $hash );
  3029. return "$name|Error|$result"
  3030. if $result;
  3031. readingsBeginUpdate($hash);
  3032. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w telcfg settings/AlarmClock".($alarm-1)."/Active ".$state );
  3033. readingsBulkUpdate($hash,"alarm".$alarm."_state",$stateTxt);
  3034. if (defined $time)
  3035. {
  3036. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w telcfg settings/AlarmClock".($alarm-1)."/Time ".$time );
  3037. readingsBulkUpdate($hash,"alarm".$alarm."_time",$timeTxt);
  3038. }
  3039. if (defined $day)
  3040. {
  3041. FRITZBOX_Shell_Exec( $hash, "ctlmgr_ctl w telcfg settings/AlarmClock".($alarm-1)."/Weekdays ".$day );
  3042. chop $dayTxt;
  3043. readingsBulkUpdate($hash,"alarm".$alarm."_wdays",$dayTxt);
  3044. }
  3045. readingsEndUpdate($hash, 1);
  3046. FRITZBOX_Telnet_CloseCon( $hash );
  3047. return undef;
  3048. } # end FRITZBOX_Set_Alarm_Shell
  3049. #######################################################################
  3050. sub FRITZBOX_Set_Alarm_Web($@)
  3051. {
  3052. my ($hash, @val) = @_;
  3053. my $name = $hash->{NAME};
  3054. my @webCmdArray;
  3055. my $alarm = $val[0];
  3056. shift @val;
  3057. my $para = " ".join(" ", @val);
  3058. my $state = 1;
  3059. my $stateTxt = "on";
  3060. if ($para =~ /off/i)
  3061. {
  3062. $state = 0;
  3063. $stateTxt = "off";
  3064. }
  3065. my $time;
  3066. my $timeTxt;
  3067. if ($para =~ /([0-2]?\d):([0-5]\d)/ )
  3068. {
  3069. if ($1<10)
  3070. {
  3071. $time = 0;
  3072. $timeTxt = "0";
  3073. }
  3074. $time .= $1.$2;
  3075. $timeTxt .= $1.":".$2;
  3076. $time = undef if $time > 2359;
  3077. }
  3078. my $day; my $dayTxt;
  3079. my %alDayValues = %alarmDays;
  3080. $alDayValues{0} = "once";
  3081. $alDayValues{127} = "daily";
  3082. while (my ($key, $value) = each(%alDayValues) )
  3083. {
  3084. if ($para =~ /$value/i)
  3085. {
  3086. $day += $key ;
  3087. $dayTxt .= $value." ";
  3088. }
  3089. }
  3090. readingsBeginUpdate($hash);
  3091. push @webCmdArray, "telcfg:settings/AlarmClock".($alarm-1)."/Active" => $state;
  3092. readingsBulkUpdate($hash,"alarm".$alarm."_state",$stateTxt);
  3093. if (defined $time)
  3094. {
  3095. push @webCmdArray, "telcfg:settings/AlarmClock".($alarm-1)."/Time" => $time;
  3096. readingsBulkUpdate($hash,"alarm".$alarm."_time",$timeTxt);
  3097. }
  3098. if (defined $day)
  3099. {
  3100. push @webCmdArray, "telcfg:settings/AlarmClock".($alarm-1)."/Weekdays" => $day;
  3101. chop $dayTxt;
  3102. readingsBulkUpdate($hash,"alarm".$alarm."_wdays",$dayTxt);
  3103. }
  3104. FRITZBOX_Web_CmdPost ($hash, \@webCmdArray);
  3105. readingsEndUpdate($hash, 1);
  3106. return undef;
  3107. } # end FRITZBOX_Set_Alarm_Web
  3108. #######################################################################
  3109. sub FRITZBOX_SetMOH($@)
  3110. {
  3111. my ($hash, $type, @file) = @_;
  3112. my $returnStr;
  3113. my @cmdArray;
  3114. my $result;
  3115. my $name = $hash->{NAME};
  3116. my $uploadFile = '/var/tmp/fhem_moh_upload';
  3117. my $mohFile = '/var/tmp/fhem_fx_moh';
  3118. return "Error: Fritz!Box has no music on hold" unless defined $hash->{READINGS}{box_moh};
  3119. if (lc $type eq lc $mohtype{0} || $type eq "0") {
  3120. FRITZBOX_Shell_Exec ($hash, 'ctlmgr_ctl w telcfg settings/MOHType 0');
  3121. return 0;
  3122. }
  3123. elsif (lc $type eq lc $mohtype{1} || $type eq "1") {
  3124. FRITZBOX_Shell_Exec ($hash, 'ctlmgr_ctl w telcfg settings/MOHType 1');
  3125. return 1;
  3126. }
  3127. return "Error: Unvalid parameter '$type'" unless lc $type eq lc $mohtype{2} || $type eq "2";
  3128. # Load customer MOH file
  3129. my $inFile = join " ", @file;
  3130. my $uploadDir = AttrVal( $name, "defaultUploadDir", "" );
  3131. $uploadDir .= "/"
  3132. unless $uploadDir =~ /\/$|^$/;
  3133. if ($inFile !~ /^say:/i)
  3134. {
  3135. $inFile = $uploadDir.$inFile
  3136. unless $inFile =~ /^\//;
  3137. return "Error: Please give a complete file path or define the attribute 'defaultUploadDir'"
  3138. unless $inFile =~ /^\//;
  3139. return "Error: Only MP3 files can be used for 'music on hold'."
  3140. unless $inFile =~ /\.mp3$/i;
  3141. }
  3142. $result = FRITZBOX_Telnet_OpenCon( $hash );
  3143. return "$name|0|$result"
  3144. if $result;
  3145. push @cmdArray, '[ -f "'.$uploadFile.'" ] && rm "'.$uploadFile.'"';
  3146. push @cmdArray, '[ -f "'.$mohFile.'" ] && rm "'.$mohFile.'"';
  3147. if ($inFile =~ /^say:/i)
  3148. {
  3149. FRITZBOX_Log $hash, 4, "Converting Text2Speech";
  3150. # 'wget -U Mozilla -O "[ZIEL]" "http://translate.google.com/translate_tts?ie=UTF-8&tl=[SPRACHE]&q=[TEXT]"';
  3151. my $ttsCmd = $ttsCmdTemplate;
  3152. $ttsCmd =~ s/\[ZIEL\]/$uploadFile/;
  3153. my $ttsText = $inFile;
  3154. $ttsText =~ s/^say:\s*//i;
  3155. my $ttsLang = "de";
  3156. if ($ttsText =~ /^\((en|es|fr|nl)\)/i )
  3157. {
  3158. $ttsLang = $1;
  3159. $ttsText =~ s/^\($1\)\s*//i;
  3160. }
  3161. $ttsCmd =~ s/\[SPRACHE\]/$ttsLang/;
  3162. # $ttsText = ($ttsText." ") x int(60/length($ttsText))
  3163. # if length($ttsText) < 30;
  3164. $ttsText = substr($ttsText,0,70);
  3165. $ttsText = uri_escape($ttsText);
  3166. $ttsCmd =~ s/\[TEXT\]/$ttsText/;
  3167. push @cmdArray, $ttsCmd;
  3168. }
  3169. elsif ($inFile =~ /^(ftp|http):\/\//)
  3170. {
  3171. push @cmdArray, 'wget -U Mozilla -O "'.$uploadFile.'" "'.$inFile.'"';
  3172. } else {
  3173. push @cmdArray, 'cp "'.$inFile.'" "'.$uploadFile.'"';
  3174. }
  3175. push @cmdArray, '[ -f "'.$uploadFile.'" ] && echo 1 || echo 0';
  3176. # Execute command array
  3177. $result = FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  3178. return "Could not access '$inFile'"
  3179. unless $result->[3] eq "1";
  3180. #Prepare 2nd command array
  3181. push @cmdArray, 'if [ ! -f "/var/tmp/ffmpeg_mp3.tables" ]; then playerd_tables; fi';
  3182. push @cmdArray, 'ffmpegconv -i "'.$uploadFile.'" -o "'.$mohFile.'" --limit 32 --type 6';
  3183. push @cmdArray, '[ -f "'.$mohFile.'" ] && echo 1 || echo 0';
  3184. # Execute 2nd command array
  3185. $result = FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  3186. return "Could not convert '$inFile'"
  3187. unless $result->[2] eq "1";
  3188. #Prepare 3rd command array
  3189. push @cmdArray, 'cat "'.$mohFile.'" >/var/flash/fx_moh';
  3190. push @cmdArray, 'killall -sigusr1 telefon';
  3191. push @cmdArray, 'rm "'.$uploadFile.'"';
  3192. push @cmdArray, 'rm "'.$mohFile.'"';
  3193. # Execute 3rd command array
  3194. $result = FRITZBOX_Shell_Exec ( $hash, \@cmdArray );
  3195. FRITZBOX_Telnet_CloseCon( $hash );
  3196. return 2;
  3197. }
  3198. #######################################################################
  3199. sub FRITZBOX_SetCustomerRingTone($@)
  3200. {
  3201. my ($hash, $intern, @file) = @_;
  3202. my @cmdArray;
  3203. my $result;
  3204. my $name = $hash->{NAME};
  3205. my $uploadDir = AttrVal( $name, "defaultUploadDir", "" );
  3206. $uploadDir .= "/"
  3207. unless $uploadDir =~ /\/$|^$/;
  3208. my $inFile = join " ", @file;
  3209. $inFile = $uploadDir.$inFile
  3210. unless $inFile =~ /^\//;
  3211. return "Error: Please give a complete file path or the attribute 'defaultUploadDir'"
  3212. unless $inFile =~ /^\//;
  3213. return "Error: Only MP3 or G722 files can be uploaded to the phone."
  3214. unless $inFile =~ /\.mp3$|.g722$/i;
  3215. my $uploadFile = '/var/InternerSpeicher/FRITZ/fonring/'.int(time()).'.g722';
  3216. push @cmdArray, 'if [ ! -d /var/InternerSpeicher/FRITZ/fonring ]; then mkdir -p "/var/InternerSpeicher/FRITZ/fonring"; fi';
  3217. push @cmdArray, '[ -x /etc/init.d/rc.preaudio.sh ] && /etc/init.d/rc.preaudio.sh start';
  3218. $inFile =~ s/file:\/\///i;
  3219. # mp3 files are converted
  3220. if ( $inFile =~ /\.mp3$/i ) {
  3221. push @cmdArray, 'picconv.sh "file://'.$inFile.'" "'.$uploadFile.'" ringtonemp3';
  3222. # G722 files are copied
  3223. } elsif ( $inFile =~ /\.g722$/i ) {
  3224. push @cmdArray, "cp '$inFile' '$uploadFile'";
  3225. # all other formats fail
  3226. } else {
  3227. return "Error: only MP3 or G722 files can be uploaded to the phone";
  3228. }
  3229. # trigger the loading of the file to the phone, file will be deleted by the box as soon as the upload has finished
  3230. push @cmdArray, '/usr/bin/pbd --set-ringtone-url --book="255" --id="'.$intern.'" --url="file://'.$uploadFile.'" --name="FHEM'.int(time()).'"';
  3231. $result = FRITZBOX_Telnet_OpenCon( $hash );
  3232. return $result if $result;
  3233. FRITZBOX_Shell_Exec ($hash, \@cmdArray);
  3234. FRITZBOX_Telnet_CloseCon( $hash );
  3235. return "Upload of ring tone will take about 1 minute. Do not work with the phone until its done.";
  3236. }
  3237. #######################################################################
  3238. sub FRITZBOX_ConvertMOH ($@)
  3239. {
  3240. my ($hash, @file) = @_;
  3241. my $name = $hash->{NAME};
  3242. my $uploadDir = AttrVal( $name, "defaultUploadDir", "" );
  3243. $uploadDir .= "/"
  3244. unless $uploadDir =~ /\/$|^$/;
  3245. my $inFile = join " ", @file;
  3246. $inFile = $uploadDir.$inFile
  3247. unless $inFile =~ /^\//;
  3248. return "Error: You have to give a complete file path or to set the attribute 'defaultUploadDir'"
  3249. unless $inFile =~ /^\//;
  3250. return "Error: only MP3 or WAV files can be converted"
  3251. unless $inFile =~ /\.mp3$|.wav$/i;
  3252. $inFile =~ s/file:\/\///;
  3253. my $outFile = $inFile;
  3254. $outFile = substr($inFile,0,-4)
  3255. if ($inFile =~ /\.(mp3|wav)$/i);
  3256. my $returnStr = FRITZBOX_Shell_Exec ($hash
  3257. , 'ffmpegconv -i "'.$inFile.'" -o "'.$outFile.'.moh" --limit 32 --type 6');
  3258. return $returnStr;
  3259. } # end FRITZBOX_ConvertMOH
  3260. #######################################################################
  3261. sub FRITZBOX_ConvertRingTone ($@)
  3262. {
  3263. my ($hash, @file) = @_;
  3264. my $name = $hash->{NAME};
  3265. my $uploadDir = AttrVal( $name, "defaultUploadDir", "" );
  3266. $uploadDir .= "/"
  3267. unless $uploadDir =~ /\/$|^$/;
  3268. my $inFile = join " ", @file;
  3269. $inFile = $uploadDir.$inFile
  3270. unless $inFile =~ /^\//;
  3271. return "Error: You have to give a complete file path or to set the attribute 'defaultUploadDir'"
  3272. unless $inFile =~ /^\//;
  3273. return "Error: only MP3 or WAV files can be converted"
  3274. unless $inFile =~ /\.mp3$|.wav$/i;
  3275. $inFile =~ s/file:\/\///;
  3276. my $outFile = $inFile;
  3277. $outFile = substr($inFile,0,-4)
  3278. if ($inFile =~ /\.(mp3|wav)$/i);
  3279. my $returnStr = FRITZBOX_Shell_Exec ($hash
  3280. , 'picconv.sh "file://'.$inFile.'" "'.$outFile.'.g722" ringtonemp3');
  3281. return $returnStr;
  3282. } # end FRITZBOX_ConvertRingTone
  3283. #######################################################################
  3284. sub FRITZBOX_SendMail_Shell($@)
  3285. {
  3286. my ($hash,@val) = @_;
  3287. my $lastField;
  3288. my %field;
  3289. my @cmdArray;
  3290. foreach (@val)
  3291. {
  3292. if ($_ =~ /^(to|subject|body):/i)
  3293. {
  3294. $lastField = $1;
  3295. $_ =~ s/^$1://;
  3296. }
  3297. $field{$lastField} .= $_." "
  3298. if $lastField;
  3299. }
  3300. my $cmd = "/sbin/mailer send";
  3301. if ($field{body})
  3302. {
  3303. chop $field{body};
  3304. $field{body} =~ s/"/\\"/g;
  3305. # change none ASCII chars in octal code for ISO-8859-1 (acc. http://www.pjb.com.au/comp/diacritics.html)
  3306. $field{body} =~ s/Ä|Ä/\\304/g;
  3307. $field{body} =~ s/Ö|Ö/\\326/g;
  3308. $field{body} =~ s/Ü|Ü/\\334/g;
  3309. $field{body} =~ s/ß|ß/\\337/g;
  3310. $field{body} =~ s/ä|ä/\\344/g;
  3311. $field{body} =~ s/ö|ö/\\366/g;
  3312. $field{body} =~ s/ü|ü/\\374/g;
  3313. push @cmdArray, '/bin/echo -e "'.$field{body}.'" >/var/tmp/fhem_nachricht.txt';
  3314. $cmd .= " -i '/var/tmp/fhem_nachricht.txt'";
  3315. }
  3316. chop $field{subject} if $field{subject};
  3317. $field{subject} = "Message from FHEM " unless $field{subject};
  3318. $cmd .= " -s \"".$field{subject}."\"";
  3319. if ($field{to})
  3320. {
  3321. chop $field{to};
  3322. $cmd .= " -t \"".$field{to}."\""
  3323. }
  3324. push @cmdArray, $cmd;
  3325. push @cmdArray, "rm /var/tmp/fhem_nachricht.txt"
  3326. if $field{body};
  3327. FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  3328. return undef;
  3329. }
  3330. #######################################################################
  3331. sub FRITZBOX_StartRadio_Shell($@)
  3332. {
  3333. my ($hash, @val) = @_;
  3334. my @cmdArray;
  3335. my $name = $hash->{NAME};
  3336. my $intNo = $val[0];
  3337. my $radioStation;
  3338. my $radioStationName;
  3339. my $result;
  3340. # Check if 1st parameter is a number
  3341. return "Error: 1st Parameter '$intNo' not an internal DECT number"
  3342. unless $intNo =~ /^61[012345]$/;
  3343. # Check if the 1st parameter is a Fritz!Fon
  3344. return "Error: Internal number $intNo does not seem to be a Fritz!Fon."
  3345. unless $hash->{fhem}{$intNo}{brand} eq "AVM";
  3346. # Check if remaining parameter is an internet Radio Station
  3347. shift (@val);
  3348. if (@val) {
  3349. $radioStationName = join (" ", @val);
  3350. if ($radioStationName =~ /^\d+$/) {
  3351. $radioStation = $radioStationName;
  3352. $radioStationName = $hash->{fhem}{radio}{$radioStation};
  3353. return "Error: Unknown internet radio number $radioStation."
  3354. unless defined $radioStationName;
  3355. }
  3356. else {
  3357. foreach (keys %{$hash->{fhem}{radio}}) {
  3358. if (lc $hash->{fhem}{radio}{$_} eq lc $radioStationName) {
  3359. $radioStation = $_;
  3360. last;
  3361. }
  3362. }
  3363. return "Error: Unknown internet radio station '$radioStationName'"
  3364. unless defined $radioStation;
  3365. }
  3366. }
  3367. $result = FRITZBOX_Telnet_OpenCon( $hash );
  3368. return $result if $result;
  3369. # Get current ringtone
  3370. my $userNo = $intNo-609;
  3371. push @cmdArray, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$userNo."/IntRingTone";
  3372. push @cmdArray, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$userNo."/RadioRingID";
  3373. $result = FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  3374. my $curRingTone = $result->[0];
  3375. my $curRadioStation = $result->[1];
  3376. # Start Internet Radio and reset ring tone
  3377. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$userNo."/IntRingTone 33";
  3378. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$userNo."/RadioRingID $radioStation"
  3379. if defined $radioStation;
  3380. push @cmdArray, "ctlmgr_ctl w telcfg command/Dial **".$intNo;
  3381. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$userNo."/IntRingTone $curRingTone";
  3382. push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$userNo."/RadioRingID $curRadioStation"
  3383. if defined $radioStation;
  3384. # Execute command array
  3385. FRITZBOX_Shell_Exec( $hash, \@cmdArray );
  3386. FRITZBOX_Telnet_CloseCon( $hash );
  3387. return undef;
  3388. }
  3389. #######################################################################
  3390. sub FRITZBOX_StartRadio_Web($@)
  3391. {
  3392. my ($hash, @val) = @_;
  3393. my @webCmdArray;
  3394. my @getCmdArray;
  3395. my @tr064CmdArray;
  3396. my $name = $hash->{NAME};
  3397. my $intNo = $val[0];
  3398. my $radioStation;
  3399. my $radioStationName;
  3400. my $result;
  3401. # Check if 1st parameter is a number
  3402. return "Error: 1st Parameter '$intNo' not an internal DECT number"
  3403. unless $intNo =~ /^61[012345]$/;
  3404. # Check if the 1st parameter is a Fritz!Fon
  3405. return "Error: Internal number $intNo does not seem to be a Fritz!Fon."
  3406. unless $hash->{fhem}{$intNo}{brand} eq "AVM";
  3407. # Check if remaining parameter is an internet Radio Station
  3408. shift (@val);
  3409. if (@val) {
  3410. $radioStationName = join (" ", @val);
  3411. if ($radioStationName =~ /^\d+$/) {
  3412. $radioStation = $radioStationName;
  3413. $radioStationName = $hash->{fhem}{radio}{$radioStation};
  3414. return "Error: Unknown internet radio number $radioStation."
  3415. unless defined $radioStationName;
  3416. }
  3417. else {
  3418. foreach (keys %{$hash->{fhem}{radio}}) {
  3419. if (lc $hash->{fhem}{radio}{$_} eq lc $radioStationName) {
  3420. $radioStation = $_;
  3421. last;
  3422. }
  3423. }
  3424. return "Error: Unknown internet radio station '$radioStationName'"
  3425. unless defined $radioStation;
  3426. }
  3427. }
  3428. # Get current ringtone
  3429. my $userNo = $intNo-609;
  3430. my $queryStr = "&curRingTone=telcfg:settings/Foncontrol/User".$userNo."/IntRingTone";
  3431. $queryStr .= "&curRadioStation=telcfg:settings/Foncontrol/User".$userNo."/RadioRingID";
  3432. my $startValue = FRITZBOX_Web_Query( $hash, $queryStr );
  3433. # Set ring tone Internet Radio
  3434. FRITZBOX_Log $hash, 5, "Set ring tone of $intNo to radio $radioStation";
  3435. push @webCmdArray, "telcfg:settings/Foncontrol/User".$userNo."/IntRingTone" => 33;
  3436. push @webCmdArray, "telcfg:settings/Foncontrol/User".$userNo."/RadioRingID" => $radioStation
  3437. if defined $radioStation;
  3438. FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  3439. FRITZBOX_Log $hash, 5, "Call $intNo";
  3440. if ($hash->{SECPORT}) { #ring with TR-064
  3441. push @tr064CmdArray, ["X_VoIP:1", "x_voip", "X_AVM-DE_DialNumber", "NewX_AVM-DE_PhoneNumber", "**".$intNo."#"];
  3442. FRITZBOX_TR064_Cmd( $hash, 0, \@tr064CmdArray );
  3443. }
  3444. else { # ring with webcm
  3445. push @webCmdArray, "telcfg:command/Dial" => "**".$intNo."#";
  3446. FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  3447. }
  3448. # Reset ring tone
  3449. FRITZBOX_Log $hash, 5, "Reset ring tones.";
  3450. push @webCmdArray, "telcfg:settings/Foncontrol/User".$userNo."/IntRingTone" => $startValue->{curRingTone};
  3451. push @webCmdArray, "telcfg:settings/Foncontrol/User".$userNo."/RadioRingID" => $startValue->{curRadioStation}
  3452. if defined $radioStation;
  3453. FRITZBOX_Web_CmdPost( $hash, \@webCmdArray );
  3454. return undef;
  3455. } # END sub FRITZBOX_StartRadio_Web
  3456. #'picconv.sh "'.$inFile.'" "'.$outFile.'.g722" ringtonemp3'
  3457. #picconv.sh "file://$dir/upload.mp3" "$dir/$filename" ringtonemp3
  3458. #"ffmpegconv -i '$inFile' -o '$outFile.g722' --limit 240");
  3459. #ffmpegconv -i "${in}" -o "${out}" --limit 240
  3460. #pbd --set-image-url --book=255 --id=612 --url=/var/InternerSpeicher/FRITZ/fonring/1416431162.g722 --type=1
  3461. #pbd --set-image-url --book=255 --id=612 --url=file://var/InternerSpeicher/FRITZBOXtest.g722 --type=1
  3462. #ctlmgr_ctl r user settings/user0/bpjm_filter_enable
  3463. #/usr/bin/pbd --set-ringtone-url --book="255" --id="612" --url="file:///var/InternerSpeicher/claydermann.g722" --name="Claydermann"
  3464. # /usr/bin/moh_upload
  3465. #######################################################################
  3466. sub FRITZBOX_Shell_Query($$$)
  3467. {
  3468. my ($hash, $readoutCmdArray, $roReadings) = @_;
  3469. my @cmdArray;
  3470. my $rValue;
  3471. my $rName;
  3472. my $rFormat;
  3473. my $count = int @{$readoutCmdArray} - 1;
  3474. for (0..$count)
  3475. {
  3476. push @cmdArray, $readoutCmdArray->[$_][1];
  3477. }
  3478. my $resultArray = FRITZBOX_Shell_Exec( $hash, \@cmdArray);
  3479. if (defined ($resultArray))
  3480. {
  3481. $count = int @{$resultArray} -1;
  3482. for (0..$count)
  3483. {
  3484. $rValue = $resultArray->[$_];
  3485. $rFormat = $readoutCmdArray->[$_][2];
  3486. $rFormat = "" unless defined $rFormat;
  3487. $rValue = FRITZBOX_Readout_Format ($hash, $rFormat, $rValue);
  3488. $rName = $readoutCmdArray->[$_][0];
  3489. if ($rName ne "")
  3490. {
  3491. FRITZBOX_Log $hash, 5, "$rName: $rValue";
  3492. push @{$roReadings}, $rName."|".$rValue;
  3493. }
  3494. }
  3495. }
  3496. @{$readoutCmdArray} = ();
  3497. return $resultArray;
  3498. }
  3499. # Executed the command on the FritzBox Shell (remote or local)
  3500. ############################################
  3501. sub FRITZBOX_Shell_Exec($$)
  3502. {
  3503. my ($hash, $cmd) = @_;
  3504. my $openedTelnet = 0;
  3505. if ($hash->{REMOTE} == 1) {
  3506. unless (defined $telnet) {
  3507. return undef
  3508. if (FRITZBOX_Telnet_OpenCon($hash));
  3509. $openedTelnet = 1;
  3510. }
  3511. my $retVal = FRITZBOX_Shell_Exec_Telnet($hash, $cmd);
  3512. FRITZBOX_Telnet_CloseCon ( $hash ) if $openedTelnet;
  3513. return $retVal;
  3514. }
  3515. else {
  3516. return FRITZBOX_Shell_Exec_Local($hash, $cmd);
  3517. }
  3518. }
  3519. # Executed the command on the fhem server (on the FritzBox Shell)
  3520. ############################################
  3521. sub FRITZBOX_Shell_Exec_Local($$)
  3522. {
  3523. my ($hash, $cmd) = @_;
  3524. if (ref \$cmd eq "SCALAR") {
  3525. FRITZBOX_Log $hash, 5, "Execute '".$cmd."'";
  3526. my $result = qx($cmd);
  3527. chomp $result;
  3528. FRITZBOX_Log $hash, 5, "Result '$result'";
  3529. return $result;
  3530. }
  3531. elsif (ref \$cmd eq "REF") {
  3532. if ( int (@{$cmd}) > 0 )
  3533. {
  3534. FRITZBOX_Log $hash, 4, "Execute " . int ( @{$cmd} ) . " command(s)";
  3535. FRITZBOX_Log $hash, 5, "Commands: '" . join( " | ", @{$cmd} ) . "'";
  3536. my $cmdStr = join "\necho ' |#|'\n", @{$cmd};
  3537. $cmdStr .= "\necho ' |#|'";
  3538. my $result = qx($cmdStr);
  3539. unless (defined $result)
  3540. {
  3541. FRITZBOX_Log $hash, 1, "Error: No STDOUT from shell command.";
  3542. return undef;
  3543. }
  3544. $result =~ s/\n|\r//g;
  3545. my @resultArray = split /\|#\|/, $result;
  3546. for (0 .. $#resultArray)
  3547. {
  3548. $resultArray[$_] =~ s/\s$//;
  3549. }
  3550. @{$cmd} = ();
  3551. FRITZBOX_Log $hash, 4, "Received ".int(@resultArray)." answer(s)";
  3552. FRITZBOX_Log $hash, 5, "Result: '" . join (" | ", @resultArray)."'";
  3553. return \@resultArray;
  3554. }
  3555. else
  3556. {
  3557. FRITZBOX_Log $hash, 4, "No shell command to execute.";
  3558. }
  3559. }
  3560. else {
  3561. FRITZBOX_Log $hash, 1, "Error: wrong perl parameter";
  3562. }
  3563. }
  3564. # Executed a command via Telnet
  3565. ############################################
  3566. sub FRITZBOX_Shell_Exec_Telnet($$)
  3567. {
  3568. my ($hash, $cmd) = @_;
  3569. my @output;
  3570. my $result;
  3571. if (ref \$cmd eq "SCALAR") {
  3572. FRITZBOX_Log $hash, 4, "Execute '".$cmd."'";
  3573. @output=$telnet->cmd($cmd);
  3574. $result = $output[0];
  3575. chomp $result;
  3576. my $log = join " ", @output;
  3577. chomp $log;
  3578. FRITZBOX_Log $hash, 4, "Result '$log'";
  3579. return $result;
  3580. }
  3581. elsif (ref \$cmd eq "REF") {
  3582. my @resultArray = ();
  3583. if ( int (@{$cmd}) > 0 )
  3584. {
  3585. FRITZBOX_Log $hash, 4, "Execute " . int ( @{$cmd} ) . " command(s)";
  3586. foreach (@{$cmd})
  3587. {
  3588. FRITZBOX_Log $hash, 5, "Execute '$_'";
  3589. unless ($_ =~ /^sleep/)
  3590. {
  3591. @output=$telnet->cmd($_);
  3592. $result = $output[0] || "";
  3593. chomp $result;
  3594. my $log = join "", @output;
  3595. chomp $log;
  3596. FRITZBOX_Log $hash, 5, "Result '$log'";
  3597. }
  3598. else
  3599. {
  3600. FRITZBOX_Log $hash, 4, "Do '$_' in perl.";
  3601. eval ($_);
  3602. $result = "";
  3603. }
  3604. push @resultArray, $result;
  3605. }
  3606. @{$cmd} = ();
  3607. FRITZBOX_Log $hash, 4, "Received ".int(@resultArray)." answer(s)";
  3608. }
  3609. else
  3610. {
  3611. FRITZBOX_Log $hash, 4, "No shell command to execute.";
  3612. }
  3613. return \@resultArray;
  3614. }
  3615. else {
  3616. FRITZBOX_Log $hash, 1, "Error: wrong perl parameter";
  3617. return undef;
  3618. }
  3619. }
  3620. # Opens a Telnet Connection to an external FritzBox
  3621. ############################################
  3622. sub FRITZBOX_Telnet_OpenCon($)
  3623. {
  3624. my ($hash) = @_;
  3625. my $name = $hash->{NAME};
  3626. return undef unless $hash->{REMOTE} == 1;
  3627. if ($missingModulTelnet) {
  3628. my $msg = "Error: Perl modul ".$missingModulTelnet."is missing on this system. Please install before using this modul.";
  3629. FRITZBOX_Log $hash, 2, $msg;
  3630. return $msg;
  3631. }
  3632. my $host = $hash->{HOST};
  3633. my $pwd = FRITZBOX_readPassword($hash);
  3634. my $msg;
  3635. my $before;
  3636. my $match;
  3637. unless (defined $pwd) {
  3638. $msg = "Error: No password set. Please define it with 'set $name password YourPassword'";
  3639. FRITZBOX_Log $hash, 2, $msg;
  3640. # return $msg;
  3641. my $pwdFile = AttrVal( $name, "pwdFile", "fb_pwd.txt");
  3642. FRITZBOX_Log $hash, 5, "Open password file '$pwdFile' to extract password";
  3643. if (open(IN, "<" . $pwdFile)) {
  3644. $pwd = <IN>;
  3645. close(IN);
  3646. FRITZBOX_Log $hash, 5, "Close password file";
  3647. } else {
  3648. FRITZBOX_Log $hash, 2, $msg;
  3649. return $msg;
  3650. }
  3651. }
  3652. my $user = AttrVal( $name, "telnetUser", "" );
  3653. FRITZBOX_Log $hash, 4, "Open Telnet connection to $host";
  3654. my $timeout = AttrVal( $name, "telnetTimeOut", "10");
  3655. $telnet = new Net::Telnet ( Host=>$host, Port => 23, Timeout=>$timeout, Errmode=>'return', Prompt=>'/# $/');
  3656. if (!$telnet) {
  3657. $msg = "Could not open telnet connection to $host: $!";
  3658. FRITZBOX_Log $hash, 2, $msg;
  3659. $telnet = undef;
  3660. return $msg;
  3661. }
  3662. FRITZBOX_Log $hash, 5, "Wait for user or password prompt.";
  3663. unless ( ($before,$match) = $telnet->waitfor('/(user|login|password): $/i') ) {
  3664. $msg = "Telnet error while waiting for user or password prompt: ".$telnet->errmsg;
  3665. FRITZBOX_Log $hash, 2, $msg;
  3666. $telnet->close;
  3667. $telnet = undef;
  3668. return $msg;
  3669. }
  3670. if ( $match =~ /(user|login): / && $user eq "") {
  3671. $msg = "Telnet login requires user name but attribute 'telnetUser' not defined";
  3672. FRITZBOX_Log $hash, 2, $msg;
  3673. $telnet->close;
  3674. $telnet = undef;
  3675. return $msg;
  3676. }
  3677. elsif ( $match =~ /(user|login): /) {
  3678. FRITZBOX_Log $hash, 5, "Entering user name";
  3679. $telnet->print( $user );
  3680. FRITZBOX_Log $hash, 5, "Wait for password prompt";
  3681. unless ($telnet->waitfor( '/password: $/i' ))
  3682. {
  3683. $msg = "Telnet error while waiting for password prompt: ".$telnet->errmsg;
  3684. FRITZBOX_Log $hash, 2, $msg;
  3685. $telnet->close;
  3686. $telnet = undef;
  3687. return $msg;
  3688. }
  3689. }
  3690. elsif ( $match eq "password: " && $user ne "") {
  3691. FRITZBOX_Log $hash, 3, "Attribute 'telnetUser' defined but telnet login did not prompt for user name.";
  3692. }
  3693. FRITZBOX_Log $hash, 5, "Entering password";
  3694. $telnet->print( $pwd );
  3695. FRITZBOX_Log $hash, 5, "Wait for command prompt";
  3696. unless ( ($before,$match) = $telnet->waitfor( '/# $|Login failed./i' )) {
  3697. $msg = "Telnet error while waiting for command prompt: ".$telnet->errmsg;
  3698. FRITZBOX_Log $hash, 2, $msg;
  3699. $telnet->close;
  3700. $telnet = undef;
  3701. return $msg;
  3702. }
  3703. elsif ( $match eq "Login failed.") {
  3704. $msg = "Telnet error: Login failed. Wrong password.";
  3705. FRITZBOX_Log $hash, 2, $msg;
  3706. $telnet->close;
  3707. $telnet = undef;
  3708. return $msg;
  3709. }
  3710. # redirect console messages
  3711. $telnet->cmd("setconsole -r");
  3712. FRITZBOX_Log $hash, 5, "Change command prompt";
  3713. $telnet->prompt('/<xFHEMx> $/');
  3714. unless ($telnet->cmd("PS1='<xFHEMx> '")) {
  3715. $msg = "Telnet error: Could not change command prompt - ".$telnet->errmsg;
  3716. FRITZBOX_Log $hash, 2, $msg;
  3717. $telnet->close;
  3718. $telnet = undef;
  3719. return $msg;
  3720. }
  3721. return undef;
  3722. } # end FRITZBOX_Telnet_OpenCon
  3723. # Closes a Telnet Connection to an external FritzBox
  3724. ############################################
  3725. sub FRITZBOX_Telnet_CloseCon($)
  3726. {
  3727. my ($hash) = @_;
  3728. return undef
  3729. unless $hash->{REMOTE} == 1;
  3730. if (defined $telnet) {
  3731. FRITZBOX_Log $hash, 4, "Close Telnet connection";
  3732. $telnet->close;
  3733. $telnet = undef;
  3734. }
  3735. else {
  3736. FRITZBOX_Log $hash, 1, "Cannot close an undefined Telnet connection";
  3737. }
  3738. } # end FRITZBOX_Telnet_CloseCon
  3739. # Execute a Command via TR-064
  3740. #################################################
  3741. sub FRITZBOX_TR064_Cmd($$$)
  3742. {
  3743. my ($hash, $xml, $cmdArray) = @_;
  3744. my $name = $hash->{NAME};
  3745. my $port = $hash->{SECPORT};
  3746. unless ($port) {
  3747. FRITZBOX_Log $hash, 4, "TR064 not used. No security port defined.";
  3748. return undef;
  3749. }
  3750. # Set Password und User for TR064 access
  3751. $FRITZBOX_TR064pwd = FRITZBOX_readPassword($hash) unless defined $FRITZBOX_TR064pwd;
  3752. $FRITZBOX_TR064user = AttrVal( $name, "boxUser", "dslf-config" );
  3753. my $host = $hash->{HOST};
  3754. my @retArray;
  3755. foreach( @{$cmdArray} ) {
  3756. next unless int @{$_} >=3 && int( @{$_} ) % 2 == 1;
  3757. my( $service, $control, $action, %params) = @{$_};
  3758. my @soapParams;
  3759. $service =~ s/urn:dslforum-org:service://;
  3760. $control =~ s#/upnp/control/##;
  3761. my $logMsg = "service='$service', control='$control', action='$action'";
  3762. # Prepare action parameter
  3763. foreach (keys %params) {
  3764. $logMsg .= ", parameter".(int(@soapParams)+1)."='$_' => '$params{$_}'" ;
  3765. push @soapParams, SOAP::Data->name( $_ => $params{$_} );
  3766. }
  3767. FRITZBOX_Log $hash, 4, "Perform TR-064 call - ".$logMsg;
  3768. my $soap = SOAP::Lite
  3769. -> on_fault ( sub {} )
  3770. -> uri( "urn:dslforum-org:service:".$service )
  3771. -> proxy('https://'.$host.":".$port."/upnp/control/".$control, ssl_opts => [ SSL_verify_mode => 0 ], timeout => 10 )
  3772. -> readable(1);
  3773. my $res = $soap -> call( $action => @soapParams );
  3774. unless( $res ) { # Transport-Error
  3775. FRITZBOX_Log $hash, 2, "TR064-Transport-Error: ".$soap->transport->status;
  3776. my %errorMsg = ( "Error" => $soap->transport->status );
  3777. push @retArray, \%errorMsg;
  3778. $FRITZBOX_TR064pwd = undef;
  3779. }
  3780. elsif( $res->fault ) { # SOAP Error - will be defined if Fault element is in the message
  3781. # my $fcode = $s->faultcode; #
  3782. # my $fstring = $s->faultstring; # also available
  3783. # my $factor = $s->faultactor;
  3784. my $ecode = $res->faultdetail->{'UPnPError'}->{'errorCode'};
  3785. my $edesc = $res->faultdetail->{'UPnPError'}->{'errorDescription'};
  3786. FRITZBOX_Log $hash, 2, "TR064-Error $ecode:$edesc ($logMsg)";
  3787. @{$cmdArray} = ();
  3788. # my $fdetail = Dumper($res->faultdetail); # returns value of 'detail' element as string or object
  3789. # return "Error\n".$fdetail;
  3790. push @retArray, $res->faultdetail;
  3791. $FRITZBOX_TR064pwd = undef;
  3792. }
  3793. else { # normal result
  3794. push @retArray, $res->body;
  3795. }
  3796. }
  3797. @{$cmdArray} = ();
  3798. return @retArray;
  3799. } # End of FRITZBOX_TR064_Cmd
  3800. # get Fritzbox tr064ServiceList
  3801. #################################################
  3802. sub FRITZBOX_TR064_Get_ServiceList($)
  3803. {
  3804. my ($hash) = @_;
  3805. my $name = $defs{NAME};
  3806. if ( $missingModulWeb ) {
  3807. my $msg = "Error: Perl modul " . $missingModulWeb . "is missing on this system. Please install before using this modul.";
  3808. FRITZBOX_Log $hash, 2, $msg;
  3809. return $msg;
  3810. }
  3811. my $host = $hash->{HOST};
  3812. my $url = 'http://'.$host.":49000/tr64desc.xml";
  3813. my $returnStr = "_" x 130 ."\n\n";
  3814. $returnStr .= " List of TR-064 services and actions that are provided by the device '$host'\n";
  3815. return "TR-064 switched off." if $hash->{READINGS}{box_tr064}{VAL} eq "off";
  3816. FRITZBOX_Log $hash, 5, "Getting service page $url";
  3817. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10);
  3818. my $response = $agent->get( $url );
  3819. return "$url does not exist." if $response->is_error();
  3820. my $content = $response->content;
  3821. my @serviceArray;
  3822. # Get basic service data
  3823. while( $content =~ /<service>(.*?)<\/service>/isg ) {
  3824. my $serviceXML = $1;
  3825. my @service;
  3826. my $service = $1 if $serviceXML =~ m/<servicetype>urn:dslforum-org:service:(.*?)<\/servicetype>/is;
  3827. my $control = $1 if $serviceXML =~ m/<controlurl>\/upnp\/control\/(.*?)<\/controlurl>/is;
  3828. my $scpd = $1 if $serviceXML =~ m/<scpdurl>(.*?)<\/scpdurl>/is;
  3829. push @serviceArray, [$service, $control, $scpd];
  3830. }
  3831. # Get actions of each service
  3832. foreach (@serviceArray) {
  3833. $url = 'http://'.$host.":49000".$_->[2];
  3834. FRITZBOX_Log $hash, 5, "Getting action page $url";
  3835. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10);
  3836. my $response = $agent->get( $url );
  3837. return "ServiceSCPD $url does not exist" if $response->is_error();
  3838. my $content = $response->content;
  3839. # get version
  3840. $content =~ /<major>(.*?)<\/major>/isg;
  3841. my $version = $1;
  3842. $content =~ /<minor>(.*?)<\/minor>/isg;
  3843. $version .= ".".$1;
  3844. $returnStr .= "_" x 130 ."\n\n";
  3845. $returnStr .= " Spec: http://".$host.":49000".$_->[2]." Version: ".$version."\n";
  3846. $returnStr .= " Service: ".$_->[0]." Control: ".$_->[1]."\n";
  3847. $returnStr .= "-" x 130 ."\n";
  3848. # get name and arguments of each action
  3849. while( $content =~ /<action>(.*?)<\/action>/isg ) {
  3850. my $serviceXML = $1;
  3851. $serviceXML =~ /<name>(.*?)<\/name>/is;
  3852. my $action = $1;
  3853. $serviceXML =~ /<argumentlist>(.*?)<\/argumentlist>/is;
  3854. my $argXML = $1;
  3855. my $lineStr = " $action (";
  3856. my $tab = " " x length( $lineStr );
  3857. my @argArray = ($argXML =~ /<argument>(.*?)<\/argument>/isg);
  3858. my @argOut;
  3859. foreach (@argArray) {
  3860. $_ =~ /<name>(.*?)<\/name>/is;
  3861. my $argName = $1;
  3862. $_ =~ /<direction>(.*?)<\/direction>/is;
  3863. my $argDir = $1;
  3864. if ($argDir eq "in") {
  3865. # Wrap
  3866. if (length ($lineStr.$argName) > 129) {
  3867. $returnStr .= $lineStr."\n" ;
  3868. $lineStr = $tab;
  3869. }
  3870. $lineStr .= " $argName";
  3871. }
  3872. else { push @argOut, $argName; }
  3873. }
  3874. $lineStr .= " )";
  3875. $lineStr .= " = (" if int @argOut;
  3876. foreach (@argOut) {
  3877. # Wrap
  3878. if (length ($lineStr.$_) > 129) {
  3879. $returnStr .= $lineStr."\n" ;
  3880. $lineStr = $tab ." " x 6;
  3881. }
  3882. $lineStr .= " $_";
  3883. }
  3884. $lineStr .= " )" if int @argOut;
  3885. $returnStr .= $lineStr."\n";
  3886. }
  3887. }
  3888. return $returnStr;
  3889. }
  3890. #######################################################################
  3891. sub FRITZBOX_TR064_Init ($$)
  3892. {
  3893. my ($hash, $host) = @_;
  3894. my $name = $hash->{NAME};
  3895. return if AttrVal( $name, "forceTelnetConnection", 0 );
  3896. if ($missingModulTR064) {
  3897. FRITZBOX_Log $hash, 2, "Cannot use TR-064. Perl modul ".$missingModulTR064."is missing on this system. Please install.";
  3898. return undef;
  3899. }
  3900. # Security Port anfordern
  3901. FRITZBOX_Log $hash, 4, "Open TR-064 connection and ask for security port";
  3902. my $s = SOAP::Lite
  3903. -> uri('urn:dslforum-org:service:DeviceInfo:1')
  3904. -> proxy('http://'.$host.':49000/upnp/control/deviceinfo', timeout => 10 )
  3905. -> getSecurityPort();
  3906. my $port = $s->result;
  3907. unless( $port ) {
  3908. FRITZBOX_Log $hash, 2, "Could not get secure port: $!";
  3909. return undef;
  3910. }
  3911. # $hash->{TR064USER} = "dslf-config";
  3912. # jetzt die Zertifikatsüberprüfung (sofort) abschalten
  3913. BEGIN {
  3914. $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
  3915. }
  3916. # dieser Code authentifiziert an der Box
  3917. sub SOAP::Transport::HTTP::Client::get_basic_credentials {return $FRITZBOX_TR064user => $FRITZBOX_TR064pwd;}
  3918. return $port;
  3919. }
  3920. # Opens a Web connection to an external Fritzbox
  3921. ############################################
  3922. sub FRITZBOX_Web_OpenCon ($)
  3923. {
  3924. my ($hash) = @_;
  3925. my $name = $hash->{NAME};
  3926. return undef
  3927. unless $hash->{REMOTE} == 1;
  3928. if ($missingModulWeb) {
  3929. FRITZBOX_Log $hash, 2, "Error: Perl modul ".$missingModulWeb."is missing on this system. Please install before using this modul.";
  3930. return undef;
  3931. }
  3932. # Use old sid if last access later than 9.5 minutes
  3933. my $sid = $hash->{fhem}{sid};
  3934. return $sid
  3935. if defined $sid && $hash->{fhem}{sidTime}>time()-9.5*60;
  3936. my $host = $hash->{HOST};
  3937. my $pwd = FRITZBOX_readPassword($hash);
  3938. unless (defined $pwd) {
  3939. FRITZBOX_Log $hash, 2, "Error: No password set. Please define it (once) with 'set $name password YourPassword'";
  3940. return undef;
  3941. }
  3942. my $user = AttrVal( $name, "boxUser", "" );
  3943. $user = AttrVal( $name, "telnetUser", "" ) if $user eq "";
  3944. FRITZBOX_Log $hash, 4, "Open Web connection to $host";
  3945. $sid = (FB_doCheckPW($host, $user, $pwd));
  3946. if ($sid) {
  3947. FRITZBOX_Log $hash, 4, "Web session opened with sid $sid";
  3948. return $sid;
  3949. }
  3950. FRITZBOX_Log $hash, 2, "Web connection could not be established. Please check your credentials (password, user).";
  3951. return undef;
  3952. }
  3953. # Execute commands via the web connection
  3954. ############################################
  3955. sub FRITZBOX_Web_CmdPost($$@)
  3956. {
  3957. my ($hash, $webCmdArray, $page) = @_;
  3958. my $name = $hash->{NAME};
  3959. unless ( $hash->{WEBCM}==1 ) {
  3960. @{$webCmdArray} = ();
  3961. my $msg = "API webcm not available on the box.";
  3962. FRITZBOX_Log $hash, 4, $msg;
  3963. my @retArray = (0, $msg);
  3964. return \@retArray;
  3965. }
  3966. my $sid = FRITZBOX_Web_OpenCon($hash);
  3967. unless ($sid) {
  3968. my @retArray = (2, "Didn't get a session ID");
  3969. return \@retArray;
  3970. }
  3971. # Complete the arguments
  3972. if ($page) {
  3973. $page .= "?sid=".$sid;
  3974. push @{$webCmdArray}, "apply" => "";
  3975. }
  3976. else {
  3977. $page = '/cgi-bin/webcm';
  3978. }
  3979. push @{$webCmdArray}, "sid" => $sid;
  3980. my $host = $hash->{HOST};
  3981. my $url = 'http://'.$host.$page;
  3982. FRITZBOX_Log $hash, 5, "Posting ".(@{$webCmdArray} /2) ." parameters to '$url'";
  3983. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10);
  3984. my $response = $agent->post( $url, $webCmdArray );
  3985. @{$webCmdArray} = ();
  3986. if ($response->is_error) {
  3987. my @retArray = (0, "Error: ".$response->status_line);
  3988. return \@retArray;
  3989. }
  3990. # FRITZBOX_Log $hash, 3, "Response: ".$response->content;
  3991. # if ($response->content)
  3992. # {
  3993. # my @retArray = (0, "Command not executed");
  3994. # return \@retArray;
  3995. # }
  3996. my @retArray = (1, $sid);
  3997. return \@retArray;
  3998. }
  3999. # Execute commands via the web connection
  4000. ############################################
  4001. sub FRITZBOX_Web_CmdGet($$)
  4002. {
  4003. #set Fritzbox ring 612 ringring
  4004. #URL=http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=4&sid=5695bd219020152b&start_ringtest=1&ringtone=4&xhr=1&t1436900289183=nocache
  4005. #URL=http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=4&sid=5695bd219020152b&start_ringtest=2&xhr=1&t1436900295372=nocache
  4006. my ($hash, $getCmdArray) = @_;
  4007. my $name = $hash->{NAME};
  4008. my $sid = FRITZBOX_Web_OpenCon($hash);
  4009. unless ($sid) {
  4010. my @retArray = (0, "Didn't get a session ID");
  4011. return \@retArray;
  4012. }
  4013. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 10 );
  4014. my $host = $hash->{HOST};
  4015. foreach ( @{$getCmdArray} ) {
  4016. my ($page,$getCmdStr) = @{$_};
  4017. my $url = 'http://'.$host."/".$page."?sid=".$sid.$getCmdStr;
  4018. FRITZBOX_Log $hash, 4, "Execute HTTP-Get '$url'";
  4019. my $response = $agent->get( $url );
  4020. if ($response->is_error) {
  4021. my @retArray = (0, "Error: ".$response->status_line);
  4022. return \@retArray;
  4023. }
  4024. else {
  4025. FRITZBOX_Log $hash, 5, "Response: ".$response->content();
  4026. }
  4027. }
  4028. @{$getCmdArray} = ();
  4029. my @retArray = (1, $sid);
  4030. return \@retArray;
  4031. }
  4032. # Read box values via the web connection
  4033. ############################################
  4034. sub FRITZBOX_Web_Query($$@)
  4035. {
  4036. my ($hash, $queryStr, $charSet) = @_;
  4037. $charSet = "" unless defined $charSet;
  4038. my $name = $hash->{NAME};
  4039. my $sid = FRITZBOX_Web_OpenCon( $hash );
  4040. unless ($sid) {
  4041. my %retHash = ( "Error" => "Didn't get a session ID", "ResetSID" => "1" ) ;
  4042. return \%retHash;
  4043. }
  4044. FRITZBOX_Log $hash, 5, "Request data via API luaQuery.";
  4045. my $host = $hash->{HOST};
  4046. my $url = 'http://' . $host . '/query.lua?sid=' . $sid . $queryStr;
  4047. #FRITZBOX_Log $hash, 3, "URL: $url";
  4048. my $agent = LWP::UserAgent->new( env_proxy => 1, keep_alive => 1, protocols_allowed => ['http'], timeout => 180);
  4049. my $response = $agent->get ( $url );
  4050. FRITZBOX_Log $hash, 5, "Response: ".$response->status_line."\n".$response->content;
  4051. unless ($response->is_success) {
  4052. my %retHash = ("Error" => $response->status_line, "ResetSID" => "1");
  4053. FRITZBOX_Log $hash, 3, "Error: ".$response->status_line;
  4054. return \%retHash;
  4055. }
  4056. if ($response->content =~ /<html>|"pid": "logout"/) {
  4057. my %retHash = ("Error" => "Old SID not valid anymore.", "ResetSID" => "1");
  4058. return \%retHash;
  4059. }
  4060. #################
  4061. # FRITZBOX_Log $hash, 3, "Response: ".$response->content;
  4062. #################
  4063. my $jsonText = $response->content;
  4064. # Remove illegal escape sequences
  4065. $jsonText =~ s/\\'/'/g; #Hochkomma
  4066. $jsonText =~ s/\\x\{[0-9a-f]\}//g; #delete control codes (as hex numbers)
  4067. FRITZBOX_Log $hash, 5, "Decode JSON string.";
  4068. my $jsonResult ;
  4069. if ($charSet eq "UTF-8") {
  4070. $jsonResult = JSON->new->utf8->decode( $jsonText );
  4071. }
  4072. else {
  4073. $jsonResult = JSON->new->latin1->decode( $jsonText );
  4074. }
  4075. $jsonResult->{sid} = $sid;
  4076. $jsonResult->{Error} = $jsonResult->{error} if defined $jsonResult->{error};
  4077. return $jsonResult;
  4078. }
  4079. #####################################
  4080. # checks and stores FritzBox password used for telnet or webinterface connection
  4081. sub FRITZBOX_storePassword($$)
  4082. {
  4083. my ($hash, $password) = @_;
  4084. my $index = $hash->{TYPE}."_".$hash->{NAME}."_passwd";
  4085. my $key = getUniqueId().$index;
  4086. my $enc_pwd = "";
  4087. if(eval "use Digest::MD5;1")
  4088. {
  4089. $key = Digest::MD5::md5_hex(unpack "H*", $key);
  4090. $key .= Digest::MD5::md5_hex($key);
  4091. }
  4092. for my $char (split //, $password)
  4093. {
  4094. my $encode=chop($key);
  4095. $enc_pwd.=sprintf("%.2x",ord($char)^ord($encode));
  4096. $key=$encode.$key;
  4097. }
  4098. my $err = setKeyValue($index, $enc_pwd);
  4099. return "error while saving the password - $err" if(defined($err));
  4100. return "password successfully saved";
  4101. } # end FRITZBOX_storePassword
  4102. #####################################
  4103. # reads the FritzBox password
  4104. sub FRITZBOX_readPassword($)
  4105. {
  4106. my ($hash) = @_;
  4107. my $name = $hash->{NAME};
  4108. my $index = $hash->{TYPE}."_".$hash->{NAME}."_passwd";
  4109. my $key = getUniqueId().$index;
  4110. my ($password, $err);
  4111. FRITZBOX_Log $hash, 5, "Read FritzBox password from file";
  4112. ($err, $password) = getKeyValue($index);
  4113. if ( defined($err) ) {
  4114. FRITZBOX_Log $hash, 4, "unable to read FritzBox password from file: $err";
  4115. return undef;
  4116. }
  4117. if ( defined($password) ) {
  4118. if ( eval "use Digest::MD5;1" ) {
  4119. $key = Digest::MD5::md5_hex(unpack "H*", $key);
  4120. $key .= Digest::MD5::md5_hex($key);
  4121. }
  4122. my $dec_pwd = '';
  4123. for my $char (map { pack('C', hex($_)) } ($password =~ /(..)/g)) {
  4124. my $decode=chop($key);
  4125. $dec_pwd.=chr(ord($char)^ord($decode));
  4126. $key=$decode.$key;
  4127. }
  4128. return $dec_pwd;
  4129. }
  4130. else {
  4131. FRITZBOX_Log $hash, 4, "No password in file";
  4132. return undef;
  4133. }
  4134. } # end FRITZBOX_readPassword
  4135. #####################################
  4136. sub FRITZBOX_fritztris($)
  4137. {
  4138. my ($d) = @_;
  4139. $d = "<none>" if(!$d);
  4140. return "$d is not a FRITZBOX instance<br>"
  4141. if(!$defs{$d} || $defs{$d}{TYPE} ne "FRITZBOX");
  4142. my $returnStr = '<script type="text/javascript" src="http://fritz.box/js/fritztris.js"></script>';
  4143. $returnStr .= '<link rel="stylesheet" type="text/css" href="http://fritz.box/css/default/fritztris.css"/>';
  4144. # $returnStr .= '<link rel="stylesheet" type="text/css" href="http://fritz.box/css/default/main.css"/>';
  4145. $returnStr .= '<link rel="stylesheet" type="text/css" href="http://fritz.box/css/default/static.css"/>';
  4146. $returnStr .= '<!--[if lte IE 8]>';
  4147. $returnStr .= '<link rel="stylesheet" type="text/css" href="http://fritz.box/css/default/ie_fix.css"/>';
  4148. $returnStr .= '<![endif]-->';
  4149. $returnStr .= '<style>#game table td {width: 10px;height: 10px;}</style>';
  4150. $returnStr .= '<script type="text/javascript">';
  4151. $returnStr .= 'var game = null;';
  4152. $returnStr .= 'function play() {';
  4153. $returnStr .= 'if (game) {';
  4154. $returnStr .= 'game.stop();';
  4155. $returnStr .= 'game = null;';
  4156. $returnStr .= '}';
  4157. $returnStr .= 'var game = new FRITZtris(document.getElementById("game"));';
  4158. $returnStr .= 'game.start();';
  4159. $returnStr .= 'game.gameOverCb = gameOver;';
  4160. $returnStr .= '}';
  4161. $returnStr .= 'function gameOver() {';
  4162. # $returnStr .= 'alert("Das Spiel ist vorbei.");';
  4163. $returnStr .= 'game.stop();';
  4164. $returnStr .= 'game = null;';
  4165. $returnStr .= '}';
  4166. $returnStr .= '</script>';
  4167. $returnStr .= '<table><tr><td valign=top><u><b>FritzTris</b></u>';
  4168. $returnStr .= '<br><a href="#" onclick="play();">Start</a>';
  4169. $returnStr .= '<br><a href="#" onclick="gameOver();">Stop</a></td>';
  4170. $returnStr .= '<td><div id="page_content" class="page_content">';
  4171. $returnStr .= '<div id="game" style="background:white;"></div></div></td></tr></table>';
  4172. return $returnStr;
  4173. }
  4174. #####################################
  4175. #{my @cmd;; $cmd=webCmdArray, "active" => "on";
  4176. # FRITZBOX_Web_CmdPost ($hash, \@webCmdArray, '/wlan/wlan_settings.lua');
  4177. # <li><code>set &lt;name&gt; convertRingTone &lt;fullFilePath&gt;</code>
  4178. # <br>
  4179. # Converts the mp3-file fullFilePath to the G722 format and puts it in the same path.
  4180. # <br>
  4181. # The file has to be placed on the file system of the Fritz!Box.
  4182. # </li><br>
  4183. # <li><code>set &lt;name&gt; convertMusicOnHold &lt;fullFilePath&gt;</code>
  4184. # <br>
  4185. # <i>Not implemented yet.</i> Converts the mp3-file fullFilePath to a format that can be used for "Music on Hold".
  4186. # <br>
  4187. # The file has to be placed on the file system of the fritzbox.
  4188. # </li><br>
  4189. # <li><code>set &lt;name&gt; convertRingTone &lt;fullFilePath&gt;</code>
  4190. # <br>
  4191. # Konvertiert die mp3-Datei fullFilePath in das G722-Format und legt es im selben Pfad ab.
  4192. # <br>
  4193. # Die Datei muss im Dateisystem der Fritz!Box liegen.
  4194. # </li><br>
  4195. # <li><code>set &lt;name&gt; convertMusicOnHold &lt;fullFilePath&gt;</code>
  4196. # <br>
  4197. # <i>Not implemented yet.</i> Converts the mp3-file fullFilePath to a format that can be used for "Music on Hold".
  4198. # <br>
  4199. # The file has to be placed on the file system of the fritzbox.
  4200. # </li><br>
  4201. 1;
  4202. =pod
  4203. =item device
  4204. =item summary Controls some features of a Fritz!Box router and Fritz!Fon.
  4205. =item summary_DE Steuert gewisse Funktionen eines Fritz!Box Routers und verbundene Fritz!Fon.
  4206. =begin html
  4207. <a name="FRITZBOX"></a>
  4208. <h3>FRITZBOX</h3>
  4209. <div>
  4210. <ul>
  4211. Controls some features of a Fritz!Box router. Connected Fritz!Fon's (MT-F, MT-D, C3, C4) can be used as
  4212. signaling devices. MP3 files and Text2Speech can be played as ring tone or when calling phones.
  4213. <br>
  4214. For detail instructions, look at and please maintain the <a href="http://www.fhemwiki.de/wiki/FRITZBOX"><b>FHEM-Wiki</b></a>.
  4215. <br/><br/>
  4216. The modul switches in local mode if FHEM runs on a Fritz!Box (as root user!). Otherwise, it tries to open a web or telnet connection to "fritz.box", so telnet (#96*7*) has to be enabled on the Fritz!Box. For remote access the password must <u>once</u> be set.
  4217. <br/><br/>
  4218. The box is partly controlled via the official TR-064 interface but also via undocumented interfaces between web interface and firmware kernel. The modul works best with Fritz!OS 6.24. AVM has removed internal interfaces (telnet, webcm) from later Fritz!OS versions without replacement. <b>For these versions, some modul functions are hence restricted or do not work at all (see remarks to required API).</b>
  4219. <br>
  4220. The modul was tested on Fritz!Box 7390 and 7490 with Fritz!OS 6.20 and higher.
  4221. <br>
  4222. Check also the other Fritz!Box moduls: <a href="#SYSMON">SYSMON</a> and <a href="#FB_CALLMONITOR">FB_CALLMONITOR</a>.
  4223. <br>
  4224. <i>The modul uses the Perl modul 'Net::Telnet', 'JSON::XS', 'LWP', 'SOAP::Lite' for remote access.</i>
  4225. <br/><br/>
  4226. <a name="FRITZBOXdefine"></a>
  4227. <b>Define</b>
  4228. <ul>
  4229. <br>
  4230. <code>define &lt;name&gt; FRITZBOX [host]</code>
  4231. <br/>
  4232. The attribute <i>host</i> is the web address (name or IP) of the Fritz!Box. If it is missing, the modul switches in local mode or uses the default host address "fritz.box".
  4233. <br/><br/>
  4234. Example: <code>define Fritzbox FRITZBOX</code>
  4235. <br/><br/>
  4236. The FritzOS has a hidden function (easter egg).
  4237. <br>
  4238. <code>define MyEasterEgg weblink htmlCode { FRITZBOX_fritztris("Fritzbox") }</code>
  4239. <br/><br/>
  4240. </ul>
  4241. <a name="FRITZBOXset"></a>
  4242. <b>Set</b>
  4243. <ul>
  4244. <br>
  4245. <li><code>set &lt;name&gt; alarm &lt;number&gt; [on|off] [time] [once|daily|Mo|Tu|We|Th|Fr|Sa|So]</code>
  4246. <br>
  4247. Switches the alarm number (1, 2 or 3) on or off (default is on). Sets the time and weekday. If no state is given it is switched on.
  4248. <br>
  4249. Requires the API: Telnet or webcm.
  4250. </li><br>
  4251. <li><code>set &lt;name&gt; call &lt;number&gt; [duration] [say:text|play:MP3URL]</code>
  4252. <br>
  4253. Calls for 'duration' seconds (default 60) the given number from an internal port (default 1 or attribute 'ringWithIntern'). If the call is taken a text or sound can be played as music on hold (moh). The internal port will also ring.
  4254. Say and play requires the API: Telnet or webcm.
  4255. </li><br>
  4256. <li><code>set &lt;name&gt; checkAPIs</code>
  4257. <br>
  4258. Restarts the initial check of the programming interfaces of the FRITZ!BOX.
  4259. </li><br>
  4260. <li><code>set &lt;name&gt; customerRingTone &lt;internalNumber&gt; &lt;fullFilePath&gt;</code>
  4261. <br>
  4262. Uploads the file fullFilePath on the given handset. Only mp3 or G722 format is allowed.
  4263. <br>
  4264. The file has to be placed on the file system of the fritzbox.
  4265. <br>
  4266. The upload takes about one minute before the tone is available.
  4267. </li><br>
  4268. <li><code>set &lt;name&gt; dect &lt;on|off&gt;</code>
  4269. <br>
  4270. Switches the DECT base of the box on or off. Requires the API: Telnet or webcm.
  4271. </li><br>
  4272. <li><code>set &lt;name&gt; diversity &lt;number&gt; &lt;on|off&gt;</code>
  4273. <br>
  4274. Switches the call diversity number (1, 2 ...) on or off.
  4275. A call diversity for an incoming number has to be created with the Fritz!Box web interface. Requires the API: Telnet, webcm or TR064 (>=6.50).
  4276. <br>
  4277. Note! Only a diversity for a concret home number and <u>without</u> filter for the calling number can be set. Hence, an approbriate <i>diversity</i>-reading must exist.
  4278. </li><br>
  4279. <li><code>set &lt;name&gt; guestWLAN &lt;on|off&gt;</code>
  4280. <br>
  4281. Switches the guest WLAN on or off. The guest password must be set. If necessary, the normal WLAN is also switched on.
  4282. </li><br>
  4283. <li><code>set &lt;name&gt; moh &lt;default|sound|customer&gt; [&lt;MP3FileIncludingPath|say:Text&gt;]</code>
  4284. <br>
  4285. Example: <code>set fritzbox moh customer say:Die Wanne ist voll</code>
  4286. <br>
  4287. <code>set fritzbox moh customer /var/InternerSpeicher/warnung.mp3</code>
  4288. <br>
  4289. Changes the 'music on hold' of the Box. The parameter 'customer' allows to upload a mp3 file. Alternatively a text can be spoken with "say:". The music on hold has <u>always</u> a length of 8.2 s. It is played continousely during the broking of calls or if the modul rings a phone and the call is taken. So, it can be used to transmit little messages of 8 s.
  4290. <br>
  4291. </li><br>
  4292. <li><code>set &lt;name&gt; password &lt;password&gt;</code>
  4293. <br>
  4294. Stores the password for remote telnet access.
  4295. </li><br>
  4296. <li><code>set &lt;name&gt; ring &lt;intNumbers&gt; [duration [ringTone]] [show:Text] [say:Text | play:MP3URL]</code>
  4297. <dt>Example:</dt>
  4298. <dd>
  4299. <code>set fritzbox ring 611,612 5 Budapest show:It is raining</code>
  4300. <br>
  4301. <code>set fritzbox ring 611 8 say:(en)It is raining</code>
  4302. <br>
  4303. <code>set fritzbox ring 610 10 play:http://raspberrypi/sound.mp3</code>
  4304. </dd>
  4305. Rings the internal numbers for "duration" seconds and (on Fritz!Fons) with the given "ring tone" name.
  4306. Different internal numbers have to be separated by a comma (without spaces).
  4307. <br>
  4308. Default duration is 5 seconds. The Fritz!Box can create further delays. Default ring tone is the internal ring tone of the device.
  4309. Ring tone will be ignored for collected calls (9 or 50).
  4310. <br>
  4311. If the call is taken the callee hears the "music on hold" which can also be used to transmit messages.
  4312. <br>
  4313. The parameter <i>ringtone, show:, say:</i> and <i>play:</i> require the API Telnet or webcm.
  4314. <br/><br/>
  4315. If the <a href=#FRITZBOXattr>attribute</a> 'ringWithIntern' is specified, the text behind 'show:' will be shown as the callers name.
  4316. Maximal 30 characters are allowed.
  4317. <br/><br/>
  4318. On Fritz!Fons the parameter 'say:' can be used to let the phone speak a message (max. 100 characters) instead of using the ringtone.
  4319. Alternatively, a MP3 link (from a web server) can be played with 'play:'. This creates the internet radio station 'FHEM' and uses translate.google.com for text2speech. It will <u>always</u> play the complete text/sound. It will than ring with standard ring tone until the end of the 'ring duration' is reached.
  4320. Say and play <u>may</u> work only with one single Fritz!Fon at a time.
  4321. <br>
  4322. The behaviour may vary depending on the Fritz!OS.
  4323. </li><br>
  4324. <li><code>set &lt;name&gt; sendMail [to:&lt;Address&gt;] [subject:&lt;Subject&gt;] [body:&lt;Text&gt;]</code>
  4325. <br>
  4326. Sends an email via the email notification service that is configured in push service of the Fritz!Box.
  4327. Use "\n" for line breaks in the body.
  4328. All parameters can be omitted. Make sure the messages are not classified as junk by your email client.
  4329. <br>
  4330. Requires Telnet access to the box.
  4331. <br>
  4332. </li><br>
  4333. <li><code>set &lt;name&gt; startRadio &lt;internalNumber&gt; [name or number]</code>
  4334. <br>
  4335. Plays the internet radio on the given Fritz!Fon. Default is the current <u>ring tone</u> radio station of the phone.
  4336. So, <b>not</b> the station that is selected at the handset.
  4337. An available internet radio can be selected by its name or (reading) number.
  4338. <br>
  4339. </li><br>
  4340. <li><code>set &lt;name&gt; tam &lt;number&gt; &lt;on|off&gt;</code>
  4341. <br>
  4342. Switches the answering machine number (1, 2 ...) on or off.
  4343. The answering machine has to be created on the Fritz!Box web interface.
  4344. </li><br>
  4345. <li><code>set &lt;name&gt; update</code>
  4346. <br>
  4347. Starts an update of the device readings.
  4348. </li><br>
  4349. <li><code>set &lt;name&gt; wlan &lt;on|off&gt;</code>
  4350. <br>
  4351. Switches WLAN on or off.
  4352. </li><br>
  4353. </ul>
  4354. <a name="FRITZBOXget"></a>
  4355. <b>Get</b>
  4356. <ul>
  4357. <br>
  4358. <li><code>get &lt;name&gt; ringTones</code>
  4359. <br>
  4360. Shows the list of ring tones that can be used.
  4361. </li><br>
  4362. <li><code>get &lt;name&gt; shellCommand &lt;Command&gt;</code>
  4363. <br>
  4364. Runs the given command on the Fritz!Box shell and returns the result.
  4365. Can be used to run shell commands not included in this modul.
  4366. <br>
  4367. Only available if the attribute "allowShellCommand" is set.
  4368. </li><br>
  4369. <li><code>get &lt;name&gt; tr064Command &lt;service&gt; &lt;control&gt; &lt;action&gt; [[argName1 argValue1] ...] </code>
  4370. <br>
  4371. Executes TR-064 actions (see <a href="http://avm.de/service/schnittstellen/">API description</a> of AVM).
  4372. <br>
  4373. argValues with spaces have to be enclosed in quotation marks.
  4374. <br>
  4375. Example: <code>get Fritzbox tr064Command X_AVM-DE_OnTel:1 x_contact GetDECTHandsetInfo NewDectID 1</code>
  4376. <br>
  4377. Only available if the attribute "allowTR064Command" is set.
  4378. </li><br>
  4379. <li><code>get &lt;name&gt; tr064ServiceListe</code>
  4380. <br>
  4381. Shows a list of TR-064 services and actions that are allowed on the device.
  4382. </li><br>
  4383. </ul>
  4384. <a name="FRITZBOXattr"></a>
  4385. <b>Attributes</b>
  4386. <ul>
  4387. <br>
  4388. <li><code>allowShellCommand &lt;0 | 1&gt;</code>
  4389. <br>
  4390. Enables the get command "shellCommand"
  4391. </li><br>
  4392. <li><code>allowTR064Command &lt;0 | 1&gt;</code>
  4393. <br>
  4394. Enables the get command "tr064Command"
  4395. </li><br>
  4396. <li><code>boxUser &lt;user name&gt;</code>
  4397. <br>
  4398. User name that is used for TR064 or other web based access. By default no user name is required to login.
  4399. <br>
  4400. If the Fritz!Box is configured differently, the user name has to be defined with this attribute.
  4401. </li><br>
  4402. <li><code>defaultCallerName &lt;Text&gt;</code>
  4403. <br>
  4404. The default text to show on the ringing phone as 'caller'.
  4405. <br>
  4406. This is done by temporarily changing the name of the calling internal number during the ring.
  4407. <br>
  4408. Maximal 30 characters are allowed. The attribute "ringWithIntern" must also be specified.
  4409. <br>
  4410. Required API: Telnet or webcmd
  4411. </li><br>
  4412. <li><code>defaultUploadDir &lt;fritzBoxPath&gt;</code>
  4413. <br>
  4414. This is the default path that will be used if a file name does not start with / (slash).
  4415. <br>
  4416. It needs to be the name of the path on the Fritz!Box. So, it should start with /var/InternerSpeicher if it equals in Windows \\ip-address\fritz.nas
  4417. </li><br>
  4418. <li><code>forceTelnetConnection &lt;0 | 1&gt;</code>
  4419. <br>
  4420. Always use telnet for remote access (instead of access via the WebGUI or TR-064).
  4421. <br>
  4422. This attribute should be enabled for older boxes/firmwares.
  4423. </li><br>
  4424. <li><code>fritzBoxIP &lt;IP Address&gt;</code>
  4425. <br>
  4426. Depreciated.
  4427. </li><br>
  4428. <li><code>INTERVAL &lt;seconds&gt;</code>
  4429. <br>
  4430. Polling-Interval. Default is 300 (seconds). Smallest possible value is 60.
  4431. </li><br>
  4432. <li><code>m3uFileLocal &lt;/path/fileName&gt;</code>
  4433. <br>
  4434. Can be used as a work around if the ring tone of a Fritz!Fon cannot be changed because of firmware restrictions (missing telnet or webcm).
  4435. <br>
  4436. How it works: If the FHEM server has also a web server running, the FritzFon can play a m3u file from this web server as an internet radio station.
  4437. For this an internet radio station on the FritzFon must point to the server URL of this file and the internal ring tone must be changed to that station.
  4438. <br>
  4439. If the attribute is set, the server file "m3uFileLocal" (local address of the FritzFon URL) will be filled with the URL of the text2speech engine (say:) or a MP3-File (play:). The FritzFon will then play this URL.
  4440. </li><br>
  4441. <li><code>ringWithIntern &lt;1 | 2 | 3&gt;</code>
  4442. <br>
  4443. To ring a fon a caller must always be specified. Default of this modul is 50 "ISDN:W&auml;hlhilfe".
  4444. <br>
  4445. To show a message (default: "FHEM") during a ring the internal phone numbers 1-3 can be specified here.
  4446. The concerned analog phone socket <u>must</u> exist.
  4447. </li><br>
  4448. <li><code>telnetTimeOut &lt;seconds&gt;</code>
  4449. <br>
  4450. Maximal time to wait for an answer during a telnet session. Default is 10 s.
  4451. </li><br>
  4452. <li><code>telnetUser &lt;user name&gt;</code>
  4453. <br>
  4454. User name that is used for telnet access. By default no user name is required to login.
  4455. <br>
  4456. If the Fritz!Box is configured differently, the user name has to be defined with this attribute.
  4457. </li><br>
  4458. <li><code>useGuiHack &lt;0 | 1&gt;</code>
  4459. <br>
  4460. If the APIs do not allow the change of the ring tone (Fritz!OS >6.24), check the <a href="http://www.fhemwiki.de/wiki/FRITZBOX#Klingelton-Einstellung_und_Abspielen_von_Sprachnachrichten_bei_Fritz.21OS-Versionen_.3E6.24">WIKI</a> (German) to understand the use of this attribute.
  4461. </li><br>
  4462. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  4463. </ul>
  4464. <br>
  4465. <a name="FRITZBOXreading"></a>
  4466. <b>Readings</b>
  4467. <ul><br>
  4468. <li><b>alarm</b><i>1</i> - Name of the alarm clock <i>1</i></li>
  4469. <li><b>alarm</b><i>1</i><b>_state</b> - Current state of the alarm clock <i>1</i></li>
  4470. <li><b>alarm</b><i>1</i><b>_target</b> - Internal number of the alarm clock <i>1</i></li>
  4471. <li><b>alarm</b><i>1</i><b>_time</b> - Alarm time of the alarm clock <i>1</i></li>
  4472. <li><b>alarm</b><i>1</i><b>_wdays</b> - Weekdays of the alarm clock <i>1</i></li>
  4473. <br>
  4474. <li><b>box_dect</b> - Current state of the DECT base</li>
  4475. <li><b>box_fwVersion</b> - Firmware version of the box, if outdated then '(old)' is appended</li>
  4476. <li><b>box_guestWlan</b> - Current state of the guest WLAN</li>
  4477. <li><b>box_guestWlanCount</b> - Number of devices connected to guest WLAN</li>
  4478. <li><b>box_guestWlanRemain</b> - Remaining time until the guest WLAN is switched off</li>
  4479. <li><b>box_ipExtern</b> - Internet IP of the Fritz!Box</li>
  4480. <li><b>box_model</b> - Fritz!Box model</li>
  4481. <li><b>box_moh</b> - music-on-hold setting</li>
  4482. <li><b>box_model</b> - Fritz!Box model</li>
  4483. <li><b>box_powerRate</b> - current power in percent of maximal power</li>
  4484. <li><b>box_rateDown</b> - average download rate in the last update interval</li>
  4485. <li><b>box_rateUp</b> - average upload rate in the last update interval</li>
  4486. <li><b>box_stdDialPort</b> - standard caller port when using the dial function of the box</li>
  4487. <li><b>box_tr064</b> - application interface TR-064 (needed by this modul)</li>
  4488. <li><b>box_tr069</b> - provider remote access TR-069 (safety issue!)</li>
  4489. <li><b>box_wlanCount</b> - Number of devices connected via WLAN</li>
  4490. <li><b>box_wlan_2.4GHz</b> - Current state of the 2.4 GHz WLAN</li>
  4491. <li><b>box_wlan_5GHz</b> - Current state of the 5 GHz WLAN</li>
  4492. <br>
  4493. <li><b>dect</b><i>1</i> - Name of the DECT device <i>1</i></li>
  4494. <li><b>dect</b><i>1</i><b>_alarmRingTone</b> - Alarm ring tone of the DECT device <i>1</i></li>
  4495. <li><b>dect</b><i>1</i><b>_custRingTone</b> - Customer ring tone of the DECT device <i>1</i></li>
  4496. <li><b>dect</b><i>1</i><b>_fwVersion</b> - Firmware Version of the DECT device <i>1</i></li>
  4497. <li><b>dect</b><i>1</i><b>_intern</b> - Internal number of the DECT device <i>1</i></li>
  4498. <li><b>dect</b><i>1</i><b>_intRingTone</b> - Internal ring tone of the DECT device <i>1</i></li>
  4499. <li><b>dect</b><i>1</i><b>_manufacturer</b> - Manufacturer of the DECT device <i>1</i></li>
  4500. <li><b>dect</b><i>1</i><b>_model</b> - Model of the DECT device <i>1</i></li>
  4501. <li><b>dect</b><i>1</i><b>_radio</b> - Current internet radio station ring tone of the DECT device <i>1</i></li>
  4502. <br>
  4503. <li><b>diversity</b><i>1</i> - Own (incoming) phone number of the call diversity <i>1</i></li>
  4504. <li><b>diversity</b><i>1</i><b>_dest</b> - Destination of the call diversity <i>1</i></li>
  4505. <li><b>diversity</b><i>1</i><b>_state</b> - Current state of the call diversity <i>1</i></li>
  4506. <br>
  4507. <li><b>fon</b><i>1</i> - Internal name of the analog FON port <i>1</i></li>
  4508. <li><b>fon</b><i>1</i><b>_intern</b> - Internal number of the analog FON port <i>1</i></li>
  4509. <li><b>fon</b><i>1</i><b>_out</b> - Outgoing number of the analog FON port <i>1</i></li>
  4510. <br>
  4511. <li><b>gsm_internet</b> - connection to internet established via GSM stick</li>
  4512. <li><b>gsm_rssi</b> - received signal strength indication (0-100)</li>
  4513. <li><b>gsm_state</b> - state of the connection to the GSM network</li>
  4514. <li><b>gsm_technology</b> - GSM technology used for data transfer (GPRS, EDGE, UMTS, HSPA)</li>
  4515. <br>
  4516. <li><b>mac_</b><i>01_26_FD_12_01_DA</i> - MAC address and name of an active network device.
  4517. <br>
  4518. If connect via WLAN, the term "WLAN" and (from boxes point of view) the down- and upload rate and the signal strength is added. For LAN devices the LAN port and its speed is added. Inactive or removed devices get first the value "inactive" and will be deleted during the next update.</li>
  4519. <br>
  4520. <li><b>radio</b><i>01</i> - Name of the internet radio station <i>01</i></li>
  4521. <br>
  4522. <li><b>tam</b><i>1</i> - Name of the answering machine <i>1</i></li>
  4523. <li><b>tam</b><i>1</i><b>_newMsg</b> - New messages on the answering machine <i>1</i></li>
  4524. <li><b>tam</b><i>1</i><b>_oldMsg</b> - Old messages on the answering machine <i>1</i></li>
  4525. <li><b>tam</b><i>1</i><b>_state</b> - Current state of the answering machine <i>1</i></li>
  4526. <br>
  4527. <li><b>user</b><i>01</i> - Name of user/IP <i>1</i> that is under parental control</li>
  4528. <li><b>user</b><i>01</i>_thisMonthTime - this month internet usage of user/IP <i>1</i> (parental control)</li>
  4529. <li><b>user</b><i>01</i>_todaySeconds - today's internet usage in seconds of user/IP <i>1</i> (parental control)</li>
  4530. <li><b>user</b><i>01</i>_todayTime - today's internet usage of user/IP <i>1</i> (parental control)</li>
  4531. </ul>
  4532. <br>
  4533. </ul>
  4534. </div>
  4535. =end html
  4536. =begin html_DE
  4537. <a name="FRITZBOX"></a>
  4538. <h3>FRITZBOX</h3>
  4539. <div>
  4540. <ul>
  4541. Steuert gewisse Funktionen eines Fritz!Box Routers. Verbundene Fritz!Fon's (MT-F, MT-D, C3, C4) k&ouml;nnen als Signalger&auml;te genutzt werden. MP3-Dateien und Text (Text2Speech) k&ouml;nnen als Klingelton oder einem angerufenen Telefon abgespielt werden.
  4542. <br>
  4543. F&uuml;r detailierte Anleitungen bitte die <a href="http://www.fhemwiki.de/wiki/FRITZBOX"><b>FHEM-Wiki</b></a> konsultieren und erg&auml;nzen.
  4544. <br/><br/>
  4545. Das Modul schaltet in den lokalen Modus, wenn FHEM auf einer Fritz!Box l&auml;uft (als root-Benutzer!). Ansonsten versucht es eine Web oder Telnet Verbindung zu "fritz.box" zu &ouml;ffnen. D.h. Telnet (#96*7*) muss auf der Fritz!Box erlaubt sein. F&uuml;r diesen Fernzugriff muss <u>einmalig</u> das Passwort gesetzt werden.
  4546. <br/><br/>
  4547. Die Steuerung erfolgt teilweise &uuml;ber die offizielle TR-064-Schnittstelle und teilweise &uuml;ber undokumentierte Schnittstellen zwischen Webinterface und Firmware Kern. Das Modul funktioniert am besten mit dem Fritz!OS 6.24. Bei den nachfolgenden Fritz!OS Versionen hat AVM einige interne Schnittstellen (telnet, webcm) ersatzlos gestrichen. <b>Einige Modul-Funktionen sind dadurch nicht oder nur eingeschr&auml;nkt verf&uuml;gbar (siehe Anmerkungen zu ben&ouml;tigten API).</b>
  4548. <br>
  4549. Bitte auch die anderen Fritz!Box-Module beachten: <a href="#SYSMON">SYSMON</a> und <a href="#FB_CALLMONITOR">FB_CALLMONITOR</a>.
  4550. <br>
  4551. <i>Das Modul nutzt das Perlmodule 'Net::Telnet', 'JSON::XS', 'LWP', 'SOAP::Lite' f&uuml;r den Fernzugriff.</i>
  4552. <br/><br/>
  4553. <a name="FRITZBOXdefine"></a>
  4554. <b>Define</b>
  4555. <ul>
  4556. <br>
  4557. <code>define &lt;name&gt; FRITZBOX [host]</code>
  4558. <br/>
  4559. Das Attribut <i>host</i> ist die Web-Adresse (Name oder IP) der Fritz!Box. Fehlt es, so schaltet das Modul in den lokalen Modus oder nutzt die Standardadresse "fritz.box".
  4560. <br/><br/>
  4561. Beispiel: <code>define Fritzbox FRITZBOX</code>
  4562. <br/><br/>
  4563. Das FritzOS hat eine versteckte Funktion (Osterei).
  4564. <br>
  4565. <code>define MyEasterEgg weblink htmlCode { FRITZBOX_fritztris("Fritzbox") }</code>
  4566. <br/><br/>
  4567. </ul>
  4568. <a name="FRITZBOXset"></a>
  4569. <b>Set</b>
  4570. <ul>
  4571. <br>
  4572. <li><code>set &lt;name&gt; alarm &lt;Nummer&gt; [on|off] [time] [once|daily|Mo|Tu|We|Th|Fr|Sa|So]</code>
  4573. <br>
  4574. Schaltet den Weckruf Nummer 1, 2 oder 3 an oder aus (Standard ist on). Setzt die Zeit und den Wochentag.
  4575. <br>
  4576. Ben&ouml;tigt die API: Telnet oder webcm.
  4577. </li><br>
  4578. <li><code>set &lt;name&gt; call &lt;number&gt; [Dauer] [say:Text|play:MP3URL]</code>
  4579. <br>
  4580. Ruf f&uuml;r 'Dauer' Sekunden (Standard 60 s) die angegebene Telefonnummer von einem internen Telefonanschluss an (Standard ist 1 oder das Attribut 'ringWithIntern'). Wenn der Angerufene abnimmt, h&ouml;rt er die Wartemusik oder den angegebenen Text oder Klang.
  4581. Der interne Telefonanschluss klingelt ebenfalls.
  4582. <br>
  4583. "say:" und "play:" ben&ouml;tigen die API: Telnet oder webcm.
  4584. </li><br>
  4585. <li><code>set &lt;name&gt; checkAPIs</code>
  4586. <br>
  4587. Startet eine erneute Abfrage der exitierenden Programmierschnittstellen der FRITZ!BOX.
  4588. </li><br>
  4589. <li><code>set &lt;name&gt; customerRingTone &lt;internalNumber&gt; &lt;MP3DateiInklusivePfad&gt;</code>
  4590. <br>
  4591. L&auml;dt die MP3-Datei als Klingelton auf das angegebene Telefon. Die Datei muss im Dateisystem der Fritzbox liegen.
  4592. <br>
  4593. Das Hochladen dauert etwa eine Minute bis der Klingelton verf&uuml;gbar ist. (API: Telnet)
  4594. </li><br>
  4595. <li><code>set &lt;name&gt; dect &lt;on|off&gt;</code>
  4596. <br>
  4597. Schaltet die DECT-Basis der Box an oder aus.
  4598. <br>
  4599. Ben&ouml;tigt die API: Telnet oder webcm.
  4600. </li><br>
  4601. <li><code>set &lt;name&gt; diversity &lt;number&gt; &lt;on|off&gt;</code>
  4602. <br>
  4603. Schaltet die Rufumleitung (Nummer 1, 2 ...) f&uuml;r einzelne Rufnummern an oder aus.
  4604. <br>
  4605. Die Rufumleitung muss zuvor auf der Fritz!Box eingerichtet werden. Ben&ouml;tigt die API: Telnet oder webcm.
  4606. <br>
  4607. Achtung! Es lassen sich nur Rufumleitungen f&uuml;r einzelne angerufene Telefonnummern (also nicht "alle") und <u>ohne</u> Abh&auml;ngigkeit von der anrufenden Nummer schalten.
  4608. Es muss also ein <i>diversity</i>-Ger&auml;wert geben.
  4609. <br>
  4610. Ben&ouml;tigt die API: Telnet, webcm oder TR064 (>=6.50).
  4611. </li><br>
  4612. <li><code>set &lt;name&gt; guestWLAN &lt;on|off&gt;</code>
  4613. <br>
  4614. Schaltet das G&auml;ste-WLAN an oder aus. Das G&auml;ste-Passwort muss gesetzt sein. Wenn notwendig wird auch das normale WLAN angeschaltet.
  4615. </li><br>
  4616. <li><code>set &lt;name&gt; moh &lt;default|sound|customer&gt; [&lt;MP3DateiInklusivePfad|say:Text&gt;]</code>
  4617. <br>
  4618. Beispiel: <code>set fritzbox moh customer say:Die Wanne ist voll</code>
  4619. <br>
  4620. <code>set fritzbox moh customer /var/InternerSpeicher/warnung.mp3</code>
  4621. <br>
  4622. &Auml;ndert die Wartemusik ('music on hold') der Box. Mit dem Parameter 'customer' kann eine eigene MP3-Datei aufgespielt werden.
  4623. Alternativ kann mit "say:" auch ein Text gesprochen werden. Die Wartemusik hat <u>immer</u> eine L&auml;nge von 8,13 s. Sie wird kontinuierlich w&auml;hrend des Makelns von Gespr&auml;chen aber auch bei Nutzung der internen W&auml;hlhilfe bis zum Abheben des rufenden Telefons abgespielt. Dadurch k&ouml;nnen &uuml;ber FHEM dem Angerufenen 8s-Nachrichten vorgespielt werden.
  4624. <br>
  4625. </li><br>
  4626. <li><code>set &lt;name&gt; password &lt;Passwort&gt;</code>
  4627. <br>
  4628. Speichert das Passwort f&uuml;r den Fernzugriff &uuml;ber Telnet.
  4629. </li><br>
  4630. <li><code>set &lt;name&gt; ring &lt;intNummern&gt; [Dauer [Klingelton]] [show:Text] [say:Text | play:Link]</code>
  4631. <dt>Beispiel:</dt>
  4632. <dd>
  4633. <code>set fritzbox ring 611,612 5 Budapest show:Es regnet</code>
  4634. <br>
  4635. <code>set fritzbox ring 610 8 say:Es regnet</code>
  4636. <br>
  4637. <code>set fritzbox ring 610 10 play:http://raspberrypi/sound.mp3</code>
  4638. </dd>
  4639. L&auml;sst die internen Nummern f&uuml;r "Dauer" Sekunden und (auf Fritz!Fons) mit dem angegebenen "Klingelton" klingeln.
  4640. <br>
  4641. Mehrere interne Nummern m&uuml;ssen durch ein Komma (ohne Leerzeichen) getrennt werden.
  4642. <br>
  4643. Standard-Dauer ist 5 Sekunden. Es kann aber zu Verz&ouml;gerungen in der Fritz!Box kommen. Standard-Klingelton ist der interne Klingelton des Ger&auml;tes.
  4644. Der Klingelton wird f&uuml;r Rundrufe (9 oder 50) ignoriert.
  4645. <br>
  4646. Wenn der Anruf angenommen wird, h&ouml;rt der Angerufene die Wartemusik (music on hold), welche ebenfalls zur Nachrichten&uuml;bermittlung genutzt werden kann.
  4647. <br>
  4648. Die Parameter <i>Klingelton, show:, say:</i> und <i>play:</i> ben&ouml;tigen die API Telnet oder webcm.
  4649. <br/><br/>
  4650. Wenn das <a href=#FRITZBOXattr>Attribut</a> 'ringWithIntern' existiert, wird der Text hinter 'show:' als Name des Anrufers angezeigt.
  4651. Er darf maximal 30 Zeichen lang sein.
  4652. <br/><br/>
  4653. Auf Fritz!Fons wird der Text (max. 100 Zeichen) hinter dem Parameter 'say:' direkt angesagt und ersetzt den Klingelton.
  4654. <br>
  4655. Alternativ kann mit 'play:' auch ein MP3-Link (vom einem Webserver) abgespielt werden. Dabei wird die Internetradiostation 39 'FHEM' erzeugt und translate.google.com f&uuml;r Text2Speech genutzt. Es wird <u>immer</u> der komplette Text/Klang abgespielt. Bis zum Ende der 'Klingeldauer' klingelt das Telefon dann mit seinem Standard-Klingelton.
  4656. Das Abspielen ist eventuell nicht auf mehreren Fritz!Fons gleichzeitig m&ouml;glich.
  4657. <br>
  4658. Je nach Fritz!OS kann das beschriebene Verhalten abweichen.
  4659. <br>
  4660. </li><br>
  4661. <li><code>set &lt;name&gt; sendMail [to:&lt;Address&gt;] [subject:&lt;Subject&gt;] [body:&lt;Text&gt;]</code>
  4662. <br>
  4663. Sendet eine Email &uuml;ber den Emailbenachrichtigungsservice der als Push Service auf der Fritz!Box konfiguriert wurde.
  4664. Mit "\n" kann einen Zeilenumbruch im Textk&ouml;rper erzeut werden.
  4665. Alle Parameter k&ouml;nnen ausgelassen werden. Bitte kontrolliert, dass die Email nicht im Junk-Verzeichnis landet.
  4666. <br>
  4667. Ben&ouml;tigt einen Telnet Zugang zur Box.
  4668. <br>
  4669. </li><br>
  4670. <li><code>set &lt;name&gt; startRadio &lt;internalNumber&gt; [Name oder Nummer]</code>
  4671. <br>
  4672. Startet das Internetradio auf dem angegebenen Fritz!Fon. Eine verf&uuml;gbare Radiostation kann &uuml;ber den Namen oder die (Ger&auml;tewert)Nummer ausgew&auml;hlt werden. Ansonsten wird die in der Box als Internetradio-Klingelton eingestellte Station abgespielt. (Also <b>nicht</b> die am Telefon ausgew&auml;hlte.)
  4673. <br>
  4674. </li><br>
  4675. <li><code>set &lt;name&gt; tam &lt;number&gt; &lt;on|off&gt;</code>
  4676. <br>
  4677. Schaltet den Anrufbeantworter (Nummer 1, 2 ...) an oder aus.
  4678. Der Anrufbeantworter muss zuvor auf der Fritz!Box eingerichtet werden.
  4679. </li><br>
  4680. <li><code>set &lt;name&gt; update</code>
  4681. <br>
  4682. Startet eine Aktualisierung der Ger&auml;tewerte.
  4683. </li><br>
  4684. <li><code>set &lt;name&gt; wlan &lt;on|off&gt;</code>
  4685. <br>
  4686. Schaltet WLAN an oder aus.
  4687. </li><br>
  4688. </ul>
  4689. <a name="FRITZBOXget"></a>
  4690. <b>Get</b>
  4691. <ul>
  4692. <br>
  4693. <li><code>get &lt;name&gt; ringTones</code>
  4694. <br>
  4695. Zeigt die Liste der Klingelt&ouml;ne, die benutzt werden k&ouml;nnen.
  4696. </li><br>
  4697. <li><code>get &lt;name&gt; shellCommand &lt;Befehl&gt;</code>
  4698. <br>
  4699. F&uuml;hrt den angegebenen Befehl auf der Fritz!Box-Shell aus und gibt das Ergebnis zur&uuml;ck.
  4700. Kann benutzt werden, um Shell-Befehle auszuf&uuml;hren, die nicht im Modul implementiert sind.
  4701. <br>
  4702. Muss zuvor &uuml;ber das Attribute "allowShellCommand" freigeschaltet werden.
  4703. </li><br>
  4704. <li><code>get &lt;name&gt; tr064Command &lt;service&gt; &lt;control&gt; &lt;action&gt; [[argName1 argValue1] ...] </code>
  4705. <br>
  4706. F&uuml;hrt &uuml;ber TR-064 Aktionen aus (siehe <a href="http://avm.de/service/schnittstellen/">Schnittstellenbeschreibung</a> von AVM).
  4707. <br>
  4708. argValues mit Leerzeichen m&uuml;ssen in Anf&uuml;hrungszeichen eingeschlossen werden.
  4709. <br>
  4710. Beispiel: <code>get Fritzbox tr064Command X_AVM-DE_OnTel:1 x_contact GetDECTHandsetInfo NewDectID 1</code>
  4711. <br>
  4712. Muss zuvor &uuml;ber das Attribute "allowTR064Command" freigeschaltet werden.
  4713. </li><br>
  4714. <li><code>get &lt;name&gt; tr064ServiceListe</code>
  4715. <br>
  4716. Zeigt die Liste der TR-064-Dienste und Aktionen, die auf dem Ger&auml;t erlaubt sind.
  4717. </li><br>
  4718. </ul>
  4719. <a name="FRITZBOXattr"></a>
  4720. <b>Attributes</b>
  4721. <ul>
  4722. <br>
  4723. <li><code>allowShellCommand &lt;0 | 1&gt;</code>
  4724. <br>
  4725. Freischalten des get-Befehls "shellCommand"
  4726. </li><br>
  4727. <li><code>allowTR064Command &lt;0 | 1&gt;</code>
  4728. <br>
  4729. Freischalten des get-Befehls "tr064Command"
  4730. </li><br>
  4731. <li><code>boxUser &lt;user name&gt;</code>
  4732. <br>
  4733. Benutzername f&uuml;r den TR064- oder einen anderen webbasierten Zugang. Normalerweise wird keine Benutzername f&uuml;r das Login ben&ouml;tigt.
  4734. Wenn die Fritz!Box anders konfiguriert ist, kann der Nutzer &uuml;ber dieses Attribut definiert werden.
  4735. </li><br>
  4736. <li><code>defaultCallerName &lt;Text&gt;</code>
  4737. <br>
  4738. Standard-Text, der auf dem angerufenen internen Telefon als "Anrufer" gezeigt wird.
  4739. <br>
  4740. Dies erfolgt, indem w&auml;hrend des Klingelns tempor&auml;r der Name der internen anrufenden Nummer ge&auml;ndert wird.
  4741. <br>
  4742. Es sind maximal 30 Zeichen erlaubt. Das Attribute "ringWithIntern" muss ebenfalls spezifiziert sein.
  4743. <br>
  4744. Ben&ouml;tigt die API: Telnet oder webcmd
  4745. </li><br>
  4746. <li><code>defaultUploadDir &lt;fritzBoxPath&gt;</code>
  4747. <br>
  4748. Dies ist der Standard-Pfad der f&uuml;r Dateinamen benutzt wird, die nicht mit einem / (Schr&auml;gstrich) beginnen.
  4749. <br>
  4750. Es muss ein Pfad auf der Fritz!Box sein. D.h., er sollte mit /var/InternerSpeicher starten, wenn es in Windows unter \\ip-address\fritz.nas erreichbar ist.
  4751. </li><br>
  4752. <li><code>forceTelnetConnection &lt;0 | 1&gt;</code>
  4753. <br>
  4754. Erzwingt den Fernzugriff &uuml;ber Telnet (anstatt &uuml;ber die WebGUI oder TR-064).
  4755. <br>
  4756. Dieses Attribut muss bei &auml;lteren Ger&auml;ten/Firmware aktiviert werden.
  4757. </li><br>
  4758. <li><code>fritzBoxIP &lt;IP-Adresse&gt;</code>
  4759. <br>
  4760. Veraltet.
  4761. </li><br>
  4762. <li><code>INTERVAL &lt;Sekunden&gt;</code>
  4763. <br>
  4764. Abfrage-Interval. Standard ist 300 (Sekunden). Der kleinste m&ouml;gliche Wert ist 60.
  4765. </li><br>
  4766. <li><code>ringWithIntern &lt;1 | 2 | 3&gt;</code>
  4767. <br>
  4768. Um ein Telefon klingeln zu lassen, muss in der Fritzbox eine Anrufer (W&auml;hlhilfe, Wert 'box_stdDialPort') spezifiziert werden.
  4769. <br>
  4770. Um w&auml;hrend des Klingelns eine Nachricht (Standard: "FHEM") anzuzeigen, kann hier die interne Nummer 1-3 angegeben werden.
  4771. Der entsprechende analoge Telefonanschluss muss vorhanden sein.
  4772. </li><br>
  4773. <li><code>telnetTimeOut &lt;Sekunden&gt;</code>
  4774. <br>
  4775. Maximale Zeit, bis zu der w&auml;hrend einer Telnet-Sitzung auf Antwort gewartet wird. Standard ist 10 s.
  4776. </li><br>
  4777. <li><code>telnetUser &lt;user name&gt;</code>
  4778. <br>
  4779. Benutzername f&uuml;r den Telnetzugang. Normalerweise wird keine Benutzername f&uuml;r das Login ben&ouml;tigt.
  4780. Wenn die Fritz!Box anders konfiguriert ist, kann der Nutzer &uuml;ber dieses Attribut definiert werden.
  4781. </li><br>
  4782. <li><code>useGuiHack &lt;0 | 1&gt;</code>
  4783. <br>
  4784. Falls die APIs der Box nicht mehr die &Auml;nderung des Klingeltones unterst&uuml;tzen (Fritz!OS >6.24), kann dieses Attribute entsprechend der <a href="http://www.fhemwiki.de/wiki/FRITZBOX#Klingelton-Einstellung_und_Abspielen_von_Sprachnachrichten_bei_Fritz.21OS-Versionen_.3E6.24">WIKI-Anleitung</a> genutzt werden.
  4785. </li><br>
  4786. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  4787. </ul>
  4788. <br>
  4789. <a name="FRITZBOXreading"></a>
  4790. <b>Readings</b>
  4791. <ul><br>
  4792. <li><b>alarm</b><i>1</i> - Name des Weckrufs <i>1</i></li>
  4793. <li><b>alarm</b><i>1</i><b>_state</b> - Aktueller Status des Weckrufs <i>1</i></li>
  4794. <li><b>alarm</b><i>1</i><b>_target</b> - Interne Nummer des Weckrufs <i>1</i></li>
  4795. <li><b>alarm</b><i>1</i><b>_time</b> - Weckzeit des Weckrufs <i>1</i></li>
  4796. <li><b>alarm</b><i>1</i><b>_wdays</b> - Wochentage des Weckrufs <i>1</i></li>
  4797. <br>
  4798. <li><b>box_dect</b> - Aktueller Status des DECT-Basis</li>
  4799. <li><b>box_fwVersion</b> - Firmware-Version der Box, wenn veraltet dann wird '(old)' angehangen</li>
  4800. <li><b>box_guestWlan</b> - Aktueller Status des G&auml;ste-WLAN</li>
  4801. <li><b>box_guestWlanCount</b> - Anzahl der Ger&auml;te die &uuml;ber das G&auml;ste-WLAN verbunden sind</li>
  4802. <li><b>box_guestWlanRemain</b> - Verbleibende Zeit bis zum Ausschalten des G&auml;ste-WLAN</li>
  4803. <li><b>box_ipExtern</b> - Internet IP der Fritz!Box</li>
  4804. <li><b>box_model</b> - Fritz!Box-Modell</li>
  4805. <li><b>box_moh</b> - Wartemusik-Einstellung</li>
  4806. <li><b>box_powerRate</b> - aktueller Stromverbrauch in Prozent der maximalen Leistung</li>
  4807. <li><b>box_rateDown</b> - Download-Geschwindigkeit des letzten Intervals in kByte/s</li>
  4808. <li><b>box_rateUp</b> - Upload-Geschwindigkeit des letzten Intervals in kByte/s</li>
  4809. <li><b>box_stdDialPort</b> - Anschluss der ger&auml;teseitig von der W&auml;hlhilfe genutzt wird</li>
  4810. <li><b>box_tr064</b> - Anwendungsschnittstelle TR-064 (wird auch von diesem Modul ben&ouml;tigt)</li>
  4811. <li><b>box_tr069</b> - Provider-Fernwartung TR-069 (sicherheitsrelevant!)</li>
  4812. <li><b>box_wlanCount</b> - Anzahl der Ger&auml;te die &uuml;ber WLAN verbunden sind</li>
  4813. <li><b>box_wlan_2.4GHz</b> - Aktueller Status des 2.4-GHz-WLAN</li>
  4814. <li><b>box_wlan_5GHz</b> - Aktueller Status des 5-GHz-WLAN</li>
  4815. <br>
  4816. <li><b>dect</b><i>1</i> - Name des DECT Telefons <i>1</i></li>
  4817. <li><b>dect</b><i>1</i><b>_alarmRingTone</b> - Klingelton beim Wecken &uuml;ber das DECT Telefon <i>1</i></li>
  4818. <li><b>dect</b><i>1</i><b>_custRingTone</b> - Benutzerspezifischer Klingelton des DECT Telefons <i>1</i></li>
  4819. <li><b>dect</b><i>1</i><b>_fwVersion</b> - Firmware-Version des DECT Telefons <i>1</i></li>
  4820. <li><b>dect</b><i>1</i><b>_intern</b> - Interne Nummer des DECT Telefons <i>1</i></li>
  4821. <li><b>dect</b><i>1</i><b>_intRingTone</b> - Interner Klingelton des DECT Telefons <i>1</i></li>
  4822. <li><b>dect</b><i>1</i><b>_manufacturer</b> - Hersteller des DECT Telefons <i>1</i></li>
  4823. <li><b>dect</b><i>1</i><b>_model</b> - Modell des DECT Telefons <i>1</i></li>
  4824. <li><b>dect</b><i>1</i><b>_radio</b> - aktueller Internet-Radio-Klingelton des DECT Telefons <i>1</i></li>
  4825. <br>
  4826. <li><b>diversity</b><i>1</i> - Eigene Rufnummer der Rufumleitung <i>1</i></li>
  4827. <li><b>diversity</b><i>1</i><b>_dest</b> - Zielnummer der Rufumleitung <i>1</i></li>
  4828. <li><b>diversity</b><i>1</i><b>_state</b> - Aktueller Status der Rufumleitung <i>1</i></li>
  4829. <br>
  4830. <li><b>fon</b><i>1</i> - Name des analogen Telefonanschlusses <i>1</i> an der Fritz!Box</li>
  4831. <li><b>fon</b><i>1</i><b>_intern</b> - Interne Nummer des analogen Telefonanschlusses <i>1</i></li>
  4832. <li><b>fon</b><i>1</i><b>_out</b> - ausgehende Nummer des Anschlusses <i>1</i></li>
  4833. <br>
  4834. <li><b>gsm_internet</b> - Internetverbindung errichtet &uuml;ber Mobilfunk-Stick </li>
  4835. <li><b>gsm_rssi</b> - Indikator der empfangenen GSM-Signalst&auml;rke (0-100)</li>
  4836. <li><b>gsm_state</b> - Status der Mobilfunk-Verbindung</li>
  4837. <li><b>gsm_technology</b> - GSM-Technologie, die f&uuml;r die Daten&uuml;bertragung genutzt wird (GPRS, EDGE, UMTS, HSPA)</li>
  4838. <br>
  4839. <li><b>mac_</b><i>01_26_FD_12_01_DA</i> - MAC Adresse und Name eines aktiven Netzwerk-Ger&auml;tes.
  4840. <br>
  4841. Bei einer WLAN-Verbindung wird "WLAN" und (von der Box gesehen) die Sende- und Empfangsgeschwindigkeit und die Empfangsst&auml;rke angehangen. Bei einer LAN-Verbindung wird der LAN-Port und die LAN-Geschwindigkeit angehangen. Gast-Verbindungen werden mit "gWLAN" oder "gLAN" gekennzeichnet.
  4842. <br>
  4843. Inaktive oder entfernte Ger&auml;te erhalten zuerst den Werte "inactive" und werden beim n&auml;chsten Update gel&ouml;scht.</li>
  4844. <br>
  4845. <li><b>radio</b><i>01</i> - Name der Internetradiostation <i>01</i></li>
  4846. <br>
  4847. <li><b>tam</b><i>1</i> - Name des Anrufbeantworters <i>1</i></li>
  4848. <li><b>tam</b><i>1</i><b>_newMsg</b> - Anzahl neuer Nachrichten auf dem Anrufbeantworter <i>1</i></li>
  4849. <li><b>tam</b><i>1</i><b>_oldMsg</b> - Anzahl alter Nachrichten auf dem Anrufbeantworter <i>1</i></li>
  4850. <li><b>tam</b><i>1</i><b>_state</b> - Aktueller Status des Anrufbeantworters <i>1</i></li>
  4851. <br>
  4852. <li><b>user</b><i>01</i> - Name von Nutzer/IP <i>1</i> f&uuml;r den eine Zugangsbeschr&auml;nkung (Kindersicherung) eingerichtet ist</li>
  4853. <li><b>user</b><i>01</i>_thisMonthTime - Internetnutzung des Nutzers/IP <i>1</i> im aktuellen Monat (Kindersicherung)</li>
  4854. <li><b>user</b><i>01</i>_todaySeconds - heutige Internetnutzung des Nutzers/IP <i>1</i> in Sekunden (Kindersicherung)</li>
  4855. <li><b>user</b><i>01</i>_todayTime - heutige Internetnutzung des Nutzers/IP <i>1</i> (Kindersicherung)</li>
  4856. </ul>
  4857. <br>
  4858. </ul>
  4859. </div>
  4860. =end html_DE
  4861. =cut--