72_FRITZBOX.pm 216 KB

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