72_FRITZBOX.pm 214 KB

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