| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209 |
- # $Id: 98_MSwitch.pm 17659 2018-11-02 05:06:07Z Byte09 $
- # 98_MSwitch.pm
- #
- # copyright #####################################################
- #
- # 98_MSwitch.pm
- #
- # written by Byte09
- # Maintained by Byte09
- #
- # This file is part of FHEM.
- #
- # FHEM is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 2 of the License, or
- # (at your option) any later version.
- #
- # FHEM is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with FHEM. If not, see <http://www.gnu.org/licenses/>.
- #################################################################
- # Todo's:
- #
- # info conf
- # reading '.lock' wenn definiert -> device locked
- # reading '.info' wenn definiert -> infotext für device
- # reading '.change' wenn definiert -> angeforderte deviceänderung
- # reading '.change_inf' wenn definiert -> info für angeforderte deviceänderung
- #
- # info conffile - austausch eines/mehrerer devices
- # I testinfo
- # Q dummy1#zu schaltendes geraet#device
- # Q dummy2#zu schaltendes geraet2#device
- #
- #################################################################
- package main;
- use Time::Local;
- use strict;
- use warnings;
- use POSIX;
- # Version #######################################################
- my $autoupdate = 'on'; #off/on
- my $version = '2.02';
- my $vupdate = 'V2.00'
- ; # versionsnummer der datenstruktur . änderung der nummer löst MSwitch_VUpdate aus .
- my $savecount = 30
- ; # anzahl der zugriff im zeitraum zur auslösung des safemodes. kann durch attribut überschrieben werden .
- my $standartstartdelay = 60
- ; # zeitraum nach fhemstart , in dem alle aktionen geblockt werden. kann durch attribut überschrieben werden .
- my $eventset = '0';
- # standartlist ignorierter Devices . kann durch attribut überschrieben werden .
- my @doignore =
- qw(notify allowed at watchdog doif fhem2fhem telnet FileLog readingsGroup FHEMWEB autocreate eventtypes readingsproxy svg cul);
- ##################### ############################################
- sub MSwitch_Checkcond_time($$);
- sub MSwitch_Checkcond_state($$);
- sub MSwitch_Checkcond_day($$$$);
- sub MSwitch_Createtimer($);
- sub MSwitch_Execute_Timer($);
- sub MSwitch_LoadHelper($);
- sub MSwitch_debug2($$);
- sub MSwitch_ChangeCode($$);
- sub MSwitch_Add_Device($$);
- sub MSwitch_Del_Device($$);
- sub MSwitch_Debug($);
- sub MSwitch_Exec_Notif($$$$$);
- sub MSwitch_checkcondition($$$);
- sub MSwitch_Delete_Delay($$);
- sub MSwitch_Check_Event($$);
- sub MSwitch_makeAffected($);
- sub MSwitch_backup($);
- sub MSwitch_backup_this($);
- sub MSwitch_backup_all($);
- sub MSwitch_backup_done($);
- sub MSwitch_checktrigger(@);
- sub MSwitch_Cmd(@);
- sub MSwitch_toggle($$);
- sub MSwitch_Getconfig($);
- sub MSwitch_saveconf($$);
- sub MSwitch_replace_delay($$);
- sub MSwitch_repeat($);
- sub MSwitch_Createrandom($$$);
- sub MSwitch_Execute_randomtimer($);
- sub MSwitch_Clear_timer($);
- sub MSwitch_Createnumber($);
- sub MSwitch_Createnumber1($);
- sub MSwitch_Savemode($);
- sub MSwitch_set_dev($);
- sub MSwitch_EventBulk($$$$);
- sub MSwitch_priority;
- sub MSwitch_sort;
- sub MSwitch_dec($$);
- sub MSwitch_makefreecmd($$);
- sub MSwitch_clearlog($);
- sub MSwitch_LOG($$$);
- sub MSwitch_Getsupport($);
- sub MSwitch_confchange($$);
- my %sets = (
- "on" => "noArg",
- "off" => "noArg",
- "reload_timer" => "noArg",
- "active" => "noArg",
- "inactive" => "noArg",
- "devices" => "noArg",
- "details" => "noArg",
- "del_trigger" => "noArg",
- "del_delays" => "noArg",
- "trigger" => "noArg",
- "filter_trigger" => "noArg",
- "add_device" => "noArg",
- "del_device" => "noArg",
- "addevent" => "noArg",
- "backup_MSwitch" => "noArg",
- "import_config" => "noArg",
- "saveconfig" => "noArg",
- "savesys" => "noArg",
- "sort_device" => "noArg",
- "fakeevent" => "noArg",
- "exec_cmd1" => "noArg",
- "exec_cmd2" => "noArg",
- "exec_cmd1+2" => "noArg",
- "wait" => "noArg",
- "VUpdate" => "noArg",
- "confchange" => "noArg",
- "clearlog" => "noArg",
- "set_trigger" => "noArg",
- "change_renamed" => ""
- );
- my %gets = (
- "active_timer" => "noArg",
- "restore_MSwitch_Data" => "noArg",
- "get_config" => "noArg"
- );
- ####################
- sub MSwitch_Initialize($) {
- my ($hash) = @_;
- $hash->{SetFn} = "MSwitch_Set";
- $hash->{AsyncOutput} = "MSwitch_AsyncOutput";
- $hash->{RenameFn} = "MSwitch_Rename";
- $hash->{CopyFn} = "MSwitch_Copy";
- $hash->{GetFn} = "MSwitch_Get";
- $hash->{DefFn} = "MSwitch_Define";
- $hash->{UndefFn} = "MSwitch_Undef";
- $hash->{DeleteFn} = "MSwitch_Delete";
- $hash->{ParseFn} = "MSwitch_Parse";
- $hash->{AttrFn} = "MSwitch_Attr";
- $hash->{NotifyFn} = "MSwitch_Notify";
- $hash->{FW_detailFn} = "MSwitch_fhemwebFn";
- $hash->{FW_deviceOverview} = 1;
- $hash->{FW_summaryFn} = "MSwitch_summary";
- $hash->{NotifyOrderPrefix} = "45-";
- $hash->{AttrList} =
- " disable:0,1"
- . " disabledForIntervals"
- . " stateFormat"
- . " MSwitch_Comments:0,1"
- . " MSwitch_Help:0,1"
- . " MSwitch_Debug:0,1,2,3,4"
- . " MSwitch_Expert:0,1"
- . " MSwitch_Delete_Delays:0,1"
- . " MSwitch_Include_Devicecmds:0,1"
- . " MSwitch_Include_Webcmds:0,1"
- . " MSwitch_Include_MSwitchcmds:0,1"
- . " MSwitch_Activate_MSwitchcmds:0,1"
- . " MSwitch_Lock_Quickedit:0,1"
- . " MSwitch_Ignore_Types"
- . " MSwitch_Trigger_Filter"
- . " MSwitch_Extensions:0,1"
- . " MSwitch_Inforoom"
- . " MSwitch_Mode:Full,Notify,Toggle"
- . " MSwitch_Condition_Time:0,1"
- . " MSwitch_RandomTime"
- . " MSwitch_RandomNumber"
- . " MSwitch_Safemode:0,1"
- . " MSwitch_Startdelay:0,10,20,30,60,90,120"
- . " MSwitch_Wait";
- $hash->{FW_addDetailToSummary} = 0;
- }
- ####################
- sub MSwitch_Rename($) {
- # routine nicht in funktion
- my ( $new_name, $old_name ) = @_;
- my $hash_new = $defs{$new_name};
- $modules{MSwitch}{defptr}{$new_name} = $hash_new;
- }
- ####################
- sub MSwitch_Copy ($) {
- my ( $old_name, $new_name ) = @_;
- my $hash = $defs{$new_name};
- my @areadings =
- qw(.Device_Affected .Device_Affected_Details .Device_Events .First_init .Trigger_Whitelist .Trigger_cmd_off .Trigger_cmd_on .Trigger_condition .Trigger_off .Trigger_on .Trigger_time .V_Check Exec_cmd Trigger_device Trigger_log last_event state .sysconf Sys_Extension)
- ; #alle readings
- my $cs = "attr $new_name disable 1";
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $new_name, 1, "ERROR $cs" );
- }
- foreach my $key (@areadings) {
- my $tmp = ReadingsVal( $old_name, $key, 'undef' );
- fhem( "setreading " . $new_name . " " . $key . " " . $tmp );
- }
- MSwitch_LoadHelper($hash);
- }
- ####################
- sub MSwitch_summary($) {
- my ( $wname, $name, $room ) = @_;
- my $hash = $defs{$name};
- my $testroom = AttrVal( $name, 'MSwitch_Inforoom', 'undef' );
- if ( $testroom ne $room ) { return; }
- my $test = AttrVal( $name, 'comment', '0' );
- my $info = AttrVal( $name, 'comment', 'No Info saved at ATTR omment' );
- my $image = ReadingsVal( $name, 'state', 'undef' );
- my $ret = '';
- my $devtitle = '';
- my $option = '';
- my $html = '';
- my $triggerc = 1;
- my $timer = 1;
- my $trigger = ReadingsVal( $name, 'Trigger_device', 'undef' );
- my @devaff = split( / /, MSwitch_makeAffected($hash) );
- $option .= "<option value=\"affected devices\">affected devices</option>";
- foreach (@devaff) {
- $devtitle .= $_ . ", ";
- $option .= "<option value=\"$_\">" . $_ . "</option>";
- }
- chop($devtitle);
- chop($devtitle);
- my $affected =
- "<select style='width: 12em;' title=\""
- . $devtitle . "\" >"
- . $option
- . "</select>";
- ### time
- my $optiontime;
- my $devtitletime = '';
- my $triggertime = ReadingsVal( $name, 'Trigger_device', 'not defined' );
- my $devtime = ReadingsVal( $name, '.Trigger_time', '' );
- $devtime =~ s/\[//g;
- $devtime =~ s/\]/ /g;
- my @devtime = split( /~/, $devtime );
- $optiontime .= "<option value=\"Time:\">At: aktiv</option>";
- my $count = @devtime;
- $devtime[0] =~ s/on/on+cmd1: /g if defined $devtime[0];
- $devtime[1] =~ s/off/off+cmd2: /g if defined $devtime[1];
- $devtime[2] =~ s/ononly/only cmd1: /g if defined $devtime[2];
- $devtime[3] =~ s/offonly/only cmd2: /g if defined $devtime[3];
- if ( AttrVal( $name, 'MSwitch_Mode', 'Full' ) ne "Notify" ) {
- $optiontime .=
- "<option value=\"$devtime[0]\">" . $devtime[0] . "</option>"
- if defined $devtime[0];
- $optiontime .=
- "<option value=\"$devtime[1]\">" . $devtime[1] . "</option>"
- if defined $devtime[1];
- }
- $optiontime .= "<option value=\"$devtime[2]\">" . $devtime[2] . "</option>"
- if defined $devtime[2];
- $optiontime .= "<option value=\"$devtime[3]\">" . $devtime[3] . "</option>"
- if defined $devtime[3];
- my $affectedtime = '';
- if ( $count == 0 ) {
- $timer = 0;
- $affectedtime =
- "<select style='width: 12em;' title=\""
- . $devtitletime
- . "\" disabled ><option value=\"Time:\">At: inaktiv</option></select>";
- }
- else {
- chop($devtitletime);
- chop($devtitletime);
- $affectedtime =
- "<select style='width: 12em;' title=\""
- . $devtitletime . "\" >"
- . $optiontime
- . "</select>";
- }
- if ( $info eq 'No Info saved at ATTR omment' ) {
- $ret .=
- "<input disabled title=\""
- . $info
- . "\" name='info' type='button' value='Info' onclick =\"FW_okDialog('"
- . $info . "')\">";
- }
- else {
- $ret .=
- "<input title=\""
- . $info
- . "\" name='info' type='button' value='Info' onclick =\"FW_okDialog('"
- . $info . "')\">";
- }
- if ( $trigger eq 'no_trigger' || $trigger eq 'undef' ) {
- $triggerc = 0;
- if ( $triggerc != 0 || $timer != 0 ) {
- $ret .=
- "<select style='width: 18em;' title=\"\" disabled ><option value=\"Trigger:\">Trigger: inaktiv</option></select>";
- }
- else {
- $affectedtime = "";
- $ret .= " Multiswitchmode (no trigger / no timer) ";
- }
- }
- else {
- $ret .= "<select style='width: 18em;' title=\"\" >";
- $ret .= "<option value=\"Trigger:\">Trigger: " . $trigger . "</option>";
- $ret .=
- "<option value=\"Trigger:\">on+cmd1: "
- . ReadingsVal( $name, '.Trigger_on', 'not defined' )
- . "</option>";
- $ret .=
- "<option value=\"Trigger:\">off+cmd2: "
- . ReadingsVal( $name, '.Trigger_off', 'not defined' )
- . "</option>";
- $ret .=
- "<option value=\"Trigger:\">only cmd1: "
- . ReadingsVal( $name, '.Trigger_cmd_on', 'not defined' )
- . "</option>";
- $ret .=
- "<option value=\"Trigger:\">only cmd2: "
- . ReadingsVal( $name, '.Trigger_cmd_off', 'not defined' )
- . "</option>";
- $ret .= "</select>";
- }
- $ret .= $affectedtime;
- $ret .= $affected;
- if ( ReadingsVal( $name, '.V_Check', 'not defined' ) ne $vupdate ) {
- $ret .= "
- </td><td informId=\"" . $name . "tmp\">Versionskonflikt !
- </td><td informId=\"" . $name . "tmp\">
- <div class=\"dval\" informid=\"" . $name . "-state\"></div>
- </td><td informId=\"" . $name . "tmp\">
- <div informid=\"" . $name . "-state-ts\">(please help)</div>
- ";
- }
- else {
- if ( AttrVal( $name, 'disable', "0" ) eq '1' ) {
- $ret .= "
- </td><td informId=\"" . $name . "tmp\">State:
- </td><td informId=\"" . $name . "tmp\">
- <div class=\"dval\" informid=\"" . $name . "-state\"></div>
- </td><td informId=\"" . $name . "tmp\">
- <div informid=\"" . $name . "-state-ts\">disabled</div>
- ";
- }
- else {
- $ret .= "
- </td><td informId=\"" . $name . "tmp\">
- State: </td><td informId=\"" . $name . "tmp\">
- <div class=\"dval\" informid=\""
- . $name
- . "-state\">"
- . ReadingsVal( $name, 'state', '' ) . "</div>
- </td><td informId=\"" . $name . "tmp\">";
- if ( AttrVal( $name, 'MSwitch_Mode', 'Full' ) ne "Notify" ) {
- $ret .=
- "<div informid=\""
- . $name
- . "-state-ts\">"
- . ReadingsTimestamp( $name, 'state', '' )
- . "</div>";
- }
- else {
- $ret .=
- "<div informid=\""
- . $name
- . "-state-ts\">"
- . ReadingsTimestamp( $name, 'state', '' )
- . "</div>";
- }
- }
- }
- $ret .= "<script>
- \$( \"td[informId|=\'" . $name . "\']\" ).attr(\"informId\", \'test\');
- \$(document).ready(function(){
- \$( \".col3\" ).text( \"\" );
- \$( \".devType\" ).text( \"MSwitch Inforoom: Anzeige der Deviceinformationen, Änderungen sind nur in den Details möglich.\" );
- });
- </script>";
-
- $ret =~ s/#dp /:/g;
-
- return $ret;
- }
- ####################
- sub MSwitch_LoadHelper($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $oldtrigger = ReadingsVal( $Name, 'Trigger_device', 'undef' );
- my $devhash = undef;
- my $cdev = '';
- my $ctrigg = '';
- if ( defined $hash->{DEF} ) {
- $devhash = $hash->{DEF};
- my @dev = split( /#/, $devhash );
- $devhash = $dev[0];
- ( $cdev, $ctrigg ) = split( / /, $devhash );
- if ( defined $ctrigg ) {
- $ctrigg =~ s/\.//g;
- }
- else {
- $ctrigg = '';
- }
- if ( defined $devhash ) {
- $hash->{NOTIFYDEV} = $cdev; # stand aug global ... änderung auf ...
- readingsSingleUpdate( $hash, "Trigger_device", $cdev, 0 );
- if ( defined $cdev && $cdev ne '' ) {
- readingsSingleUpdate( $hash, "Trigger_device", $cdev, 0 );
- }
- }
- else {
- $hash->{NOTIFYDEV} = 'no_trigger';
- readingsSingleUpdate( $hash, "Trigger_device", 'no_trigger', 0 );
- }
- }
- if ( !defined $hash->{NOTIFYDEV}
- || $hash->{NOTIFYDEV} eq 'undef'
- || $hash->{NOTIFYDEV} eq '' )
- {
- $hash->{NOTIFYDEV} = 'no_trigger';
- }
- if ( $oldtrigger ne 'undef' ) {
- $hash->{NOTIFYDEV} = $oldtrigger;
- readingsSingleUpdate( $hash, "Trigger_device", $oldtrigger, 0 );
- }
- #################
- MSwitch_set_dev($hash);
- #################
- if ( AttrVal( $Name, 'MSwitch_Activate_MSwitchcmds', "0" ) eq '1' ) {
- addToAttrList('MSwitchcmd');
- }
- ################erste initialisierung eines devices
- if ( ReadingsVal( $Name, '.V_Check', 'undef' ) ne $vupdate
- && $autoupdate eq "on" )
- {
- MSwitch_VUpdate($hash);
- }
- ################
- if ( ReadingsVal( $Name, '.First_init', 'undef' ) ne 'done' ) {
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, ".V_Check", $vupdate );
- readingsBulkUpdate( $hash, "state", 'off' );
- if ( defined $ctrigg && $ctrigg ne '' ) {
- readingsBulkUpdate( $hash, ".Device_Events", $ctrigg );
- $hash->{DEF} = $cdev;
- }
- else {
- readingsBulkUpdate( $hash, ".Device_Events", 'no_trigger' );
- }
- readingsBulkUpdate( $hash, ".Trigger_on", 'no_trigger' );
- readingsBulkUpdate( $hash, ".Trigger_off", 'no_trigger' );
- readingsBulkUpdate( $hash, ".Trigger_cmd_on", 'no_trigger' );
- readingsBulkUpdate( $hash, ".Trigger_cmd_off", 'no_trigger' );
- readingsBulkUpdate( $hash, "Trigger_log", 'off' );
- readingsBulkUpdate( $hash, ".Device_Affected", 'no_device' );
- readingsBulkUpdate( $hash, ".First_init", 'done' );
- readingsEndUpdate( $hash, 0 );
- # setze ignoreliste
- $attr{$Name}{MSwitch_Ignore_Types} = join( " ", @doignore );
- # setze attr inforoom
- my $testdev = '';
- LOOP22:
- foreach my $testdevices ( keys %{ $modules{MSwitch}{defptr} } ) #
- {
- if ( $Name eq $testdevices ) { next LOOP22; }
- $testdev = AttrVal( $testdevices, 'MSwitch_Inforoom', '' );
- }
- if ( $testdev ne '' ) {
- $attr{$Name}{MSwitch_Inforoom} = $testdev,;
- }
- #setze alle attrs
- $attr{$Name}{MSwitch_Help} = '0';
- $attr{$Name}{MSwitch_Debug} = '0';
- $attr{$Name}{MSwitch_Expert} = '0';
- $attr{$Name}{MSwitch_Delete_Delays} = '1';
- $attr{$Name}{MSwitch_Include_Devicecmds} = '1';
- $attr{$Name}{MSwitch_Include_Webcmds} = '0';
- $attr{$Name}{MSwitch_Include_MSwitchcmds} = '0';
- $attr{$Name}{MSwitch_Include_MSwitchcmds} = '0';
- $attr{$Name}{MSwitch_Lock_Quickedit} = '1';
- $attr{$Name}{MSwitch_Extensions} = '0';
- $attr{$Name}{MSwitch_Mode} = 'Full';
- }
- # NEU; ZUVOR IN SET
- my $testnew = ReadingsVal( $Name, '.Trigger_on', 'undef' );
- if ( $testnew eq 'undef' ) {
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, ".Device_Events", 'no_trigger' );
- readingsBulkUpdate( $hash, ".Trigger_on", 'no_trigger' );
- readingsBulkUpdate( $hash, ".Trigger_off", 'no_trigger' );
- readingsBulkUpdate( $hash, "Trigger_log", 'on' );
- readingsBulkUpdate( $hash, ".Device_Affected", 'no_device' );
- readingsEndUpdate( $hash, 0 );
- }
- MSwitch_Createtimer($hash); #Neustart aller timer
- }
- ####################
- sub MSwitch_Define($$) {
- my $loglevel = 0;
- my ( $hash, $def ) = @_;
- my @a = split( "[ \t][ \t]*", $def );
- my $name = $a[0];
- my $devpointer = $name;
- my $devhash = '';
- my $old = $hash->{OLDDEF};
- $old = '' if !defined $old;
- $modules{MSwitch}{defptr}{$devpointer} = $hash;
- $hash->{Version_Modul} = $version;
- $hash->{Version_Datenstruktur} = $vupdate;
- $hash->{Version_autoupdate} = $autoupdate;
- if ( $init_done && $old ne '' ) {
- my $timecond = gettimeofday() + 5;
- InternalTimer( $timecond, "MSwitch_LoadHelper", $hash );
- }
- return;
- }
- ####################
- sub MSwitch_Get($$@) {
- my ( $hash, $name, $opt, @args ) = @_;
- my $ret;
- if ( ReadingsVal( $name, '.change', '' ) ne '' ) {
- return "Unknown argument, choose one of ";
- }
- return "\"get $name\" needs at least one argument" unless ( defined($opt) );
- ####################
- if ( $opt eq 'restore_MSwitch_Data' && $args[0] eq "this_Device" ) {
- $ret = MSwitch_backup_this($hash);
- return $ret;
- }
- ####################
- if ( $opt eq 'restore_MSwitch_Data' && $args[0] eq "all_Devices" ) {
- open( BACKUPDATEI, "<MSwitch_backup_$vupdate.cfg" )
- || return "no Backupfile found\n";
- close(BACKUPDATEI);
- $hash->{helper}{RESTORE_ANSWER} = $hash->{CL};
- my $ret = MSwitch_backup_all($hash);
- return $ret;
- }
- ####################
- if ( $opt eq 'checkevent' ) {
- $ret = MSwitch_Check_Event( $hash, $args[0] );
- return $ret;
- }
- ####################
- if ( $opt eq 'get_config' ) {
- $ret = MSwitch_Getconfig($hash);
- return $ret;
- }
- ####################
- if ( $opt eq 'get_support_info' ) {
- $ret = MSwitch_Getsupport($hash);
- return $ret;
- }
- ####################
- if ( $opt eq 'get_sysextension' ) {
- $ret = MSwitch_Sysextension($hash);
- return $ret;
- }
- ####################
- if ( $opt eq 'checkcondition' ) {
- my ( $condstring, $eventstring ) = split( /\|/, $args[0] );
- $condstring =~ s/#\[dp\]/:/g;
- $condstring =~ s/#\[pt\]/./g;
- $condstring =~ s/#\[ti\]/~/g;
- $condstring =~ s/#\[sp\]/ /g;
- $eventstring =~ s/#\[dp\]/:/g;
- $eventstring =~ s/#\[pt\]/./g;
- $eventstring =~ s/#\[ti\]/~/g;
- $eventstring =~ s/#\[sp\]/ /g;
- $condstring =~ s/\(DAYS\)/|/g;
- my $ret1 = MSwitch_checkcondition( $condstring, $name, $eventstring );
- my $condstring1 = $hash->{helper}{conditioncheck};
- my $errorstring = $hash->{helper}{conditionerror};
- if ( !defined $errorstring ) { $errorstring = '' }
- $condstring1 =~ s/</\<\;/g;
- $condstring1 =~ s/>/\>\;/g;
- $errorstring =~ s/</\<\;/g;
- $errorstring =~ s/>/\>\;/g;
- if ( $errorstring ne '' && $condstring1 ne 'Klammerfehler' ) {
- $ret1 =
- '<div style="color: #FF0000">Syntaxfehler:<br>'
- . $errorstring
- . '</div><br>';
- }
- elsif ( $condstring1 eq 'Klammerfehler' ) {
- $ret1 =
- '<div style="color: #FF0000">Syntaxfehler:<br>Fehler in der Klammersetzung, die Anzahl öffnender und schliessender Klammern stimmt nicht überein . </div><br>';
- }
- else {
- if ( $ret1 eq 'true' ) {
- $ret1 = 'Bedingung ist Wahr und wird ausgeführt';
- }
- if ( $ret1 eq 'false' ) {
- $ret1 = 'Bedingung ist nicht Wahr und wird nicht ausgeführt';
- }
- }
- $condstring =~ s/~/ /g;
- my $condmarker = $condstring1;
- my $x = 0; # exit
- while ( $condmarker =~ m/(.*)(\d{10})(.*)/ ) {
- $x++; # exit
- last if $x > 20; # exit
- my $timestamp = FmtDateTime($2);
- chop $timestamp;
- chop $timestamp;
- chop $timestamp;
- my ( $st1, $st2 ) = split( / /, $timestamp );
- $condmarker = $1 . $st2 . $3;
- }
- $ret =
- "eingehender String:<br>$condstring<br><br>If Anweisung Perl:<br>$condstring1<br><br>";
- $ret .= "If Anweisung Perl Klarzeiten:<br>$condmarker<br><br>"
- if $x > 0;
- $ret .= $ret1;
- my $condsplit = $condmarker;
- my $reads = '<br><br>States der geprüften Readings:<br>';
- $x = 0; # exit
- while ( $condsplit =~ m/(.*')(.*)',\s'(.*)',\s(.*)/ ) {
- $x++; # exit
- last if $x > 20; # exit
- $reads .= "Reading: [$2:$3] - Inhalt: "
- . ReadingsVal( $2, $3, 'undef' );
- $reads .=
- "<div style=\"color: #FF0000\">Reading nicht vorhanden !</div>"
- if ( ReadingsVal( $2, $3, 'undef' ) ) eq "undef";
- $reads .= "<br>";
- $condsplit = $1 . $4;
- }
- $ret .= $reads if $x > 0;
- my $err1;
- my $err2;
- if ( $errorstring ne '' ) {
- ( $err1, $err2 ) = split( /near /, $errorstring );
- chop $err2;
- chop $err2;
- $err2 = substr( $err2, 1 );
- $ret =~ s/$err2/<span style="color: #FF0000">$err2<\/span>/ig;
- }
- $hash->{helper}{conditioncheck} = '';
- $hash->{helper}{conditionerror} = '';
- return "<span style=\"font-size: medium\">" . $ret . "<\/span>";
- }
- #################################################
- if ( $opt eq 'active_timer' && $args[0] eq 'delete' ) {
- MSwitch_Clear_timer($hash);
- MSwitch_Createtimer($hash);
- MSwitch_Delete_Delay( $hash, 'all' );
- $ret .=
- "<br>INFO: Alle anstehenden Timer wurden neu berechnet, alle Delays wurden gelöscht<br>";
- return $ret;
- }
- #################################################
- if ( $opt eq 'active_timer' && $args[0] eq 'show' ) {
- $ret .= "<div nowrap>Systemzeit: " . localtime() . "</div><hr>";
- $ret .= "<div nowrap>Schaltzeiten (at - kommandos).</div><hr>";
- #timer
- my $timehash = $hash->{helper}{timer};
- foreach my $a ( sort keys %{$timehash} ) {
- my $time = FmtDateTime( $hash->{helper}{timer}{$a} );
- my @timers = split( /,/, $a );
- if ( substr( $hash->{helper}{timer}{$a}, 11, 1 ) eq '1' ) {
- $ret .=
- "<div nowrap>"
- . $time
- . " switch MSwitch on + execute 'on' cmds</div>";
- }
- if ( substr( $hash->{helper}{timer}{$a}, 11, 1 ) eq '2' ) {
- $ret .=
- "<div nowrap>"
- . $time
- . " switch MSwitch off + execute 'off' cmds</div>";
- }
- if ( substr( $hash->{helper}{timer}{$a}, 11, 1 ) eq '3' ) {
- $ret .=
- "<div nowrap>" . $time . " execute 'on' commands only</div>";
- }
- if ( substr( $hash->{helper}{timer}{$a}, 11, 1 ) eq '4' ) {
- $ret .=
- "<div nowrap>" . $time . " execute 'off' commands only</div>";
- }
- if ( substr( $hash->{helper}{timer}{$a}, 11, 1 ) eq '5' ) {
- $ret .=
- "<div nowrap>"
- . $time
- . " neuberechnung aller Schaltzeiten </div>";
- }
- }
- #delays
- $ret .= "<br> <br><div nowrap>aktive Delays:</div><hr>";
- $timehash = $hash->{helper}{delays};
- foreach my $a ( sort keys %{$timehash} ) {
- my $b = substr( $hash->{helper}{delays}{$a}, 0, 10 );
- my $time = FmtDateTime($b);
- my @timers = split( /#\[tr\]/, $a );
- $ret .= "<div nowrap>" . $time . " " . $timers[0] . "</div>";
- }
- if ( $ret ne
- "<div nowrap>Schaltzeiten (at - kommandos).</div><hr><div nowrap>aktive Delays:</div><hr>"
- )
- {
- return $ret;
- }
- return
- "<span style=\"font-size: medium\">Keine aktiven Delays/Ats gefunden <\/span>";
- }
- my $extension = '';
- if ( ReadingsVal( $name, 'Sys_Extension', '' ) eq 'on' ) {
- $extension = 'get_sysextension:noArg';
- }
- if ( ReadingsVal( $name, '.lock', 'undef' ) ne "undef" ) {
- return
- "Unknown argument $opt, choose one of active_timer:show,delete get_config:noArg restore_MSwitch_Data:this_Device,all_Devices";
- }
- else {
- return
- "Unknown argument $opt, choose one of get_support_info:noArg get_config:noArg active_timer:show,delete restore_MSwitch_Data:this_Device,all_Devices $extension";
- }
- }
- ####################
- sub MSwitch_AsyncOutput ($) {
- my ( $client_hash, $text ) = @_;
- return $text;
- }
- ####################
- sub MSwitch_Set($@) {
- my ( $hash, $name, $cmd, @args ) = @_;
- ##############################
- if ( $cmd eq 'inactive' ) {
- # setze device auf inaktiv
- readingsSingleUpdate( $hash, "state", 'inactive', 1 );
- return;
- }
- ##############################
- if ( $cmd eq 'active' ) {
- # setze device auf aktiv
- readingsSingleUpdate( $hash, "state", 'active', 1 );
- return;
- }
- ##############################
- return ""
- if ( IsDisabled($name) && ( $cmd eq 'on' || $cmd eq 'off' ) )
- ; # Return without any further action if the module is disabled
- my $execids = "0";
- $hash->{eventsave} = 'unsaved';
- # verry special commands readingactivated (
- my $special = '';
- my $cs = ReadingsVal( $name, '.sysconf', 'undef' );
- if ( $cs ne "undef" ) {
- $cs =~ s/#\[wa\]/|/g;
- $cs =~ s/#\[sp\]/ /g;
- $cs =~ s/#\[nl\]/\n/g;
- $cs =~ s/#\[se\]/;/g;
- $cs =~ s/#\[dp\]/:/g;
- $cs =~ s/#\[st\]/'/g;
- $cs =~ s/#\[dst\]/\"/g;
- $cs =~ s/#\[tab\]/ /g;
- $cs =~ s/#\[ko\]/,/g;
- $cs =~ s/#.*\n//g;
- $cs =~ s/\n//g;
- my $return = "no value";
- $return = eval($cs);
- if ($@) {
- Log3( $name, 1, "$name MSwitch_repeat: ERROR $cs: $@ " . __LINE__ );
- }
- return if $return eq "exit";
- }
- ############################
- if ( !defined $args[0] ) { $args[0] = ''; }
- if ( $cmd eq 'exec_cmd1' && $args[0] eq 'ID' ) {
- Log3( $name, 5, "$name: execids werden gesetzt -> " . $args[1] );
- $execids = $args[1];
- $args[0] = 'ID';
- }
- if ( $cmd eq 'exec_cmd2' && $args[0] eq 'ID' ) {
- Log3( $name, 5, "$name: execids werden gesetzt als -> " . $args[1] );
- $execids = $args[1];
- $args[0] = 'ID';
- }
- my $ic = '';
- $ic = $hash->{IncommingHandle};
- #######################################
- if ( ( ( $cmd eq 'on' ) || ( $cmd eq 'off' ) )
- && ( $args[0] ne '' )
- && ( $ic ne 'fromnotify' ) )
- {
- readingsSingleUpdate( $hash, "Parameter", $args[0], 1 );
- if ( $cmd eq 'on' ) { $args[0] = "$name:on_with_Parameter:$args[0]"; }
- if ( $cmd eq 'off' ) { $args[0] = "$name:off_with_Parameter:$args[0]"; }
- }
- delete( $hash->{IncommingHandle} );
- #######################################
- if ( AttrVal( $name, 'MSwitch_Debug', "0" ) eq '4' )
- #AUFRUF DEBUGFUNKTIONEN
- {
- MSwitch_Debug($hash);
- }
- if ( !exists( $sets{$cmd} ) ) {
- my @cList;
- # Overwrite %sets with setList
- my $atts = AttrVal( $name, 'setList', "" );
- my %setlist = split( "[: ][ ]*", $atts );
- foreach my $k ( sort keys %sets ) {
- my $opts = undef;
- $opts = $sets{$k};
- $opts = $setlist{$k} if ( exists( $setlist{$k} ) );
- if ( defined($opts) ) {
- push( @cList, $k . ':' . $opts );
- }
- else {
- push( @cList, $k );
- }
- } # end foreach
- if ( ReadingsVal( $name, '.change', '' ) ne '' ) {
- return "Unknown argument $cmd, choose one of ";
- }
- if ( AttrVal( $name, 'MSwitch_Mode', 'Full' ) eq "Notify" ) {
- return
- "Unknown argument $cmd, choose one of active:noArg inactive:noArg del_delays:noArg backup_MSwitch:all_devices fakeevent exec_cmd1 exec_cmd2 exec_cmd1+2 wait reload_timer:noArg change_renamed $special";
- }
- elsif ( AttrVal( $name, 'MSwitch_Mode', 'Full' ) eq "Toggle" ) {
- return
- "Unknown argument $cmd, choose one of active:noArg inactive:noArg on offdel_delays:noArg backup_MSwitch:all_devices fakeevent wait reload_timer:noArg change_renamed $special";
- }
- else {
- return
- "Unknown argument $cmd, choose one of active:noArg inactive:noArg on off del_delays:noArg backup_MSwitch:all_devices fakeevent exec_cmd1 exec_cmd2 exec_cmd1+2 wait reload_timer:noArg change_renamed $special";
- }
- }
- if ( AttrVal( $name, 'MSwitch_RandomNumber', '' ) ne '' ) {
- # randomnunner erzeugen wenn attr an
- MSwitch_Createnumber1($hash);
- }
- #######################################
- if ( $cmd eq 'change_renamed' ) {
- my $changestring = $args[0] . "#" . $args[1];
- MSwitch_confchange( $hash, $changestring );
- return;
- }
- #######################################
- if ( $cmd eq 'reload_timer' ) {
- MSwitch_Clear_timer($hash);
- MSwitch_Createtimer($hash);
- return;
- }
- #######################################
- if ( $cmd eq 'VUpdate' ) {
- MSwitch_VUpdate($hash);
- return;
- }
- #######################################
- if ( $cmd eq 'confchange' ) {
- MSwitch_confchange( $hash, $args[0] );
- return;
- }
- ###################################
- if ( $cmd eq 'clearlog' ) {
- MSwitch_clearlog($hash);
- return;
- }
- ##############################
- if ( $cmd eq 'wait' ) {
- readingsSingleUpdate( $hash, "waiting", ( time + $args[0] ), 1 );
- return;
- }
- ###############################
- if ( $cmd eq 'sort_device' ) {
- readingsSingleUpdate( $hash, ".sortby", $args[0], 0 );
- return;
- }
- if ( $cmd eq 'fakeevent' ) {
- # fakeevent abarbeiten
- MSwitch_Check_Event( $hash, $args[0] );
- return;
- }
- ##############################
- if ( $cmd eq 'exec_cmd1' ) {
- # cmd1 abarbeiten
- MSwitch_Exec_Notif( $hash, 'on', 'nocheck', '', $execids );
- return;
- }
- ##############################
- if ( $cmd eq 'exec_cmd2' ) {
- # cmd1 abarbeiten
- MSwitch_Exec_Notif( $hash, 'off', 'nocheck', '', $execids );
- return;
- }
- ##############################
- if ( $cmd eq 'backup_MSwitch' ) {
- # backup erstellen
- MSwitch_backup($hash);
- return;
- }
- ##############################
- if ( $cmd eq 'del_delays' ) {
- # löschen aller delays
- MSwitch_Delete_Delay( $hash, $name );
- MSwitch_Createtimer($hash);
- return;
- }
- ##############################
- if ( $cmd eq 'saveconfig' ) {
- # configfile speichern
- $args[0] =~ s/\[s\]/ /g;
- MSwitch_saveconf( $hash, $args[0] );
- return;
- }
- ##############################
- if ( $cmd eq 'savesys' ) {
- # sysfile speichern
- MSwitch_savesys( $hash, $args[0] );
- return;
- }
- ##############################
- if ( $cmd eq "addevent" ) {
- # event manuell zufügen
- my $devName = ReadingsVal( $name, 'Trigger_device', '' );
- $args[0] =~ s/~/ /g;
- my @newevents = split( /,/, $args[0] );
- if ( ReadingsVal( $name, 'Trigger_device', '' ) eq "all_events" ) {
- foreach (@newevents) {
- $hash->{helper}{events}{all_events}{$_} = "on";
- }
- }
- else {
- foreach (@newevents) {
- $hash->{helper}{events}{$devName}{$_} = "on";
- }
- }
- my $events = '';
- my $eventhash = $hash->{helper}{events}{$devName};
- foreach my $name ( keys %{$eventhash} ) {
- $events = $events . $name . '#[tr]';
- }
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- readingsSingleUpdate( $hash, ".Device_Events", $events, 1 );
- return;
- }
- ##############################
- if ( $cmd eq "add_device" ) {
- #add device
- MSwitch_Add_Device( $hash, $args[0] );
- return;
- }
- ##############################
- if ( $cmd eq "del_device" ) {
- #del device
- MSwitch_Del_Device( $hash, $args[0] );
- return;
- }
- ##############################
- if ( $cmd eq "del_trigger" ) {
- #lösche trigger
- MSwitch_Delete_Triggermemory($hash);
- return;
- }
- ##############################
- if ( $cmd eq "filter_trigger" ) {
- #filter to trigger
- MSwitch_Filter_Trigger($hash);
- return;
- }
- ##############################
- if ( $cmd eq "set_trigger" ) {
- # setze trigger
- chop( $args[1], $args[2], $args[3], $args[4], $args[5] );
- my $triggertime = 'on'
- . $args[1] . '~off'
- . $args[2]
- . '~ononly'
- . $args[3]
- . '~offonly'
- . $args[4];
- my $oldtrigger = ReadingsVal( $name, 'Trigger_device', '' );
- readingsSingleUpdate( $hash, "Trigger_device", $args[0], '1' );
- readingsSingleUpdate( $hash, ".Trigger_condition", $args[5], 0 );
- if ( !defined $args[6] ) {
- readingsDelete( $hash, '.Trigger_Whitelist' );
- }
- else {
- readingsSingleUpdate( $hash, ".Trigger_Whitelist", $args[6], 0 );
- }
- my $testtrig = ReadingsVal( $name, 'Trigger_device', '' );
- if ( $oldtrigger ne $args[0] ) {
- MSwitch_Delete_Triggermemory($hash); # lösche alle events
- }
- if ( $args[1] ne ''
- || $args[2] ne ''
- || $args[3] ne ''
- || $args[4] ne '' )
- {
- readingsSingleUpdate( $hash, ".Trigger_time", $triggertime, 0 );
- MSwitch_Createtimer($hash);
- }
- else {
- readingsSingleUpdate( $hash, ".Trigger_time", '', 0 );
- MSwitch_Clear_timer($hash);
- }
- $hash->{helper}{events}{ $args[0] }{'no_trigger'} = "on";
- if ( $args[0] ne 'no_trigger' ) {
- if ( $args[0] eq "all_events" ) {
- delete( $hash->{NOTIFYDEV} );
- if ( ReadingsVal( $name, '.Trigger_Whitelist', '' ) ne '' ) {
- $hash->{NOTIFYDEV} =
- ReadingsVal( $name, '.Trigger_Whitelist', '' );
- }
- }
- else {
- $hash->{NOTIFYDEV} = $args[0];
- my $devices = MSwitch_makeAffected($hash);
- $hash->{DEF} = $args[0] . ' # ' . $devices;
- }
- }
- else {
- $hash->{NOTIFYDEV} = 'no_trigger';
- delete $hash->{DEF};
- }
- return;
- }
- ##############################
- if ( $cmd eq "trigger" ) {
- # setze trigger events
- my $triggeron = '';
- my $triggeroff = '';
- my $triggercmdon = '';
- my $triggercmdoff = '';
- $args[0] =~ s/~/ /g;
- $args[1] =~ s/~/ /g;
- $args[2] =~ s/~/ /g;
- $args[3] =~ s/~/ /g;
- $args[4] =~ s/~/ /g;
- if ( !defined $args[1] ) { $args[1] = "" }
- if ( !defined $args[3] ) { $args[3] = "" }
- $triggeron = $args[0];
- $triggeroff = $args[1];
- if ( !defined $args[3] ) { $args[3] = "" }
- if ( !defined $args[4] ) { $args[4] = "" }
- $triggercmdon = $args[3];
- $triggercmdoff = $args[4];
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, ".Trigger_on", $triggeron );
- readingsBulkUpdate( $hash, ".Trigger_off", $triggeroff );
- if ( $args[2] eq 'nein' ) {
- readingsBulkUpdate( $hash, "Trigger_log", 'off' );
- }
- if ( $args[2] eq 'ja' ) {
- readingsBulkUpdate( $hash, "Trigger_log", 'on' );
- }
- readingsBulkUpdate( $hash, ".Trigger_cmd_on", $triggercmdon );
- readingsBulkUpdate( $hash, ".Trigger_cmd_off", $triggercmdoff );
- readingsEndUpdate( $hash, 0 );
- return;
- }
- ##############################
- if ( $cmd eq "devices" ) {
- # setze devices
- my $devices = $args[0];
- if ( $devices eq 'null' ) {
- readingsSingleUpdate( $hash, ".Device_Affected", 'no_device', 0 );
- return;
- }
- my @olddevices =
- split( /,/, ReadingsVal( $name, '.Device_Affected', 'no_device' ) );
- my @devices = split( /,/, $args[0] );
- my $addolddevice = '';
- foreach (@devices) {
- my $testdev = $_;
- LOOP6: foreach my $olddev (@olddevices) {
- my $oldcmd = '';
- my $oldname = '';
- ( $oldname, $oldcmd ) = split( /-AbsCmd/, $olddev );
- if ( !defined $oldcmd ) { $oldcmd = '' }
- if ( $oldcmd eq '1' ) { next LOOP6 }
- if ( $oldname eq $testdev ) {
- $addolddevice = $addolddevice . $olddev . ',';
- }
- }
- $_ = $_ . '-AbsCmd1';
- }
- chop($addolddevice);
- $devices = join( ',', @devices ) . ',' . $addolddevice;
- my @sortdevices = split( /,/, $devices );
- @sortdevices = sort @sortdevices;
- $devices = join( ',', @sortdevices );
- readingsSingleUpdate( $hash, ".Device_Affected", $devices, 0 );
- $devices = MSwitch_makeAffected($hash);
- if ( defined $hash->{DEF} ) {
- my $devhash = $hash->{DEF};
- my @dev = split( /#/, $devhash );
- $hash->{DEF} = $dev[0] . ' # ' . $devices;
- }
- else {
- $hash->{DEF} = ' # ' . $devices;
- }
- return;
- }
- ##############################
- if ( $cmd eq "details" ) {
- # setze devices details
- $args[0] = urlDecode( $args[0] );
- $args[0] =~ s/#\[pr\]/%/g;
- #devicehasch
- my %devhash = split( /#\[DN\]/, $args[0] );
- my @devices =
- split( /,/, ReadingsVal( $name, '.Device_Affected', '' ) );
- my @inputcmds = split( /#\[ND\]/, $args[0] );
- #my $counter = 0;
- my $error = '';
- my $key = '';
- my $savedetails = '';
- LOOP10: foreach (@devices) {
- my @devicecmds = split( /#\[NF\]/, $devhash{$_} );
- $savedetails = $savedetails . $_ . '#[NF]';
- $savedetails = $savedetails . $devicecmds[0] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[1] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[2] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[3] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[4] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[5] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[7] . '#[NF]';
- $savedetails = $savedetails . $devicecmds[6] . '#[NF]';
- if ( defined $devicecmds[8] ) {
- $savedetails = $savedetails . $devicecmds[8] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '' . '#[NF]';
- }
- if ( defined $devicecmds[9] ) {
- $savedetails = $savedetails . $devicecmds[9] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '' . '#[NF]';
- }
- if ( defined $devicecmds[10] ) {
- $savedetails = $savedetails . $devicecmds[10] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '' . '#[NF]';
- }
- if ( defined $devicecmds[11] ) {
- $savedetails = $savedetails . $devicecmds[11] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '' . '#[NF]';
- }
- # priority
- if ( defined $devicecmds[12] && $devicecmds[12] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[12] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '1' . '#[NF]';
- }
- # id
- if ( defined $devicecmds[13] && $devicecmds[13] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[13] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '0' . '#[NF]';
- }
- # comment
- if ( defined $devicecmds[14] && $devicecmds[14] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[14] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '' . '#[NF]';
- }
- # exit1
- if ( defined $devicecmds[15] && $devicecmds[15] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[15] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '0' . '#[NF]';
- }
- # exit2
- if ( defined $devicecmds[16] && $devicecmds[16] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[16] . '#[NF]';
- }
- else {
- $savedetails = $savedetails . '0' . '#[NF]';
- }
- # show
- if ( defined $devicecmds[17] && $devicecmds[17] ne 'undefined' ) {
- $savedetails = $savedetails . $devicecmds[17] . '#[ND]';
- }
- else {
- $savedetails = $savedetails . '1' . '#[ND]';
- }
- # $counter++;
- }
- chop($savedetails);
- chop($savedetails);
- chop($savedetails);
- chop($savedetails);
- chop($savedetails);
- # ersetzung sonderzeichen etc mscode
- # auskommentierte wurden bereits dur jscript ersetzt
- $savedetails =~ s/\n/#[nl]/g;
- $savedetails =~ s/\t/ /g;
- $savedetails =~ s/ /#[sp]/g;
- $savedetails =~ s/\\/#[bs]/g;
- $savedetails =~ s/,/#[ko]/g;
- $savedetails =~ s/^#\[/#[eo]/g;
- $savedetails =~ s/^#\]/#[ec]/g;
- $savedetails =~ s/\|/#[wa]/g;
- $savedetails =~ s/\|/#[ti]/g;
- readingsSingleUpdate( $hash, ".Device_Affected_Details", $savedetails,
- 0 );
- return;
- }
- ##################################################################
- my $update = '';
- # unbedingt überarbeiten !!!
- my @testdetails =
- qw(_on _off _onarg _offarg _playback _record _timeon _timeoff _conditionon _conditionoff);
- my @testdetailsstandart =
- ( 'no_action', 'no_action', '', '', 'nein', 'nein', 0, 0, '', '' );
- ##################################
- #neu ausführung on/off
- if ( $cmd eq "off" || $cmd eq "on" ) {
- # ausführen des off befehls
- my $zweig = 'nicht definiert';
- $zweig = "cmd1" if $cmd eq "on";
- $zweig = "cmd2" if $cmd eq "off";
- my $exittest = '';
- $exittest = "1" if $cmd eq "on";
- $exittest = "2" if $cmd eq "off";
- my $ekey = '';
- my $out = '0';
- MSwitch_Safemode($hash);
- MSwitch_LOG( $name, 6, "----------------------------------------" );
- MSwitch_LOG( $name, 6, "$name: aufruf on/off -> $cmd" );
- MSwitch_LOG( $name, 6, "----------------------------------------" );
- my @cmdpool;
- my %devicedetails = MSwitch_makeCmdHash($name);
- my @devices =
- split( /,/, ReadingsVal( $name, '.Device_Affected', '' ) );
- # liste anpassen ( reihenfolge ) wenn expert = 1
- @devices = MSwitch_priority( $hash, $execids, @devices );
- LOOP1: foreach my $device (@devices) {
- $out = '0';
- if ( AttrVal( $name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $ekey = $device . "_exit" . $exittest;
- $out = $devicedetails{$ekey};
- }
- MSwitch_LOG( $name, 6,
- "$name: angesprochener zweig "
- . $zweig
- . " -> device -> -"
- . $device
- . "-" );
- # teste auf on kommando
- next LOOP1 if $device eq "no_device";
- my @devicesplit = split( /-AbsCmd/, $device );
- my $devicenamet = $devicesplit[0];
- my $count = 0;
- foreach my $testset (@testdetails) {
- if ( !defined( $devicedetails{ $device . $testset } ) ) {
- my $key = '';
- $key = $device . $testset;
- $devicedetails{$key} = $testdetailsstandart[$count];
- }
- $count++;
- }
- my $key = $device . "_" . $cmd;
- my $timerkey = $device . "_time" . $cmd;
- my $testtstate = $devicedetails{$timerkey};
- # teste auf delayinhalt
- MSwitch_LOG( $name, 6,
- "$name: teste auf timerstatus -> $testtstate" );
- $testtstate =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtstate eq "[:]" || $testtstate eq "[\$:]" ) {
- $devicedetails{$timerkey} =
- eval MSwitch_Checkcond_state( $devicedetails{$timerkey},
- $name );
- if ( $devicedetails{$timerkey} =~ m/[0-9]\d:[0-9]\d:[0-9]\d/ ) {
- MSwitch_LOG( $name, 6, "$name: format ok " );
- my $hdel =
- ( substr( $devicedetails{$timerkey}, 0, 2 ) ) * 3600;
- my $mdel =
- ( substr( $devicedetails{$timerkey}, 3, 2 ) ) * 60;
- my $sdel =
- ( substr( $devicedetails{$timerkey}, 6, 2 ) ) * 1;
- $devicedetails{$timerkey} = $hdel + $mdel + $sdel;
- }
- else {
- MSwitch_LOG( $name, 1,
- "$name: ERROR Timerformat "
- . $devicedetails{$timerkey}
- . " fehlerhaf " );
- $devicedetails{$timerkey} = 0;
- }
- }
- MSwitch_LOG( $name, 6,
- "$name: timerstatus nach test -> "
- . $devicedetails{$timerkey} );
- # suche befehl
- if ( $devicedetails{$key} ne ""
- && $devicedetails{$key} ne "no_action" ) #befehl gefunden
- {
- my $cs = '';
- $cs =
- "set $devicenamet $devicedetails{$device.'_off'} $devicedetails{$device.'_offarg'}"
- if $cmd eq "off";
- $cs =
- "set $devicenamet $devicedetails{$device.'_on'} $devicedetails{$device.'_onarg'}"
- if $cmd eq "on";
- if ( $devicenamet eq 'FreeCmd' ) {
- $cs = "$devicedetails{$device.'_'.$cmd.'arg'}";
- $cs = MSwitch_makefreecmd( $hash, $cs );
- }
- MSwitch_LOG( $name, 6, "$name: befehl gefunden -> " . $cs );
- MSwitch_LOG( $name, 6,
- "$name: teste auf delay -> " . $devicedetails{$timerkey} );
- my $conditionkey = $device . "_condition" . $cmd;
- MSwitch_LOG( $name, 6,
- "$name: TIMERKEY -> " . $devicedetails{$timerkey} );
- if ( $devicedetails{$timerkey} eq "0"
- || $devicedetails{$timerkey} eq "" )
- {
- # $conditionkey = $device . "_conditionoff";
- MSwitch_LOG( $name, 6,
- "$name: teste auf condition -> aufruf sub checkcondition mit "
- . $devicedetails{$conditionkey} )
- if $devicedetails{$conditionkey} ne '';
- MSwitch_LOG( $name, 6,
- "$name: teste auf condition -> wird nicht getestet - kein eintrag"
- . $devicedetails{$conditionkey} )
- if $devicedetails{$conditionkey} eq '';
- my $execute = "true";
- $execute =
- MSwitch_checkcondition( $devicedetails{$conditionkey},
- $name, $args[0] )
- if $devicedetails{$conditionkey} ne '';
- MSwitch_LOG( $name, 6,
- "$name: ergebniss condition -> ergebniss " . $execute );
- if ( $execute eq 'true' ) {
- $cs =~ s/\$NAME/$hash->{helper}{eventfrom}/;
- $cs =~ s/\$SELF/$name/;
- MSwitch_LOG( $name, 6,
- "$name: in exec-cmdpool geschrieben ->" . $cs );
- push @cmdpool, $cs . '|' . $device;
- $update = $device . ',' . $update;
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von "
- . $device );
- last LOOP1;
- }
- }
- }
- else {
- MSwitch_LOG( $name, 6,
- "$name: teste auf condition -> keine vorhanden " );
- if ( AttrVal( $name, 'MSwitch_RandomTime', '' ) ne ''
- && $devicedetails{$timerkey} eq '[random]' )
- {
- MSwitch_LOG( $name, 6,
- "$name: randomtimer gefunden attr gesetzt -> "
- . $devicedetails{$timerkey} );
- $devicedetails{$timerkey} =
- MSwitch_Execute_randomtimer($hash);
- # ersetzt $devicedetails{$timerkey} gegen randomtimer
- MSwitch_LOG( $name, 6,
- "$name: timerd ersetzt-> "
- . $devicedetails{$timerkey} );
- }
- elsif ( AttrVal( $name, 'MSwitch_RandomTime', '' ) eq ''
- && $devicedetails{$timerkey} eq '[random]' )
- {
- MSwitch_LOG( $name, 6,
- "$name: randomtimer gefunden attr nicht gesetzt -> 0"
- );
- $devicedetails{$timerkey} = 0;
- }
- # ?
- my $execute = "true";
- # conditiontest nur dann, wenn cond-test nicht nur nach verzögerung
- if ( $devicedetails{ $device . "_delayat" . $cmd } ne
- "delay2"
- && $devicedetails{ $device . "_delayat" . $cmd } ne
- "at02" )
- {
- MSwitch_LOG( $name, 6,
- "$name: checkcondition bei gefundem delay -> "
- . $devicedetails{ $device . "_delayat" . $cmd } );
- $execute =
- MSwitch_checkcondition( $devicedetails{$conditionkey},
- $name, $args[0] );
- MSwitch_LOG( $name, 6,
- "$name: ergebniss checkcondition für delay-> "
- . $execute );
- }
- MSwitch_LOG( $name, 6,
- "$name: ----------------- Delay -> "
- . $devicedetails{$timerkey} );
- if ( $execute eq 'true' ) {
- MSwitch_LOG( $name, 6,
- "$name: conidtion ok - Befehl mt at/delay wird ausgefuehrt -> "
- . $cs );
- my $delaykey = $device . "_delayat" . $cmd;
- my $delayinhalt = $devicedetails{$delaykey};
- my $delaykey1 = $device . "_delayat" . $cmd . "org";
- my $teststateorg = $devicedetails{$delaykey1};
- MSwitch_LOG( $name, 6,
- "$name: delaykey -> " . $delaykey );
- MSwitch_LOG( $name, 6,
- "$name: delaykeyinhalt -> " . $delayinhalt );
- MSwitch_LOG( $name, 6,
- "$name: delaykeyinhaltorg -> " . $teststateorg );
- if ( $delayinhalt eq 'at0' || $delayinhalt eq 'at1' ) {
- MSwitch_LOG( $name, 6,
- "$name: delay mit at erkannt -> "
- . $devicedetails{$timerkey} );
- MSwitch_LOG( $name, 6,
- "$name: delay wird ersetzt " );
- $devicedetails{$timerkey} =
- MSwitch_replace_delay( $hash, $teststateorg );
- Log3( $name, 6,
- "$name: delay ersetzt -> "
- . $devicedetails{$timerkey} );
- }
- if ( $delayinhalt eq 'at1' || $delayinhalt eq 'delay0' )
- {
- MSwitch_LOG( $name, 6,
- "$name: delay ohne zusatzprüfung erkannt -> "
- . $delayinhalt );
- $conditionkey = 'nocheck';
- MSwitch_LOG( $name, 6,
- "$name: conditionkey ersetzt -> "
- . $conditionkey );
- }
- my $timecond =
- gettimeofday() + $devicedetails{$timerkey};
- my $msg =
- $cs . "#[tr]"
- . $name . "#[tr]"
- . $conditionkey
- . "#[tr]#[tr]"
- . $timecond . "#[tr]"
- . $device;
- # variabelersetzung
- $msg =~ s/\$NAME/$hash->{helper}{eventfrom}/;
- $msg =~ s/\$SELF/$name/;
- $hash->{helper}{delays}{$msg} = $timecond;
- InternalTimer( $timecond, "MSwitch_Restartcmd", $msg );
- MSwitch_LOG( $name, 6,
- "$name: verzögerte befehl gesetzt -> "
- . $timecond . " : "
- . $msg );
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von "
- . $device );
- last LOOP1;
- }
- }
- }
- }
- }
- if ( AttrVal( $name, 'MSwitch_Mode', 'Full' ) ne "Notify" ) {
- readingsSingleUpdate( $hash, "state", $cmd, 1 );
- }
- else {
- readingsSingleUpdate( $hash, "state", 'active', 1 );
- }
- #MSwitch_EventBulk($hash,$args[0],'0','MSwitch_set');
- my $anzahl = @cmdpool;
- MSwitch_LOG( $name, 6,
- "$name: anzahl der auszufuehrenden befehle -> " . $anzahl );
- MSwitch_LOG( $name, 6, "$name: uebergabe an sub execute " )
- if $anzahl > 0;
- MSwitch_Cmd( $hash, @cmdpool ) if $anzahl > 0;
- return;
- }
- return;
- }
- ###################################
- sub MSwitch_Cmd(@) {
- my ( $hash, @cmdpool ) = @_;
- my $Name = $hash->{NAME};
- my %devicedetails = MSwitch_makeCmdHash($Name);
- foreach my $cmds (@cmdpool) {
- MSwitch_LOG( $Name, 6, "$Name: execute -> " . $cmds );
- my @cut = split( /\|/, $cmds );
- $cmds = $cut[0];
- # ersetze platzhakter vor ausführung
- #change # $cmds =~ s/#\[wa\]/|/g; #neu
- my $device = $cut[1];
- my $toggle = '';
- if ( $cmds =~ m/set (.*)(MSwitchtoggle)(.*)/ ) {
- MSwitch_LOG( $Name, 6,
- "$Name: togglemode erkannt -> " . $cmds );
- $toggle = $cmds;
- $cmds = MSwitch_toggle( $hash, $cmds );
- }
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1'
- && $devicedetails{ $device . '_repeatcount' } ne '' )
- {
- MSwitch_LOG( $Name, 6,
- "$Name: teste auf repeatcount -> "
- . $devicedetails{ $device . '_repeatcount' } );
- my $x = 0;
- while ( $devicedetails{ $device . '_repeatcount' } =~
- m/\[(.*)\:(.*)\]/ )
- {
- $x++; # exit
- last if $x > 20; # exitg
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeatcount' } = $setmagic;
- }
- MSwitch_LOG( $Name, 6,
- "$Name: repeatcount nach setmagicersetzung -> "
- . $devicedetails{ $device . '_repeatcount' } );
- }
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1'
- && $devicedetails{ $device . '_repeattime' } ne '' )
- {
- MSwitch_LOG( $Name, 6,
- "$Name: teste auf repeattime -> "
- . $devicedetails{ $device . '_repeattime' } );
- my $x = 0;
- while (
- $devicedetails{ $device . '_repeattime' } =~ m/\[(.*)\:(.*)\]/ )
- {
- $x++; # exit
- last if $x > 20; # exitg
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeattime' } = $setmagic;
- }
- MSwitch_LOG( $Name, 6,
- "$Name: _repeattime nach setmagicersetzung -> "
- . $devicedetails{ $device . '_repeattime' } );
- }
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1'
- && $devicedetails{ $device . '_repeatcount' } > 0
- && $devicedetails{ $device . '_repeattime' } > 0 )
- {
- my $i;
- for (
- $i = 0 ;
- $i <= $devicedetails{ $device . '_repeatcount' } ;
- $i++
- )
- {
- my $msg = $cmds . "|" . $Name;
- if ( $toggle ne '' ) {
- $msg = $toggle . "|" . $Name;
- }
- my $timecond = gettimeofday() +
- ( ( $i + 1 ) * $devicedetails{ $device . '_repeattime' } );
- $msg = $msg . "|" . $timecond;
- $hash->{helper}{repeats}{$timecond} = "$msg";
- MSwitch_LOG( $Name, 6,
- "$Name: repeat gesetzt -> "
- . $timecond . " : "
- . $msg );
- InternalTimer( $timecond, "MSwitch_repeat", $msg );
- }
- }
- my $todec = $cmds;
- $cmds = MSwitch_dec( $hash, $todec );
- MSwitch_LOG( $Name, 6, "$Name: cmd nach decodierung -> " . $cmds );
- ############################
- # debug2 mode , kein execute
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '2' ) {
- MSwitch_LOG( $Name, 6, "$Name: exec comand -> " . $cmds );
- }
- else {
- if ( $cmds =~ m/{.*}/ ) {
- MSwitch_LOG( $Name, 6,
- "$Name: exec als perlcode -> " . $cmds );
- my $out = eval($cmds);
- if ($@) {
- MSwitch_LOG( $Name, 1,
- "$Name MSwitch_Set: ERROR $cmds: $@ " . __LINE__ );
- }
- }
- else {
- MSwitch_LOG( $Name, 6,
- "$Name: execute als fhemcode -> " . $cmds );
- my $errors = AnalyzeCommandChain( undef, $cmds );
- if ( defined($errors) ) {
- MSwitch_LOG( $Name, 1,
- "$Name MSwitch_Set: ERROR $cmds: $errors " . __LINE__ );
- }
- }
- }
- #############################
- }
- my $showpool = join( ',', @cmdpool );
- if ( length($showpool) > 100 ) {
- $showpool = substr( $showpool, 0, 100 ) . '....';
- }
- readingsSingleUpdate( $hash, "Exec_cmd", $showpool, 1 ) if $showpool ne '';
- }
- ####################
- sub MSwitch_toggle($$) {
- my ( $hash, $cmds ) = @_;
- my $Name = $hash->{NAME};
- $cmds =~ m/(set) (.*)( )MSwitchtoggle (.*)/;
- my @tcmd = split( /\//, $4 );
- if ( !defined $tcmd[2] ) { $tcmd[2] = 'state' }
- if ( !defined $tcmd[3] ) { $tcmd[3] = $tcmd[0] }
- if ( !defined $tcmd[4] ) { $tcmd[4] = $tcmd[1] }
- my $cmd1 = $1 . " " . $2 . " " . $tcmd[0];
- my $cmd2 = $1 . " " . $2 . " " . $tcmd[1];
- my $chk1 = $tcmd[0];
- my $chk2 = $tcmd[1];
- my $testnew = ReadingsVal( $2, $tcmd[2], 'undef' );
- if ( $testnew =~ m/$tcmd[3]/ ) {
- $cmds = $cmd2;
- }
- elsif ( $testnew =~ m/$tcmd[4]/ ) {
- $cmds = $cmd1;
- }
- else {
- $cmds = $cmd1;
- }
- return $cmds;
- }
- ##############################
- sub MSwitch_Attr(@) {
- my ( $cmd, $name, $aName, $aVal ) = @_;
- my $hash = $defs{$name};
- if ( $aName eq 'MSwitch_Debug'
- && ( $aVal == 0 || $aVal == 1 || $aVal == 2 || $aVal == 3 ) )
- {
- delete( $hash->{READINGS}{Bulkfrom} );
- delete( $hash->{READINGS}{Device_Affected} );
- delete( $hash->{READINGS}{Device_Affected_Details} );
- delete( $hash->{READINGS}{Device_Events} );
- }
- if ( $aName eq 'MSwitch_RandomTime' && $aVal ne '' ) {
- if ( $aVal !~
- m/([0-9]{2}:[0-9]{2}:[0-9]{2}-[0-9]{2}:[0-9]{2}:[0-9]{2})/ )
- {
- return 'wrong syntax !<br>the syntax must be: HH:MM:SS-HH:MM:SS';
- }
- else {
- $aVal =~ s/\://g;
- my @test = split( /-/, $aVal );
- if ( $test[0] >= $test[1] ) {
- return
- 'fist '
- . $test[0]
- . ' parameter must be lower than second parameter '
- . $test[1];
- }
- }
- return;
- }
- if ( $cmd eq 'set' && $aName eq 'disable' && $aVal == 1 ) {
- $hash->{NOTIFYDEV} = 'no_trigger';
- MSwitch_Delete_Delay( $hash, 'all' );
- MSwitch_Clear_timer($hash);
- }
- if ( $cmd eq 'set' && $aName eq 'disable' && $aVal == 0 ) {
- delete( $hash->{helper}{savemodeblock} );
- delete( $hash->{READINGS}{Safemode} );
- MSwitch_Createtimer($hash);
- }
- if ( $cmd eq 'set'
- && $aName eq 'disable'
- && $aVal == 0
- && ReadingsVal( $name, 'Trigger_device', 'no_trigger' ) ne
- 'no_trigger' )
- {
- $hash->{NOTIFYDEV} =
- ReadingsVal( $name, 'Trigger_device', 'no_trigger' );
- }
- if ( $cmd eq 'del'
- && $aName eq 'disable'
- && ReadingsVal( $name, 'Trigger_device', 'no_trigger' ) ne
- 'no_trigger' )
- {
- $hash->{NOTIFYDEV} =
- ReadingsVal( $name, 'Trigger_device', 'no_trigger' );
- }
- if ( $aName eq 'MSwitch_Activate_MSwitchcmds' && $aVal == 1 ) {
- addToAttrList('MSwitchcmd');
- }
- if ( $aName eq 'MSwitch_Debug' && $aVal eq '0' ) {
- unlink("./log/MSwitch_debug_$name.log");
- }
- if ( $aName eq 'MSwitch_Debug' && $aVal eq '2' || $aVal eq '3' ) {
- MSwitch_clearlog($hash);
- }
- if ( $cmd eq 'set' && $aName eq 'MSwitch_Inforoom' ) {
- my $testarg = $aVal;
- foreach my $testdevices ( keys %{ $modules{MSwitch}{defptr} } ) {
- $attr{$testdevices}{MSwitch_Inforoom} = $testarg;
- }
- }
- if ( $aName eq 'MSwitch_Mode' && ( $aVal eq 'Full' || $aVal eq 'Toggle' ) )
- {
- my $cs = "setstate $name ???";
- my $errors = AnalyzeCommandChain( undef, $cs );
- }
- if ( $aName eq 'MSwitch_Mode' && $aVal eq 'Notify' ) {
- readingsSingleUpdate( $hash, "state", 'active', 1 );
- my $cs = "setstate $name active";
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $name, 1,
- "$name MSwitch_Notify: Fehler bei Befehlsausführung $errors -> Comand: $_ "
- . __LINE__ );
- }
- }
- #############
- if ( $cmd eq 'del' ) {
- my $testarg = $aName;
- my $errors;
- if ( $testarg eq 'MSwitch_Inforoom' ) {
- LOOP21:
- foreach my $testdevices ( keys %{ $modules{MSwitch}{defptr} } ) {
- if ( $testdevices eq $name ) { next LOOP21; }
- delete( $attr{$testdevices}{MSwitch_Inforoom} );
- }
- }
- if ( $testarg eq 'disable' ) {
- MSwitch_Delete_Delay( $hash, "all" );
- MSwitch_Clear_timer($hash);
- delete( $hash->{helper}{savemodeblock} );
- delete( $hash->{READINGS}{Safemode} );
- }
- }
- return undef;
- }
- ####################
- sub MSwitch_Delete($$) {
- my ( $hash, $name ) = @_;
- RemoveInternalTimer($hash);
- return undef;
- }
- ####################
- sub MSwitch_Undef($$) {
- my ( $hash, $name ) = @_;
- RemoveInternalTimer($hash);
- delete( $modules{MSwitch}{defptr}{$name} );
- return undef;
- }
- ####################
- sub MSwitch_Notify($$) {
- my $testtoggle = '';
- my ( $own_hash, $dev_hash ) = @_;
- my $ownName = $own_hash->{NAME}; # own name / hash
- my $devName = $dev_hash->{NAME};
- my $events = deviceEvents( $dev_hash, 1 );
- my $trigevent = '';
- my $eventset = '0';
- my $execids = "0";
- # nur abfragen für eigenes Notify
- if ( $init_done
- && $devName eq "global"
- && grep( m/^MODIFIED $ownName$/, @{$events} ) )
- {
- # reaktion auf eigenes notify start / define / modify
- my $timecond = gettimeofday() + 5;
- InternalTimer( $timecond, "MSwitch_LoadHelper", $own_hash );
- # return;
- }
- if ( $init_done
- && $devName eq "global"
- && grep( m/^DEFINED $ownName$/, @{$events} ) )
- {
- # reaktion auf eigenes notify start / define / modify
- my $timecond = gettimeofday() + 5;
- InternalTimer( $timecond, "MSwitch_LoadHelper", $own_hash );
- # return;
- }
- if ( $devName eq "global"
- && grep( m/^INITIALIZED|REREADCFG$/, @{$events} ) )
- {
- # reaktion auf eigenes notify start / define / modify
- MSwitch_LoadHelper($own_hash);
- # return;
- }
- # nur abfragen für eigenes Notify ENDE
- return ""
- if ( IsDisabled($ownName) )
- ; # Return without any further action if the module is disabled
- # startverzöferung abwarten
- my $startdelay =
- AttrVal( $ownName, 'MSwitch_Startdelay', $standartstartdelay );
- my $diff = int(time) - $fhem_started;
- if ( $diff < $startdelay ) {
- MSwitch_LOG( $ownName, 6,
- 'Anfrage fuer '
- . $ownName
- . ' blockiert - Zeit seit start:'
- . $diff );
- return;
- }
- # safemode testen
- MSwitch_Safemode($own_hash);
- MSwitch_LOG( $ownName, 6, "----------------------------------------" );
- MSwitch_LOG( $ownName, 6,
- "$ownName: eingehendes Event von -> " . $devName );
- MSwitch_LOG( $ownName, 6, "----------------------------------------" );
- # versionscheck
- if ( ReadingsVal( $ownName, '.V_Check', $vupdate ) ne $vupdate ) {
- my $ver = ReadingsVal( $ownName, '.V_Check', '' );
- MSwitch_LOG( $ownName, 4,
- $ownName
- . ' Versionskonflikt, aktion abgebrochen ! erwartet:'
- . $vupdate
- . ' vorhanden:'
- . $ver );
- return;
- }
- if ( AttrVal( $ownName, 'MSwitch_RandomNumber', '' ) ne '' ) {
- # create randomnumber wenn attr an
- MSwitch_Createnumber1($own_hash);
- }
- if ( ReadingsVal( $ownName, "waiting", '0' ) > time ) {
- MSwitch_LOG( $ownName, 6,
- '$ownName: Aktion abgebrochen - wait gesetzt ->'
- . ReadingsVal( $ownName, "waiting", '0' ) );
- # teste auf attr waiting verlesse wenn gesetzt
- return "";
- }
- else {
- # reading löschen
- delete( $own_hash->{READINGS}{waiting} );
- }
-
- MSwitch_LOG( $ownName, 6, "-------------waiting passiert-----------------" );
-
-
- my $incommingdevice = '';
- if ( defined( $own_hash->{helper}{testevent_device} ) ) {
- # unklar
- $events = 'x';
- $incommingdevice = ( $own_hash->{helper}{testevent_device} );
- }
- else {
- $incommingdevice = $dev_hash->{NAME}; # aufrufendes device
- }
- return if ( !$events );
- my $triggerdevice =
- ReadingsVal( $ownName, 'Trigger_device', '' ); # Triggerdevice
- my @cmdarray;
- my @cmdarray1; # enthält auszuführende befehle nach conditiontest
- ########### ggf. löschen
- my $triggeron = ReadingsVal( $ownName, '.Trigger_on', '' );
- my $triggeroff = ReadingsVal( $ownName, '.Trigger_off', '' );
- my $triggercmdon = ReadingsVal( $ownName, '.Trigger_cmd_on', '' );
- my $triggercmdoff = ReadingsVal( $ownName, '.Trigger_cmd_off', '' );
- if ( AttrVal( $ownName, 'MSwitch_Mode', 'Full' ) eq "Notify" ) {
- # passt triggerfelder an attr an
- $triggeron = 'no_trigger';
- $triggeroff = 'no_trigger';
- }
- if ( AttrVal( $ownName, 'MSwitch_Mode', 'Full' ) eq "Toggle" ) {
- # passt triggerfelder an attr an
- $triggeroff = 'no_trigger';
- $triggercmdon = 'no_trigger';
- $triggercmdoff = 'no_trigger';
- }
- my $set = "noset";
- my $eventcopy = "";
- # notify für eigenes device
- my $devcopyname = $devName;
- $own_hash->{helper}{eventfrom} = $devName;
- my @eventscopy;
- if ( defined( $own_hash->{helper}{testevent_event} ) ) {
- # unklar
- # wenn global , sonst ohne 1
- @eventscopy = "$own_hash->{helper}{testevent_event}";
- }
- else {
- @eventscopy = ( @{$events} );
- }
- my $triggerlog = ReadingsVal( $ownName, 'Trigger_log', 'off' );
- if ( $incommingdevice eq $triggerdevice || $triggerdevice eq "all_events" )
- {
- # teste auf triggertreffer oder GLOBAL trigger
- my $activecount = 0;
- my $anzahl;
- EVENT: foreach my $event (@eventscopy) {
- $own_hash->{eventsave} = 'unsaved';
- MSwitch_LOG( $ownName, 6,
- "$ownName: eingehendes Event -> "
- . $incommingdevice . " "
- . $event );
- # durchlauf für jedes ankommende event
- #
- $event = "" if ( !defined($event) );
- $eventcopy = $event;
- $eventcopy =~ s/: /:/s; # BUG !!!!!!!!!!!!!!!!!!!!!!!!
- $event =~ s/: /:/s;
- readingsSingleUpdate( $own_hash, "incomming", $eventcopy, 1 );
- # Teste auf einhaltung Triggercondition für ausführung zweig 1 und zweig 2
- # kann ggf an den anfang der routine gesetzt werden ? test erforderlich
- my $triggercondition =
- ReadingsVal( $ownName, '.Trigger_condition', '' );
- $triggercondition =~ s/#\[dp\]/:/g;
- $triggercondition =~ s/#\[pt\]/./g;
- $triggercondition =~ s/#\[ti\]/~/g;
- $triggercondition =~ s/#\[sp\]/ /g;
- if ( $triggercondition ne '' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: teste Triggercondition -> "
- . $triggercondition );
- my $ret = MSwitch_checkcondition( $triggercondition, $ownName,
- $eventcopy );
- MSwitch_LOG( $ownName, 6,
- "$ownName: ergebniss Triggercondition -> " . $ret );
- if ( $ret eq 'false' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: ergebniss Triggercondition false-> abbruch"
- );
- MSwitch_LOG( $ownName, 6, "-----------------" );
- next EVENT;
- }
- }
- # wird nur ausgefüht wenn ankommende events gelogd werden
- if ( AttrVal( $ownName, 'MSwitch_Trigger_Filter', 'undef' ) ne
- 'undef'
- && AttrVal( $ownName, 'MSwitch_Trigger_Filter', 'undef' ) ne
- "" )
- {
- my $eventcopy1 = $eventcopy;
- if ( $triggerdevice eq "all_events" ) {
- # fügt dem event den devicenamen hinzu , wenn global getriggert wird
- $eventcopy1 = "$devName:$eventcopy";
- }
- my @filters =
- split( /,/,
- AttrVal( $ownName, 'MSwitch_Trigger_Filter', 'undef' ) )
- ; # beinhaltet filter durch komma getrennt
- MSwitch_LOG( $ownName, 5,
- "$ownName: Filtertest Event -> " . $eventcopy );
- foreach my $filter (@filters) {
- if ( $filter eq "*" ) { $filter = ".*"; }
- MSwitch_LOG( $ownName, 5,
- "$ownName: eingehendes Event teste Filter -> "
- . $filter );
- if ( $eventcopy1 =~ m/$filter/ ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: eingehendes Event durch MSwitch_Trigger_Filter ausgefiltert: "
- . $eventcopy1 );
- next EVENT;
- }
- }
- }
- if ( $triggerlog eq 'on' ) {
- if ( $triggerdevice eq "all_events" ) {
- $own_hash->{helper}{events}{'all_events'}
- { $devName . ':' . $eventcopy } = "on";
- }
- else {
- $own_hash->{helper}{events}{$devName}{$eventcopy} = "on";
- }
- }
- ##############################################################################################################
- #anzahl checken / ggf nicht mehr nötig
- #check checken / ggf nicht mehr nötig
- if ( $event ne '' ) {
- my $eventcopy1 = $eventcopy;
- if ( $triggerdevice eq "all_events" ) {
- # fügt dem event den devicenamen hinzu , wenn global getriggert wird
- $eventcopy1 = "$devName:$eventcopy";
- }
- MSwitch_LOG( $ownName, 5, "rufe eventbulk auf" );
- MSwitch_EventBulk( $own_hash, $eventcopy1, '0',
- 'MSwitch_Notify' );
- }
- # Teste auf einhaltung Triggercondition ENDE
- ###############################################################################################################
- my $eventcopy1 = $eventcopy;
- if ( $triggerdevice eq "all_events" ) {
- # fügt dem event den devicenamen hinzu , wenn global getriggert wird
- $eventcopy1 = "$devName:$eventcopy";
- }
- my $direktswitch = 0;
- my @eventsplit = split( /\:/, $eventcopy );
- my $eventstellen = @eventsplit;
- my $testvar = '';
- my $check = 0;
- #test auf zweige cmd1/2 and switch MSwitch on/off
- if ( $triggeron ne 'no_trigger' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger trigger cmd1 -> " );
- $testvar =
- MSwitch_checktrigger( $own_hash, $ownName, $eventstellen,
- $triggeron, $incommingdevice, 'on', $eventcopy,
- @eventsplit );
- if ( $testvar ne 'undef' ) {
- $set = $testvar;
- $check = 1;
- $trigevent = $eventcopy;
- #readingsSingleUpdate( $own_hash, "incomming", $eventcopy, 0 );
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger ergebniss -> " . $testvar );
- }
- if ( $triggeroff ne 'no_trigger' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger trigger cmd2 -> " );
- $testvar =
- MSwitch_checktrigger( $own_hash, $ownName, $eventstellen,
- $triggeroff, $incommingdevice, 'off', $eventcopy,
- @eventsplit );
- if ( $testvar ne 'undef' ) {
- $set = $testvar;
- $check = 1;
- $trigevent = $eventcopy;
- #readingsSingleUpdate( $own_hash, "incomming", $eventcopy, 0 );
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger ergebniss -> " . $testvar );
- }
- #test auf zweige cmd1/2 and switch MSwitch on/off ENDE
- #test auf zweige cmd1/2 only
- # ergebnisse werden in @cmdarray geschrieben
- if ( $triggercmdoff ne 'no_trigger' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger trigger cmd4 -> " );
- $testvar =
- MSwitch_checktrigger( $own_hash, $ownName, $eventstellen,
- $triggercmdoff, $incommingdevice, 'offonly', $eventcopy,
- @eventsplit );
- if ( $testvar ne 'undef' ) {
- push @cmdarray, $own_hash . ',off,check,' . $eventcopy1;
- $check = 1;
- #readingsSingleUpdate( $own_hash, "incomming", $eventcopy, 0 );
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger ergebniss -> " . $testvar );
- }
- if ( $triggercmdon ne 'no_trigger' ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger trigger cmd4 -> " );
- $testvar =
- MSwitch_checktrigger( $own_hash, $ownName, $eventstellen,
- $triggercmdon, $incommingdevice, 'ononly', $eventcopy,
- @eventsplit );
- if ( $testvar ne 'undef' ) {
- push @cmdarray, $own_hash . ',on,check,' . $eventcopy1;
- $check = 1;
- #readingsSingleUpdate( $own_hash, "incomming", $eventcopy, 0 );
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName: checktrigger ergebniss -> " . $testvar );
- }
- #test auf zweige cmd1/2 only ENDE
- $anzahl = @cmdarray;
- MSwitch_LOG( $ownName, 6,
- "$ownName: anzahl gefundener Befehle -> " . $anzahl );
- MSwitch_LOG( $ownName, 6,
- "$ownName: inhalt gefundener Befehle -> @cmdarray" );
- $own_hash->{IncommingHandle} = 'fromnotify';
- #$event =~ s/ //ig; #?
- $event =~ s/~/ /g; #?
- if ( AttrVal( $ownName, 'MSwitch_Mode', 'Full' ) eq "Notify"
- and $activecount == 0 )
- {
- # reading activity aktualisieren
- readingsSingleUpdate( $own_hash, "state", 'active', 1 );
- $activecount = 1;
- }
- # abfrage und setzten von blocking
- # schalte blocking an , wenn anzahl grösser 0 und MSwitch_Wait gesetzt
- my $mswait = $attr{$ownName}{MSwitch_Wait};
- if ( !defined $mswait ) { $mswait = '0'; }
- if ( $anzahl > 0 && $mswait > 0 ) {
- readingsSingleUpdate( $own_hash, "waiting", ( time + $mswait ),
- 0 );
- }
- # abfrage und setzten von blocking ENDE
- if ( AttrVal( $ownName, 'MSwitch_Mode', 'Full' ) eq "Toggle"
- && $set eq 'on' )
- { # umschalten des devices nur im togglemode
- my $cmd = '';
- my $statetest = ReadingsVal( $ownName, 'state', 'on' );
- $cmd = "set $ownName off" if $statetest eq 'on';
- $cmd = "set $ownName on" if $statetest eq 'off';
- MSwitch_LOG( $ownName, 6,
- "$ownName: togglemode execute -> " . $cmd );
- if ( AttrVal( $ownName, 'MSwitch_Debug', "0" ) ne '2' ) {
- my $errors = AnalyzeCommandChain( undef, $cmd );
- if ( defined($errors) ) {
- MSwitch_LOG( $ownName, 1,
- "$ownName MSwitch_Notify: Fehler bei Befehlsausführung $errors -> Comand: $_ "
- . __LINE__ );
- }
- }
- return;
- }
- }
- #ausführen aller cmds in @cmdarray nach triggertest aber vor conditiontest
- #my @cmdarray1; #enthält auszuführende befehle nach conditiontest
- #schaltet zweig 3 und 4
- if ( $anzahl != 0 ) {
- MSwitch_LOG( $ownName, 6,
- "$ownName: abarbeiten aller befehle aus eventprüfung " );
- #aberabeite aller befehlssätze in cmdarray
- MSwitch_Safemode($own_hash);
- LOOP31: foreach (@cmdarray) {
- MSwitch_LOG( $ownName, 6, "$ownName: Befehl -> " . $_ );
- if ( $_ eq 'undef' ) { next LOOP31; }
- my ( $ar1, $ar2, $ar3, $ar4 ) = split( /,/, $_ );
- if ( !defined $ar2 ) { $ar2 = ''; }
- if ( $ar2 eq '' ) { next LOOP31; }
- my $returncmd = 'undef';
- #MSwitch_LOG( $ownName, 0,"$ownName: aufruf execnotif $_ $ar2, $ar3, $ar4 ");
- $returncmd =
- MSwitch_Exec_Notif( $own_hash, $ar2, $ar3, $ar4, $execids );
- #MSwitch_LOG( $ownName, 0,"$ownName: ergebniss execnotif -> ".$returncmd);
- if ( defined $returncmd && $returncmd ne 'undef' ) {
- # datensatz nur in cmdarray1 übernehme wenn
- chop $returncmd; #CHANGE
- MSwitch_LOG( $ownName, 5,
- "$ownName: ergebniss execnotif datensatz to array -> "
- . $returncmd );
- push( @cmdarray1, $returncmd );
- }
- }
- my $befehlssatz = join( ',', @cmdarray1 );
- foreach ( split( /,/, $befehlssatz ) ) {
- my $ecec = $_;
- if ( !$ecec =~ m/set (.*)(MSwitchtoggle)(.*)/ ) {
- if ( AttrVal( $ownName, 'MSwitch_RandomNumber', '' ) ne '' )
- {
- MSwitch_Createnumber($own_hash);
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName: Befehlsausfuehrung -> " . $ecec );
- if ( AttrVal( $ownName, 'MSwitch_Debug', "0" ) ne '2' ) {
- my $errors = AnalyzeCommandChain( undef, $_ );
- if ( defined($errors) ) {
- MSwitch_LOG( $ownName, 1,
- "$ownName MSwitch_Notify: Fehler bei Befehlsausführung $errors -> Comand: $_ "
- . __LINE__ );
- }
- }
- if ( length($ecec) > 100 ) {
- $ecec = substr( $ecec, 0, 100 ) . '....';
- }
- readingsSingleUpdate( $own_hash, "Exec_cmd", $ecec, 1 )
- if $ecec ne '';
- }
- else {
- }
- }
- }
- # ende loopeinzeleventtest
- # schreibe gruppe mit events
- my $events = '';
- my $eventhash = $own_hash->{helper}{events}{$devName};
- if ( $triggerdevice eq "all_events" ) {
- $eventhash = $own_hash->{helper}{events}{all_events};
- }
- else {
- $eventhash = $own_hash->{helper}{events}{$devName};
- }
- foreach my $name ( keys %{$eventhash} ) {
- $events = $events . $name . '#[tr]';
- }
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- if ( $events ne "" ) {
- readingsSingleUpdate( $own_hash, ".Device_Events", $events, 1 );
- }
- # schreiben ende
- # schalte modul an/aus bei entsprechendem notify
- # teste auf condition
- return if $set eq 'noset'; # keine MSwitch on/off incl cmd1/2 gefunden
- ###############################################################################################################
- # schaltet zweig 1 und 2 , wenn $set befehl enthält , es wird nur MSwitch geschaltet, Devices werden dann 'mitgerissen'
- my $cs;
- if ( $triggerdevice eq "all_events" ) {
- $cs = "set $ownName $set $devName:$trigevent";
- }
- else {
- $cs = "set $ownName $set $trigevent";
- }
- MSwitch_LOG( $ownName, 6,
- "$ownName MSwitch_Notif: Befehlsausfuehrung -> $cs " . __LINE__ );
- # variabelersetzung
- $cs =~ s/\$NAME/$own_hash->{helper}{eventfrom}/;
- $cs =~ s/\$SELF/$ownName/;
- if ( AttrVal( $ownName, 'MSwitch_RandomNumber', '' ) ne '' ) {
- MSwitch_Createnumber($own_hash);
- }
- MSwitch_LOG( $ownName, 6, "$ownName: Befehlsausführung -> " . $cs );
- if ( AttrVal( $ownName, 'MSwitch_Debug', "0" ) ne '2' ) {
- my $errors = AnalyzeCommandChain( undef, $cs );
- }
- return;
- }
- }
- #########################
- sub MSwitch_fhemwebFn($$$$) {
- # my $loglevel = 5;
- my ( $FW_wname, $d, $room, $pageHash ) =
- @_; # pageHash is set for summaryFn.
- my $hash = $defs{$d};
- my $Name = $hash->{NAME};
- my $jsvarset = '';
- my $j1 = '';
- my $border = 0;
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '4' ) {
- $border = 0;
- }
- #versetzen nach ATTR
- if ( AttrVal( $Name, 'MSwitch_RandomNumber', '' ) eq '' ) {
- delete( $hash->{READINGS}{RandomNr} );
- delete( $hash->{READINGS}{RandomNr1} );
- }
- ####################
- ### teste auf new defined device
- my $hidden = '';
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '4' ) {
- $hidden = '';
- }
- else {
- $hidden = 'hidden';
- }
- my $triggerdevices = '';
- my $events = ReadingsVal( $Name, '.Device_Events', '' );
- my @eventsall = split( /#\[tr\]/, $events );
- my $Triggerdevice = ReadingsVal( $Name, 'Trigger_device', '' );
- my $triggeron = ReadingsVal( $Name, '.Trigger_on', '' );
- if ( !defined $triggeron ) { $triggeron = "" }
- my $triggeroff = ReadingsVal( $Name, '.Trigger_off', '' );
- if ( !defined $triggeroff ) { $triggeroff = "" }
- my $triggercmdon = ReadingsVal( $Name, '.Trigger_cmd_on', '' );
- if ( !defined $triggercmdon ) { $triggercmdon = "" }
- my $triggercmdoff = ReadingsVal( $Name, '.Trigger_cmd_off', '' );
- if ( !defined $triggercmdoff ) { $triggercmdoff = "" }
- my $disable = "";
- my %korrekt;
- foreach (@eventsall) {
- $korrekt{$_} = 'ok';
- }
- $korrekt{$triggeron} = 'ok';
- $korrekt{$triggeroff} = 'ok';
- $korrekt{$triggercmdon} = 'ok';
- $korrekt{$triggercmdoff} = 'ok';
- my @eventsallnew;
- for my $name ( sort keys %korrekt ) {
- push( @eventsallnew, $name );
- }
- @eventsall = @eventsallnew;
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Notify" ) {
- readingsSingleUpdate( $hash, "state", 'active', 1 );
- $triggeroff = "";
- $triggeron = "";
- }
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Toggle" ) {
- $triggeroff = "";
- $triggercmdoff = "";
- $triggercmdon = "";
- }
- #eigene trigger festlegen
- my $optionon = '';
- my $optiongeneral = '';
- my $optioncmdon = '';
- my $alltriggers = '';
- my $to = '';
- my $toc = '';
- LOOP12: foreach (@eventsall) {
- $alltriggers =
- $alltriggers . "<option value=\"$_\">" . $_ . "</option>";
- if ( $_ eq 'no_trigger' ) {
- next LOOP12;
- }
- if ( $triggeron eq $_ ) {
- $optionon =
- $optionon
- . "<option selected=\"selected\" value=\"$_\">"
- . $_
- . "</option>";
- $to = '1';
- }
- else {
- $optionon = $optionon . "<option value=\"$_\">" . $_ . "</option>";
- }
- if ( $triggercmdon eq $_ ) {
- $optioncmdon =
- $optioncmdon
- . "<option selected=\"selected\" value=\"$_\">"
- . $_
- . "</option>";
- $toc = '1';
- }
- else {
- $optioncmdon =
- $optioncmdon . "<option value=\"$_\">" . $_ . "</option>";
- }
- #################### nur bei entsprechender regex
- my $test = $_;
- if ( $test =~ m/(.*)\((.*)\)(.*)/ ) {
- }
- else {
- if ( index( $_, '*', 0 ) == -1 ) {
- if (
- ReadingsVal( $Name, 'Trigger_device', '' ) ne "all_events" )
- {
- $optiongeneral =
- $optiongeneral
- . "<option value=\"$_\">"
- . $_
- . "</option>";
- }
- else {
- $optiongeneral =
- $optiongeneral
- . "<option value=\"$_\">"
- . $_
- . "</option>";
- }
- }
- }
- #####################
- }
- if ( $to eq '1' ) {
- $optionon =
- "<option value=\"no_trigger\">no_trigger</option>" . $optionon;
- }
- else {
- $optionon =
- "<option selected=\"selected\" value=\"no_trigger\">no_trigger</option>"
- . $optionon;
- }
- if ( $toc eq '1' ) {
- $optioncmdon =
- "<option value=\"no_trigger\">no_trigger</option>" . $optioncmdon;
- }
- else {
- $optioncmdon =
- "<option selected=\"selected\" value=\"no_trigger\">no_trigger</option>"
- . $optioncmdon;
- }
- my $optioncmdoff = '';
- my $optionoff = '';
- $to = '';
- $toc = '';
- LOOP14: foreach (@eventsall) {
- if ( $_ eq 'no_trigger' ) { next LOOP14 }
- if ( $triggeroff eq $_ ) {
- $optionoff = $optionoff
- . "<option selected=\"selected\" value=\"$_\">$_</option>";
- $to = '1';
- }
- else {
- $optionoff = $optionoff . "<option value=\"$_\">$_</option>";
- }
- if ( $triggercmdoff eq $_ ) {
- $optioncmdoff = $optioncmdoff
- . "<option selected=\"selected\" value=\"$_\">$_</option>";
- $toc = '1';
- }
- else {
- $optioncmdoff = $optioncmdoff . "<option value=\"$_\">$_</option>";
- }
- }
- if ( $to eq '1' ) {
- $optionoff =
- "<option value=\"no_trigger\">no_trigger</option>" . $optionoff;
- }
- else {
- $optionoff =
- "<option selected=\"selected\" value=\"no_trigger\">no_trigger</option>"
- . $optionoff;
- }
- if ( $toc eq '1' ) {
- $optioncmdoff =
- "<option value=\"no_trigger\">no_trigger</option>" . $optioncmdoff;
- }
- else {
- $optioncmdoff =
- "<option selected=\"selected\" value=\"no_trigger\">no_trigger</option>"
- . $optioncmdoff;
- }
- $optionon =~ s/\[bs\]/|/g;
- $optionoff =~ s/\[bs\]/|/g;
- $optioncmdon =~ s/\[bs\]/|/g;
- $optioncmdoff =~ s/\[bs\]/|/g;
- ####################
- # mögliche affected devices und mögliche triggerdevices
- my $devicesets;
- my $deviceoption = "";
- my $selected = "";
- my $errors = "";
- my $javaform = ""; # erhält javacode für übergabe devicedetail
- my $cs = "";
- my %cmdsatz; # ablage desbefehlssatzes jedes devices
- my $globalon = 'off';
- if ( ReadingsVal( $Name, 'Trigger_device', 'no_trigger' ) eq 'no_trigger' )
- {
- $triggerdevices =
- "<option selected=\"selected\" value=\"no_trigger\">no_trigger</option>";
- }
- else {
- $triggerdevices = "<option value=\"no_trigger\">no_trigger</option>";
- }
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- if ( ReadingsVal( $Name, 'Trigger_device', 'no_trigger' ) eq
- 'all_events' )
- {
- $triggerdevices .=
- "<option selected=\"selected\" value=\"all_events\">GLOBAL</option>";
- $globalon = 'on';
- }
- else {
- $triggerdevices .= "<option value=\"all_events\">GLOBAL</option>";
- }
- }
- my @notype = split( / /, AttrVal( $Name, 'MSwitch_Ignore_Types', "" ) );
- my $affecteddevices = ReadingsVal( $Name, '.Device_Affected', 'no_device' );
- # affected devices to hash
- my %usedevices;
- my @deftoarray = split( /,/, $affecteddevices );
- my $anzahl = @deftoarray;
- my $anzahl1 = @deftoarray;
- my $anzahl3 = @deftoarray;
- my @testidsdev = split( /#\[ND\]/,
- ReadingsVal( $Name, '.Device_Affected_Details', 'no_device' ) );
- #PRIORITY
- # teste auf grössere PRIORITY als anzahl devices
- foreach (@testidsdev) {
- MSwitch_LOG( $Name, 5, "dev @testidsdev" );
- my @testid = split( /#\[NF\]/, $_ );
- my $x = 0;
- #foreach (@testid)
- #{
- #MSwitch_LOG( $Name, 0, "devfelder $x -> $testid[$x]");
- #$x++;
- #}
- MSwitch_LOG( $Name, 5, "devfelder @testid" );
- my $id = $testid[13];
- MSwitch_LOG( $Name, 5, "id $id" );
- $anzahl = $id if $id > $anzahl;
- }
- #################################
- my $reihenfolgehtml = "";
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $reihenfolgehtml = "<select name = 'reihe' id=''>";
- for ( my $i = 1 ; $i < $anzahl + 1 ; $i++ ) {
- $reihenfolgehtml .= "<option value='$i'>$i</option>";
- }
- $reihenfolgehtml .= "</select>";
- }
- #########################################
- #SHOW
- # teste auf grössere PRIORITY als anzahl devices
- foreach (@testidsdev)
- #if (1 == 2)
- {
- MSwitch_LOG( $Name, 5, "dev @testidsdev" );
- my @testid = split( /#\[NF\]/, $_ );
- my $x = 0;
- #foreach (@testid)
- #{
- #MSwitch_LOG( $Name, 0, "devfelder $x -> $testid[$x]");
- #$x++;
- #}
- MSwitch_LOG( $Name, 5, "devfelder @testid" );
- my $id = $testid[18];
- MSwitch_LOG( $Name, 5, "id $id" );
- $anzahl1 = $id if $id > $anzahl;
- }
- #################################
- my $showfolgehtml = "";
- $showfolgehtml = "<select name = 'showreihe' id=''>";
- for ( my $i = 1 ; $i < $anzahl1 + 1 ; $i++ ) {
- $showfolgehtml .= "<option value='$i'>$i</option>";
- }
- $showfolgehtml .= "</select>";
- ######################################
- #ID
- my $idfolgehtml = "";
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $idfolgehtml = "<select name = 'idreihe' id=''>";
- for ( my $i = -1 ; $i < $anzahl3 + 1 ; $i++ ) {
- $idfolgehtml .= "<option value='$i'>$i</option>" if $i > 0;
- $idfolgehtml .= "<option value='$i'>-</option>" if $i == 0;
- }
- $idfolgehtml .= "</select>";
- }
- foreach (@deftoarray) {
- my ( $a, $b ) = split( /-/, $_ );
- $usedevices{$a} = 'on';
- }
- LOOP9: for my $name ( sort keys %defs ) {
- my $selectedtrigger = '';
- my $devicealias = AttrVal( $name, 'alias', "" );
- my $devicewebcmd =
- AttrVal( $name, 'webCmd', "noArg" ); # webcmd des devices
- my $devicehash = $defs{$name}; #devicehash
- my $deviceTYPE = $devicehash->{TYPE};
- # triggerfile erzeugen
- foreach (@notype) {
- if ( lc($_) eq lc($deviceTYPE) ) { next LOOP9; }
- }
- if ( ReadingsVal( $Name, 'Trigger_device', '' ) eq $name ) {
- $selectedtrigger = 'selected=\"selected\"';
- if ( $name eq 'all_events' ) { $globalon = 'on' }
- }
- $triggerdevices .=
- "<option $selectedtrigger value=\"$name\">$name (a:$devicealias t:$deviceTYPE)</option>";
- # filter auf argumente on oder off ;
- if ( $name eq '' ) { next LOOP9; }
- my $cs = "set $name ?";
- # abfrage und auswertung befehlssatz
- if ( AttrVal( $Name, 'MSwitch_Include_Devicecmds', "1" ) eq '1' ) {
- $errors = AnalyzeCommandChain( undef, $cs );
- if ($errors) { }
- }
- else {
- $errors = '';
- }
- if ( !defined $errors ) { $errors = '' }
- my @tmparg = split( /of /, $errors );
- if ( !defined $tmparg[1] ) { $tmparg[1] = "" }
- #if ( defined $tmparg[1] && $tmparg[1] ne '' ) { $errors = $tmparg[1]; }
- if ( $tmparg[1] ne '' ) {
- $errors = $tmparg[1];
- }
- else {
- $errors = '';
- }
- $errors = '|' . $errors;
- $errors =~ s/\| //g;
- $errors =~ s/\|//g;
- if ( $errors eq ''
- && AttrVal( $Name, 'MSwitch_Include_Webcmds', "1" ) eq '1' )
- {
- if ( $devicewebcmd ne "noArg" ) {
- my $device = '';
- my @webcmd = split( /:/, $devicewebcmd );
- foreach (@webcmd) {
- $_ =~ tr/ /:/;
- my @parts = split( /:/, $_ );
- if ( !defined $parts[1] || $parts[1] eq '' ) {
- $device .= $parts[0] . ':noArg ';
- }
- else {
- $device .= $parts[0] . ':' . $parts[1] . ' ';
- }
- }
- chop $device;
- $devicewebcmd = $device;
- $errors = $devicewebcmd;
- }
- }
- my $usercmds = AttrVal( $name, 'MSwitchcmd', '' );
- if ( $usercmds ne ''
- && AttrVal( $Name, 'MSwitch_Include_MSwitchcmds', "1" ) eq '1' )
- {
- $usercmds =~ tr/:/ /;
- $errors .= ' ' . $usercmds;
- }
- my $extensions = AttrVal( $Name, 'MSwitch_Extensions', "0" );
- if ( $extensions eq '1' ) {
- $errors .= ' ' . 'MSwitchtoggle';
- }
- if ( $errors ne '' ) {
- $selected = "";
- if ( exists $usedevices{$name} && $usedevices{$name} eq 'on' ) {
- $selected = "selected=\"selected\" ";
- }
- $deviceoption =
- $deviceoption
- . "<option "
- . $selected
- . "value=\""
- . $name . "\">"
- . $name . " (a:"
- . $devicealias
- . ")</option>";
- # befehlssatz für device in scalar speichern
- $cmdsatz{$name} = $errors;
- }
- else { }
- }
- my $select = index( $affecteddevices, 'FreeCmd', 0 );
- $selected = "";
- if ( $select > -1 ) { $selected = "selected=\"selected\" " }
- $deviceoption =
- "<option "
- . "value=\"FreeCmd\" "
- . $selected
- . ">Free Cmd (nicht an ein Device gebunden)</option>"
- . $deviceoption;
- $select = index( $affecteddevices, 'MSwitch_Self', 0 );
- $selected = "";
- if ( $select > -1 ) { $selected = "selected=\"selected\" " }
- $deviceoption =
- "<option "
- . "value=\"MSwitch_Self\" "
- . $selected
- . ">MSwitch_Self ("
- . $Name
- . ")</option>"
- . $deviceoption;
- ####################
- # #devices details
- # detailsatz in scalar laden
- # my @devicedatails = split(/:/,ReadingsVal($Name, '.Device_Affected_Details', '')); #inhalt decice und cmds # durch komma getrennt
- my %savedetails = MSwitch_makeCmdHash($Name);
- my $detailhtml = "";
- my @affecteddevices =
- split( /,/, ReadingsVal( $Name, '.Device_Affected', 'no_device' ) );
- #####################################
- MSwitch_LOG( $Name, 5, "$Name: -> @affecteddevices" );
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1'
- && ReadingsVal( $Name, '.sortby', 'none' ) eq 'priority' )
- {
- #sortieren
- my $typ = "_priority";
- @affecteddevices = MSwitch_sort( $hash, $typ, @affecteddevices );
- }
- if ( ReadingsVal( $Name, '.sortby', 'none' ) eq 'show' ) {
- #sortieren
- my $typ = "_showreihe";
- @affecteddevices = MSwitch_sort( $hash, $typ, @affecteddevices );
- }
- MSwitch_LOG( $Name, 5, "$Name: -> @affecteddevices" );
- ######################################
- if ( $affecteddevices[0] ne 'no_device' ) {
- $detailhtml =
- "<table border='$border' class='block wide' id='MSwitchDetails' nm='MSwitch'>
- <tr class='even'>
- <td colspan='5'>device actions sortby:
- <input type='hidden' id='affected' name='affected' size='40' value ='"
- . ReadingsVal( $Name, '.Device_Affected', 'no_device' ) . "'>";
- my $select = ReadingsVal( $Name, '.sortby', 'none' );
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) ne '1'
- && $select eq 'priority' )
- {
- $select = 'none';
- readingsSingleUpdate( $hash, ".sortby", $select, 0 );
- }
- my $nonef = "";
- #my $namef ="";
- my $priorityf = "";
- my $showf = "";
- $nonef = 'selected="selected"' if $select eq 'none';
- $priorityf = 'selected="selected"' if $select eq 'priority';
- $showf = 'selected="selected"' if $select eq 'show';
- $detailhtml .= '
- <select name="sort" id="sort" onchange="changesort()" >
- <option value="none" ' . $nonef . '>None</option>';
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $detailhtml .=
- '<option value="priority" '
- . $priorityf
- . '>Field Priority</option>';
- }
- $detailhtml .=
- '<option value="show" ' . $showf . '>Field Show</option>';
- $detailhtml .= "<br> </td></tr>"; #start
- my $alert;
- foreach (@affecteddevices) {
- $alert = '';
- my @devicesplit = split( /-AbsCmd/, $_ );
- my $devicenamet = $devicesplit[0];
- # prüfe auf nicht vorhandenes device
- if ( $devicenamet ne "FreeCmd"
- && $devicenamet ne "MSwitch_Self"
- && !defined $cmdsatz{$devicenamet} )
- {
- $alert =
- '<div style="color: #FF0000">Achtung: Dieses Device ist nicht vorhanden , bitte mit "set changed_renamed" korrigieren !</div>';
- $cmdsatz{$devicenamet} = $savedetails{ $_ . '_on' } . " "
- . $savedetails{ $_ . '_off' };
- }
- my $zusatz = "";
- my $add = $devicenamet;
- if ( $devicenamet eq "MSwitch_Self" ) {
- $devicenamet = $Name;
- $zusatz = "MSwitch_Self -> ";
- $add = "MSwitch_Self";
- }
- my $devicenumber = $devicesplit[1];
- my @befehlssatz = '';
- if ( $devicenamet eq "FreeCmd" ) {
- $cmdsatz{$devicenamet} = '';
- }
- @befehlssatz = split( / /, $cmdsatz{$devicenamet} );
- my $aktdevice = $_;
- ## optionen erzeugen
- my $option1html = '';
- my $option2html = '';
- my $selectedhtml = "";
- if ( !defined( $savedetails{ $aktdevice . '_on' } ) ) {
- my $key = '';
- $key = $aktdevice . "_on";
- $savedetails{$key} = 'no_action';
- }
- if ( !defined( $savedetails{ $aktdevice . '_off' } ) ) {
- my $key = '';
- $key = $aktdevice . "_off";
- $savedetails{$key} = 'no_action';
- }
- if ( !defined( $savedetails{ $aktdevice . '_onarg' } ) ) {
- my $key = '';
- $key = $aktdevice . "_onarg";
- $savedetails{$key} = '';
- }
- if ( !defined( $savedetails{ $aktdevice . '_offarg' } ) ) {
- my $key = '';
- $key = $aktdevice . "_offarg";
- $savedetails{$key} = '';
- }
- if ( !defined( $savedetails{ $aktdevice . '_delayaton' } ) ) {
- my $key = '';
- $key = $aktdevice . "_delayaton";
- $savedetails{$key} = 'delay1';
- }
- if ( !defined( $savedetails{ $aktdevice . '_delayatoff' } ) ) {
- my $key = '';
- $key = $aktdevice . "_delayatoff";
- $savedetails{$key} = 'delay1';
- }
- if ( !defined( $savedetails{ $aktdevice . '_timeon' } ) ) {
- my $key = '';
- $key = $aktdevice . "_timeon";
- $savedetails{$key} = '000000';
- }
- if ( !defined( $savedetails{ $aktdevice . '_timeoff' } ) ) {
- my $key = '';
- $key = $aktdevice . "_timeoff";
- $savedetails{$key} = '000000';
- }
- if ( !defined( $savedetails{ $aktdevice . '_conditionon' } ) ) {
- my $key = '';
- $key = $aktdevice . "_conditionon";
- $savedetails{$key} = '';
- }
- if ( !defined( $savedetails{ $aktdevice . '_conditionoff' } ) ) {
- my $key = '';
- $key = $aktdevice . "_conditionoff";
- $savedetails{$key} = '';
- }
- foreach (@befehlssatz) #befehlssatz einfügen
- {
- my @aktcmdset =
- split( /:/, $_ ); # befehl von noarg etc. trennen
- $selectedhtml = "";
- next if !defined $aktcmdset[0]; #changed 19.06
- if ( $aktcmdset[0] eq $savedetails{ $aktdevice . '_on' } ) {
- $selectedhtml = "selected=\"selected\"";
- }
- $option1html = $option1html
- . "<option $selectedhtml value=\"$aktcmdset[0]\">$aktcmdset[0]</option>";
- $selectedhtml = "";
- if ( $aktcmdset[0] eq $savedetails{ $aktdevice . '_off' } ) {
- $selectedhtml = "selected=\"selected\"";
- }
- $option2html = $option2html
- . "<option $selectedhtml value=\"$aktcmdset[0]\">$aktcmdset[0]</option>";
- }
- if ( '' eq $savedetails{ $aktdevice . '_delayaton' } ) {
- $savedetails{ $aktdevice . '_delayaton' } = 'delay1';
- }
- if ( '' eq $savedetails{ $aktdevice . '_delayatoff' } ) {
- $savedetails{ $aktdevice . '_delayatoff' } = 'delay1';
- }
- if ( '' eq $savedetails{ $aktdevice . '_timeoff' } ) {
- $savedetails{ $aktdevice . '_timeoff' } = '0';
- }
- if ( '' eq $savedetails{ $aktdevice . '_timeon' } ) {
- $savedetails{ $aktdevice . '_timeon' } = '0';
- }
- $savedetails{ $aktdevice . '_onarg' } =~ s/#\[ti\]/~/g;
- $savedetails{ $aktdevice . '_offarg' } =~ s/#\[ti\]/~/g;
- $savedetails{ $aktdevice . '_onarg' } =~ s/#\[wa\]/|/g; #neu
- $savedetails{ $aktdevice . '_offarg' } =~ s/#\[wa\]/|/g; #neu
- my $dalias = '';
- if ( $devicenamet ne "FreeCmd" ) {
- $dalias = "(a: " . AttrVal( $devicenamet, 'alias', "no" ) . ")"
- if AttrVal( $devicenamet, 'alias', "no" ) ne "no";
- }
- my $realname = '';
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '4' ) {
- $realname =
- "<input id='' name='devicename"
- . $_
- . "' size='20' value ='"
- . $_ . "'>";
- }
- else {
- $realname =
- "<input type='$hidden' id='' name='devicename"
- . $_
- . "' size='20' value ='"
- . $_ . "'>";
- }
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $detailhtml = $detailhtml . "
- <tr class='odd'>
- <td colspan='4' class='col1' style=\"width: 100%\">";
- $detailhtml = $detailhtml
- . "$zusatz $devicenamet $realname  $dalias $alert
- </td>";
- ###################### priority
- my $aktfolge = $reihenfolgehtml;
- my $newname = "reihe" . $_;
- my $tochange =
- "<option value='$savedetails{ $aktdevice . '_priority' }'>$savedetails{ $aktdevice . '_priority' }</option>";
- my $change =
- "<option selected value='$savedetails{ $aktdevice . '_priority' }'>$savedetails{ $aktdevice . '_priority' }</option>";
- $aktfolge =~ s/reihe/$newname/g;
- $aktfolge =~ s/$tochange/$change/g;
- $detailhtml = $detailhtml
- . "<td nowrap style='text-align: right;' class='col1'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('priority')\"> ";
- }
- $detailhtml = $detailhtml . "priority: " . $aktfolge . " ";
- # ende
- # show
- #showfolgehtml
- $aktfolge = $showfolgehtml;
- $newname = "showreihe" . $_;
- $tochange =
- "<option value='$savedetails{ $aktdevice . '_showreihe' }'>$savedetails{ $aktdevice . '_showreihe' }</option>";
- $change =
- "<option selected value='$savedetails{ $aktdevice . '_showreihe' }'>$savedetails{ $aktdevice . '_showreihe' }</option>";
- $aktfolge =~ s/showreihe/$newname/g;
- $aktfolge =~ s/$tochange/$change/g;
- $detailhtml = $detailhtml . "show: " . $aktfolge . " ";
- # ID
- $aktfolge = $idfolgehtml;
- $newname = "idreihe" . $_;
- $tochange =
- "<option value='$savedetails{ $aktdevice . '_id' }'>$savedetails{ $aktdevice . '_id' }</option>";
- $change =
- "<option selected value='$savedetails{ $aktdevice . '_id' }'>$savedetails{ $aktdevice . '_id' }</option>";
- $aktfolge =~ s/idreihe/$newname/g;
- $aktfolge =~ s/$tochange/$change/g;
- $detailhtml = $detailhtml . "ID: " . $aktfolge;
- $detailhtml = $detailhtml . "</td>";
- # ende
- }
- else {
- $detailhtml = $detailhtml . "
- <tr class='odd'>
- <td colspan='5' class='col1'>";
- $detailhtml = $detailhtml
- . "$zusatz $devicenamet $realname  $dalias $alert
- </td>";
- my $aktfolge = $showfolgehtml;
- my $newname = "showreihe" . $_;
- my $tochange =
- "<option value='$savedetails{ $aktdevice . '_showreihe' }'>$savedetails{ $aktdevice . '_showreihe' }</option>";
- my $change =
- "<option selected value='$savedetails{ $aktdevice . '_showreihe' }'>$savedetails{ $aktdevice . '_showreihe' }</option>";
- $aktfolge =~ s/showreihe/$newname/g;
- $aktfolge =~ s/$tochange/$change/g;
- $detailhtml = $detailhtml
- . "<td nowrap style='text-align: right;' class='col1'>";
- $detailhtml = $detailhtml . "show: " . $aktfolge . " ";
- }
- $detailhtml = $detailhtml . "</td></tr>";
- my $noschow = "style=\"display:none\"";
- if ( AttrVal( $Name, 'MSwitch_Comments', "0" ) eq '1' ) {
- $noschow = '';
- }
- $detailhtml = $detailhtml . "<tr class='odd' $noschow>
- <td style='vertical-align:middle' colspan='5' class='col1'>
- <textarea class=\"devdetails\" cols='100' rows='1' id='cmdcomment"
- . $_
- . "1' name='cmdcomment"
- . $_ . "'>"
- . $savedetails{ $aktdevice . '_comment' }
- . "</textarea>
- </td>
- </tr>";
- $detailhtml = $detailhtml . "<tr class=''>";
- my $rephide = "style='display:none;'";
- my $rows = 7;
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $rephide = '';
- $rows = 8;
- }
- $detailhtml = $detailhtml
- . "<td rowspan='$rows' class='col2'> ";
- if ( $devicenamet ne 'FreeCmd' ) {
- $detailhtml = $detailhtml . "</td>
- <td nowrap class='col2' style='text-align: left;'>
- <table border='0'><tr>
- <td nowrap class='col2' style='text-align: left;'>
- <br>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('onoff')\"> ";
- }
- $detailhtml = $detailhtml . "MSwitch 'cmd1':
- Set <select class=\"devdetails2\" id='"
- . $_
- . "_on' name='cmdon"
- . $_
- . "' onchange=\"javascript: activate(document.getElementById('"
- . $_
- . "_on').value,'"
- . $_
- . "_on_sel','"
- . $cmdsatz{$devicenamet}
- . "','cmdonopt"
- . $_
- . "1')\" >
- <option value='no_action'>no_action</option>";
- $detailhtml = $detailhtml . $option1html;
- $detailhtml = $detailhtml . "
- </select>
- <td nowrap valign=bottom id='" . $_ . "_on_sel'> </td>
- </tr></table>
- <td nowrap>
- </td>
-
- <td class='col2' style=\"width: 100%\"> <br><input type='$hidden' id='cmdseton"
- . $_
- . "' name='cmdseton"
- . $_
- . "' size='20' value ='"
- . $cmdsatz{$devicenamet} . "'>
- <input type='$hidden' id='cmdonopt"
- . $_
- . "1' name='cmdonopt"
- . $_
- . "' size='20' value ='"
- . $savedetails{ $aktdevice . '_onarg' }
- . "'> ";
- }
- else {
- $savedetails{ $aktdevice . '_onarg' } =~ s/'/'/g;
- $detailhtml = $detailhtml . "</td>
- <td class='col2' nowrap style='text-align: left;vertical-align: middle;'>
- <table><tr>
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('onoff')\"> ";
- }
- $detailhtml = $detailhtml . "MSwitch 'cmd1':</td>
- <td><textarea class=\"devdetails\" cols='50' rows='3' id='cmdonopt"
- . $_
- . "1' name='cmdonopt"
- . $_ . "'
- >" . $savedetails{ $aktdevice . '_onarg' } . "</textarea>
- </td>
- </tr></table>
- </td>";
- $detailhtml = $detailhtml . "
- <td style='text-align: left;' class='col2' nowrap id='" . $_
- . "_on_sel'></td>
- <td nowrap><input type='$hidden' id='"
- . $_
- . "_on' name='cmdon"
- . $_
- . "' size='20' value ='cmd'></td>
- <td class='col2' style=\"width: 100%\"> <br><input type='$hidden' id='cmdseton"
- . $_ . "' name='cmdseton" . $_ . "' size='20' value ='cmd'>";
- }
- $detailhtml = $detailhtml . "</td><td></td></tr>";
- # block off #$devicename
- if ( $devicenamet ne 'FreeCmd' ) {
- $detailhtml = $detailhtml . "
- <tr class='even'>
- <td class='col2' nowrap style='text-align: left;'>
- <table><tr>
- <td class='col2' nowrap style='text-align: left;'>
- ";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('onoff')\"> ";
- }
- $detailhtml = $detailhtml . "MSwitch 'cmd2':
- Set <select class=\"devdetails2\" id='"
- . $_
- . "_off' name='cmdoff"
- . $_
- . "' onchange=\"javascript: activate(document.getElementById('"
- . $_
- . "_off').value,'"
- . $_
- . "_off_sel','"
- . $cmdsatz{$devicenamet}
- . "','cmdoffopt"
- . $_
- . "1')\" >
- <option value='no_action'>no_action</option>";
- $detailhtml = $detailhtml
- . $option2html; #achtung tausch $_ devicenamet oben unten
- $detailhtml = $detailhtml . "
- </select>
- </td>
- <td class='col2' nowrap id='" . $_ . "_off_sel' > </td>
- </tr></table>
- </td>
- <td></td>
-
- <td class='col2' nowrap>
- <input type='$hidden' id='cmdsetoff"
- . $_
- . "' name='cmdsetoff"
- . $_
- . "' size='20' value ='"
- . $cmdsatz{$devicenamet} . "'>
- <input type='$hidden' id='cmdoffopt"
- . $_
- . "1' name='cmdoffopt"
- . $_
- . "' size='20' value ='"
- . $savedetails{ $aktdevice . '_offarg' }
- . "'> ";
- }
- else {
- $savedetails{ $aktdevice . '_offarg' } =~ s/'/'/g;
- $detailhtml = $detailhtml . "
- <tr class='even'>
- <td class='col2' nowrap style='text-align: left;'>
-
- <table><tr>
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('onoff')\"> ";
- }
- $detailhtml = $detailhtml . "MSwitch 'cmd2':</td>
- <td>
- <textarea class=\"devdetails\" cols='50' rows='3' id='cmdoffopt"
- . $_ . "1' name='cmdoffopt" . $_ . "'
- >" . $savedetails{ $aktdevice . '_offarg' } . "</textarea>
- </td>
- </tr></table>
- </td>
- <td style='text-align: left;' class='col2' nowrap id='" . $_
- . "_off_sel' ></td>
- <td><input type='$hidden' id='"
- . $_
- . "_off' name='cmdoff"
- . $_
- . "' size='20' value ='cmd'></td>
- <td class='col2' nowrap>
- <input type='$hidden' id='cmdsetoff"
- . $_
- . "' name='cmdsetoff"
- . $_
- . "' size='20' value ='cmd'>";
- }
- $detailhtml = $detailhtml . "</td><td></td></tr>";
- $detailhtml = $detailhtml . "
- <tr class='even'>
- <td class='col2' colspan='4' nowrap style='text-align: left;'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('condition')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "'cmd1' condition: <input class=\"devdetails\" type='text' id='conditionon"
- . $_
- . "' name='conditionon"
- . $_
- . "' size='55' value ='"
- . $savedetails{ $aktdevice . '_conditionon' }
- . "' onClick=\"javascript:bigwindow(this.id);\"> ";
- my $exit1 = '';
- $exit1 = 'checked' if $savedetails{ $aktdevice . '_exit1' } eq '1';
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('exit')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "<input type=\"checkbox\" $exit1 name='exit1"
- . $_
- . "' /> execute and exit if applies";
- }
- else {
- $detailhtml =
- $detailhtml
- . "<input hidden type=\"checkbox\" $exit1 name='exit1"
- . $_ . "' /> ";
- }
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1' ) {
- $detailhtml =
- $detailhtml
- . "<input name='info' type='button' value='check condition' onclick=\"javascript: checkcondition('conditionon"
- . $_
- . "',document.querySelector('#checkon"
- . $_
- . "').value)\"> with \$EVENT=<select id = \"checkon"
- . $_
- . "\" name=\"checkon"
- . $_ . "\">"
- . $optiongeneral
- . "</select>";
- }
- #alltriggers
- $detailhtml = $detailhtml . "</td></tr>
- <tr class='even'>
- <td class='col2' colspan='4' nowrap style='text-align: left;'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('condition')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "'cmd2' condition: <input class=\"devdetails\" type='text' id='conditionoff"
- . $_
- . "' name='conditionoff"
- . $_
- . "' size='55' value ='"
- . $savedetails{ $aktdevice . '_conditionoff' }
- . "' onClick=\"javascript:bigwindow(this.id);\"> ";
- my $exit2 = '';
- $exit2 = 'checked' if $savedetails{ $aktdevice . '_exit2' } eq '1';
- if ( AttrVal( $Name, 'MSwitch_Expert', "0" ) eq '1' ) {
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('exit')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "<input type=\"checkbox\" $exit2 name='exit2"
- . $_
- . "' /> execute and exit if applies";
- }
- else {
- $detailhtml =
- $detailhtml
- . "<input hidden type=\"checkbox\" $exit2 name='exit1"
- . $_ . "' /> ";
- }
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1' ) {
- $detailhtml =
- $detailhtml
- . "<input name='info' type='button' value='check condition' onclick=\"javascript: checkcondition('conditionoff"
- . $_
- . "',document.querySelector('#checkoff"
- . $_
- . "').value)\"> with \$EVENT=<select id = \"checkoff"
- . $_
- . "\" name=\"checkoff"
- . $_ . "\">"
- . $optiongeneral
- . "</select>";
- }
- #### zeitrechner
- my $delaym = 0;
- my $delays = 0;
- my $delayh = 0;
- my $timestroff;
- my $testtimestroff = $savedetails{ $aktdevice . '_timeoff' };
- if ( $testtimestroff ne '[random]' ) {
- $testtimestroff =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtimestroff eq "[:]" || $testtimestroff eq "[\$:]" ) {
- $timestroff =
- $savedetails{ $aktdevice . '_timeoff' }; #sekunden
- }
- else {
- $timestroff =
- $savedetails{ $aktdevice . '_timeoff' }; #sekunden
- $delaym = int $timestroff / 60;
- $delays = $timestroff - ( $delaym * 60 );
- $delayh = int $delaym / 60;
- $delaym = $delaym - ( $delayh * 60 );
- $timestroff =
- sprintf( "%02d:%02d:%02d", $delayh, $delaym, $delays );
- }
- }
- else {
- $timestroff = "[random]";
- }
- my $timestron;
- my $testtimestron = $savedetails{ $aktdevice . '_timeon' };
- if ( $testtimestron ne '[random]' ) {
- $testtimestron =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtimestron eq "[:]" || $testtimestron eq "[\$:]" ) {
- $timestron =
- $savedetails{ $aktdevice . '_timeon' }; #sekunden
- }
- else {
- $timestron =
- $savedetails{ $aktdevice . '_timeon' }; #sekunden
- $delaym = int $timestron / 60;
- $delays = $timestron - ( $delaym * 60 );
- $delayh = int $delaym / 60;
- $delaym = $delaym - ( $delayh * 60 );
- $timestron =
- sprintf( "%02d:%02d:%02d", $delayh, $delaym, $delays );
- }
- }
- else {
- $timestron = "[random]";
- }
- $detailhtml = $detailhtml . "</td></tr><tr class='even'>
- <td class='col2' colspan='4' nowrap style='text-align: left;'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('timer')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "'cmd1' <select id = '' name='onatdelay"
- . $_ . "'>";
- my $se11 = '';
- my $sel2 = '';
- my $sel3 = '';
- my $sel4 = '';
- my $sel5 = '';
- my $sel6 = '';
- my $testkey = $aktdevice . '_delaylaton';
- $se11 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "delay1" );
- $sel2 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "delay0" );
- $sel5 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "delay2" );
- $sel4 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "at0" );
- $sel3 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "at1" );
- $sel6 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayaton' } eq "at2" );
- $detailhtml = $detailhtml
- . "<option $se11 value='delay1'>delay with Cond-check immediately and delayed: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel2 value='delay0'>delay with Cond-check immediately only: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel5 value='delay2'>delay with Cond-check delayed only: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel4 value='at0'>at with Cond-check immediately and delayed:</option>";
- $detailhtml = $detailhtml
- . "<option $sel3 value='at1'>at with Cond-check immediately only:</option>";
- $detailhtml = $detailhtml
- . "<option $sel6 value='at0'>at with Cond-check delayed only:</option>";
- $detailhtml =
- $detailhtml
- . "</select><input type='text' class=\"devdetails\" id='timeseton"
- . $_
- . "' name='timeseton"
- . $_
- . "' size='30' value ='"
- . $timestron
- . "'> (hh:mm:ss)</td></tr>";
- $detailhtml = $detailhtml . "
- <tr class='even'>
- <td class='col2' colspan='4' nowrap style='text-align: left;'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('timer')\"> ";
- }
- $detailhtml =
- $detailhtml
- . "'cmd2' <select id = '' name='offatdelay"
- . $_ . "'>";
- $se11 = '';
- $sel2 = '';
- $sel3 = '';
- $sel4 = '';
- $sel5 = '';
- $sel6 = '';
- $testkey = $aktdevice . '_delaylatoff';
- $se11 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "delay1" );
- $sel2 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "delay0" );
- $sel5 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "delay2" );
- $sel4 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "at0" );
- $sel3 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "at1" );
- $sel6 = 'selected'
- if ( $savedetails{ $aktdevice . '_delayatoff' } eq "at2" );
- $detailhtml = $detailhtml
- . "<option $se11 value='delay1'>delay with Cond-check immediately and delayed: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel2 value='delay0'>delay with Cond-check immediately only: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel5 value='delay2'>delay with Cond-check delayed only: +</option>";
- $detailhtml = $detailhtml
- . "<option $sel4 value='at0'>at with Cond-check immediately and delayed:</option>";
- $detailhtml = $detailhtml
- . "<option $sel3 value='at1'>at with Cond-check immediately only:</option>";
- $detailhtml = $detailhtml
- . "<option $sel6 value='at0'>at with Cond-check delayed only:</option>";
- $detailhtml =
- $detailhtml
- . "</select><input type='text' class=\"devdetails\" id='timesetoff"
- . $_
- . "' name='timesetoff"
- . $_
- . "' size='30' value ='"
- . $timestroff
- . "'> (hh:mm:ss) ";
- $detailhtml = $detailhtml . "</td></tr>";
- $detailhtml = $detailhtml . "<tr $rephide class='even'>
- <td class='col2' colspan='4' style='text-align: left;'>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $detailhtml = $detailhtml
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('repeats')\"> ";
- }
- $detailhtml = $detailhtml . "Repeats:
- <input type='text' id='repeatcount' name='repeatcount"
- . $_
- . "' size='10' value ='"
- . $savedetails{ $aktdevice . '_repeatcount' } . "'>
-
- Repeatdelay in sec:
- <input type='text' id='repeattime' name='repeattime"
- . $_
- . "' size='10' value ='"
- . $savedetails{ $aktdevice . '_repeattime' } . "'>
- </td></tr>";
- $detailhtml = $detailhtml . "<tr $rephide class='even'>
- <td class='col2' colspan='4' style='text-align: left;'>
- <br>
- </td></tr>";
- $detailhtml = $detailhtml . "<tr class='even'>
- <td class='col2' colspan='5' style='text-align: left;'>";
- if ( $devicenumber == 1 ) {
- $detailhtml =
- $detailhtml
- . "<input name='info' class=\"randomidclass\" id=\"add_action1_"
- . rand(1000000)
- . "\" type='button' value='add action for $add' onclick=\"javascript: addevice('$add')\">";
- }
- $detailhtml =
- $detailhtml
- . "<input name='info' id=\"del_action1_"
- . rand(1000000)
- . "\" class=\"randomidclass\" type='button' value='delete this action for $add' onclick=\"javascript: deletedevice('$_')\">";
- $detailhtml = $detailhtml . "<br> </td></tr>";
- #middle
- ####################change1 = change.replace(/,/g,'##');
- # javazeile für übergabe erzeugen
- $javaform = $javaform . "
-
- devices += \$(\"[name=devicename$_]\").val();
- devices += '#[DN]';
-
-
- devices += \$(\"[name=cmdon$_]\").val()+'#[NF]';
- devices += \$(\"[name=cmdoff$_]\").val()+'#[NF]';
- change = \$(\"[name=cmdonopt$_]\").val();
- devices += change+'#[NF]';;
- change = \$(\"[name=cmdoffopt$_]\").val();
- devices += change+'#[NF]';;
- devices += \$(\"[name=onatdelay$_]\").val();
- devices += '#[NF]';
- devices += \$(\"[name=offatdelay$_]\").val();
- devices += '#[NF]';
- delay1 = \$(\"[name=timesetoff$_]\").val();
- devices += delay1+'#[NF]';
- delay2 = \$(\"[name=timeseton$_]\").val();
- devices += delay2+'#[NF]';
- devices1 = \$(\"[name=conditionon$_]\").val();
- devices2 = \$(\"[name=conditionoff$_]\").val();
- devices2 = devices2.replace(/\\|/g,'(DAYS)');
- devices += devices1+'#[NF]';
- devices += devices2;
- devices += '#[NF]';
- devices3 = \$(\"[name=repeatcount$_]\").val();
- devices += devices3;
- devices += '#[NF]';
- devices += \$(\"[name=repeattime$_]\").val();
- devices += '#[NF]';
- devices += \$(\"[name=reihe$_]\").val();
- devices += '#[NF]';
- devices += \$(\"[name=idreihe$_]\").val();
- devices += '#[NF]';
- devices += \$(\"[name=cmdcomment$_]\").val();
- devices += '#[NF]';
- devices += \$(\"[name=exit1$_]\").prop(\"checked\") ? \"1\":\"0\";
- devices += '#[NF]';
- devices += \$(\"[name=exit2$_]\").prop(\"checked\") ? \"1\":\"0\";
- devices += '#[NF]';
- devices += \$(\"[name=showreihe$_]\").val();
- devices += '#[DN]';
- ";
- }
- ####################
- $detailhtml = $detailhtml;
- $detailhtml = $detailhtml . "<tr class='even'><td colspan='5'><left>
- <input type='button' id='aw_det' value='modify Actions' >
- </td></tr></table>"; #end
- }
- ####################
- my $triggercondition = ReadingsVal( $Name, '.Trigger_condition', '' );
- $triggercondition =~ s/~/ /g;
- $triggercondition =~ s/#\[dp\]/:/g;
- $triggercondition =~ s/#\[pt\]/./g;
- $triggercondition =~ s/#\[ti\]/~/g;
- $triggercondition =~ s/#\[sp\]/ /g;
- my $triggertime = ReadingsVal( $Name, '.Trigger_time', '' );
- $triggertime =~ s/#\[dp\]/:/g;
- my @triggertimes = split( /~/, $triggertime );
- my $condition = ReadingsVal( $Name, '.Trigger_time', '' );
- my $lenght = length($condition);
- my $timeon = '';
- my $timeoff = '';
- my $timeononly = '';
- my $timeoffonly = '';
- if ( $lenght != 0 ) {
- $timeon = substr( $triggertimes[0], 2 );
- $timeoff = substr( $triggertimes[1], 3 );
- $timeononly = substr( $triggertimes[2], 6 );
- $timeoffonly = substr( $triggertimes[3], 7 );
- }
- my $ret = '';
- $ret .= "<p id=\"triggerdevice\">";
- ########################
- my $blocking = '';
- $blocking = $hash->{helper}{savemodeblock}{blocking}
- if ( defined $hash->{helper}{savemodeblock}{blocking} );
- if ( $blocking eq 'on' ) {
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>ACHTUNG: Der Safemodus hat eine Endlosschleife erkannt, welche zum Fhemabsturz führen könnte.<br>Dieses Device wurde automatisch deaktiviert ( ATTR 'disable') !<br>
- </td></tr></table><br> <br>
- ";
- }
- my $errortest = "";
- $errortest = $hash->{helper}{error} if ( defined $hash->{helper}{error} );
- if ( $errortest ne "" ) {
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>AT-Kommandos können nicht ausgeführt werden !<br>"
- . $errortest
- . "<br>
- </td></tr></table><br> <br>
- ";
- }
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '2'
- || AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '3' )
- {
- my $Zeilen = ("");
- open( BACKUPDATEI, "./log/MSwitch_debug_$Name.log" );
- while (<BACKUPDATEI>) {
- $Zeilen = $Zeilen . $_;
- }
- close(BACKUPDATEI);
- my $text = "";
- $text =
- "Das Device befindet sich im Debug 2 Mode. Es werden keine Befehle ausgeführt, sondern nur protokolliert."
- if AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '2';
- $text =
- "Das Device befindet sich im Debug 3 Mode. Alle Aktionen werden protokolliert."
- if AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '3';
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>
- $text<br> <br>
- <textarea name=\"log\" id=\"log\" rows=\"5\" cols=\"160\" STYLE=\"font-family:Arial;font-size:9pt;\">"
- . $Zeilen . "</textarea>
- <br> <br>
- <input type=\"button\" id=\"\"
- value=\"clear log\" onClick=\"clearlog();\">
- <br> <br>
- </td></tr></table><br>
- <br>
- ";
- }
- if ( ReadingsVal( $Name, '.info', 'undef' ) ne "undef" ) {
- $ret .= "
- <table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td colspan ='3'><center><br> ";
- $ret .= ReadingsVal( $Name, '.info', '' );
- $ret .= "<br> </td></tr></table><br>
- <br>
- ";
- }
- # anpassung durch configeinspielung
- if ( ReadingsVal( $Name, '.change', 'undef' ) ne "undef" ) {
- # geräteliste
- my $dev;
- for my $name ( sort keys %defs ) {
- my $devicealias = AttrVal( $name, 'alias', "" );
- my $devicewebcmd = AttrVal( $name, 'webCmd', "noArg" );
- my $devicehash = $defs{$name};
- my $deviceTYPE = $devicehash->{TYPE};
- $dev .=
- "<option selected=\"\" value=\"$name\">"
- . $name . " (a: "
- . $devicealias
- . ")</option>";
- }
- my $sel = "<select id = \"CID\" name=\"trigon\">" . $dev . "</select>";
- my @change = split( "\\|", ReadingsVal( $Name, '.change', 'undef' ) );
- my $out = '';
- my $count = 0;
- foreach my $changes (@change) {
- my @set = split( "#", $changes );
- $out .= "<tr class='even'>";
- $out .= "<td>";
- $out .= $set[1];
- $out .= "</td>";
- $out .= "<td>";
- $out .= "</td>";
- $out .= "<td>";
- $out .=
- "<input type='' id='cdorg"
- . $count
- . "' name='' value ='$set[0]' disabled> ersetzen durch:";
- if ( $set[2] eq "device" ) {
- my $newstring = $sel;
- my $newname = "cdnew" . $count;
- $newstring =~ s/CID/$newname/g;
- $out .= $newstring;
- }
- else {
- $out .=
- " <input type='' id='cdnew"
- . $count
- . "' name='' size='20' value =''>";
- }
- $out .= "</td>";
- $out .= "</tr>";
- $count++;
- }
- $ret .= "
- <table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td colspan ='3'><center> <br>Eingriff erforderlich !<br> ";
- $ret .= ReadingsVal( $Name, '.change_info', '' );
- $ret .= "</td></tr>" . $out . "
- <tr class='even'>
- <td colspan ='3'><center> <br>
- <input type=\"button\" id=\"\"
- value=\"save changes\" onClick=\"changedevices();\">
- <br> <br>
- </td></tr></table><br>
- <br>
- ";
- $j1 = "<script type=\"text/javascript\">{";
- $j1 .=
- "var t=\$(\"#MSwitchWebTR\"), ip=\$(t).attr(\"ip\"), ts=\$(t).attr(\"ts\");
- FW_replaceWidget(\"[name=aw_ts]\", \"aw_ts\", [\"time\"], \"12:00\");
- \$(\"[name=aw_ts] input[type=text]\").attr(\"id\", \"aw_ts\");";
- $j1 .= "function changedevices(){
- var count = $count;
- var string = '';
- for (i=0; i<count; i++)
- {
- var field1 = 'cdorg'+i;
- var field2 = 'cdnew'+i;
- string += document.getElementById(field1).value + '#' + document.getElementById(field2).value + '|';
- }
- var strneu = string.substr(0, string.length-1);
- strneu = strneu.replace(/ /g,'#[sp]');
- var def = \"" . $Name . "\"+\" confchange \"+encodeURIComponent(strneu);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "}</script>";
- return "$ret" . "$j1";
- }
- #readingsSingleUpdate( $hash, ".wrong_version", $1, 0 );
- if ( ReadingsVal( $Name, '.wrong_version', 'undef' ) ne "undef" ) {
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>Einspielen des Configfiles nicht möglich !<br>falsche Versionsnummer: "
- . ReadingsVal( $Name, '.wrong_version', '' )
- . "<br>geforderte Versionsnummer $vupdate<br>
-
- </td></tr></table><br>
- <br>
-
- ";
- fhem("deletereading $Name .wrong_version");
- }
- if ( ReadingsVal( $Name, '.V_Check', $vupdate ) ne $vupdate ) {
- my $ver = ReadingsVal( $Name, '.V_Check', '' );
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>Versionskonflikt erkannt!<br>Das Device führt derzeit keine Aktionen aus. Bitte ein Update des Devices vornehmen.<br>Erwartete Strukturversionsnummer: $vupdate<br>Vorhandene Strukturversionsnummer: $ver <br> <br>
- <input type=\"button\" id=\"\"
- value=\"try update to $vupdate\" onClick=\"vupdate();\">
- <br> <br>
- </td></tr></table><br>
- <br>
-
- ";
- $j1 = "<script type=\"text/javascript\">{";
- $j1 .=
- "var t=\$(\"#MSwitchWebTR\"), ip=\$(t).attr(\"ip\"), ts=\$(t).attr(\"ts\");
- FW_replaceWidget(\"[name=aw_ts]\", \"aw_ts\", [\"time\"], \"12:00\");
- \$(\"[name=aw_ts] input[type=text]\").attr(\"id\", \"aw_ts\");";
- $j1 .= "function vupdate(){
- conf='';
- var def = \"" . $Name . "\"+\" VUpdate \"+encodeURIComponent(conf);
- //alert(def);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "}</script>";
- return "$ret" . "$j1";
- }
- $ret .= "<table border='$border' class='block wide' id=''>
- <tr class='even'>
- <td><center> <br>Device is disabled, configuration avaible<br> <br>
- </td></tr></table><br>" if ( IsDisabled($Name) );
- ####################
- $ret .=
- "<table border='$border' class='block wide' id='MSwitchWebTR' nm='$hash->{NAME}'>";
- $ret .= " <tr class=\"even\">";
- $ret .=
- "<td colspan=\"3\" id =\"savetrigger\">trigger device/time: ";
- $ret = $ret . "</td>
- </tr>
- <tr class=\"even\">
- <td></td>
- <td></td>
- <td></td>
- </tr>
- <tr class=\"even\">
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('trigger')\"> ";
- }
- $ret .= "Trigger device: </td>
- <td colspan =\"2\">
- <select id =\"trigdev\" name=\"trigdev\">" . $triggerdevices . "</select>
- </td>
- </tr>";
- my $visible = 'visible';
- if ( $globalon ne 'on' ) {
- $visible = 'collapse';
- }
- $ret =
- $ret
- . "<tr class=\"even\" id='triggerwhitelist' style=\"visibility:"
- . $visible . ";\" >
- <td nowrap>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('whitelist')\"> ";
- }
- $ret = $ret . "Trigger Device Global Whitelist:
- </td>
- <td></td>
- <td><input type='text' id ='triggerwhite' name='triggerwhitelist' size='30' value ='"
- . ReadingsVal( $Name, '.Trigger_Whitelist', '' )
- . "' onClick=\"javascript:bigwindow(this.id);\" >";
- $ret = $ret . "</td></tr>";
- my $inhalt = "execute 'cmd1' only at :";
- my $inhalt1 = "execute 'cmd2' only at :";
- my $inhalt2 = "execute 'cmd1' only";
- my $inhalt3 = "execute 'cmd2' only";
- my $inhalt4 = "switch MSwitch on + execute 'cmd1' at :";
- my $inhalt5 = "switch $Name on + execute 'cmd1'";
- my $displaynot = '';
- my $displayntog = '';
- my $help = "";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $help =
- "<input name='info' type='button' value='?' onclick=\"javascript: info('execcmd')\"> ";
- }
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Notify" ) {
- $displaynot = "style='display:none;'";
- $inhalt = "execute 'cmd1' at :";
- $inhalt1 = "execute 'cmd2' at :";
- $inhalt2 = $help . "execute 'cmd1'";
- $inhalt3 = $help . "execute 'cmd2'";
- }
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Toggle" ) {
- $displayntog = "style='display:none;'";
- $inhalt4 = "toggle $Name + execute 'cmd1/cmd2' at :";
- $inhalt5 = "toggle $Name + execute 'cmd1/cmd2'";
- }
- $ret = $ret . "
- <tr class=\"even\">
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('trigger')\"> ";
- }
- $ret = $ret . "Trigger time: </td>
- <td></td>
- <td>
- </td>
- </tr>
- <tr " . $displaynot . " class=\"even\">
- <td></td>
- <td>" . $inhalt4 . "</td>
- <td><input type='text' id='timeon' name='timeon' size='60' value ='"
- . $timeon . "'></td>
- </tr>
- <tr " . $displaynot . $displayntog . " class=\"even\">
- <td></td>
- <td>switch MSwitch off + execute 'cmd2' at :</td>
- <td><input type='text' id='timeoff' name='timeoff' size='60' value ='"
- . $timeoff . "'></td>
- </tr>
- <tr " . $displayntog . "class=\"even\">
- <td></td>
- <td>" . $inhalt . "</td>
- <td><input type='text' id='timeononly' name='timeononly' size='60' value ='"
- . $timeononly . "'></td>
- </tr>
- <tr " . $displayntog . "class=\"even\">
- <td></td>
- <td>" . $inhalt1 . "</td>
- <td><input type='text' id='timeoffonly' name='timeoffonly' size='60' value ='"
- . $timeoffonly . "'></td>
- </tr>";
- my $triggerinhalt = "Trigger condition (events only): ";
- if ( AttrVal( $Name, 'MSwitch_Condition_Time', "0" ) eq '1' ) {
- $triggerinhalt = "Trigger condition (time&events): ";
- }
- $ret = $ret . "<tr class=\"even\">
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret .=
- "<input name='info' type='button' value='?' onclick=\"javascript: info('triggercondition')\"> ";
- }
- $ret = $ret . $triggerinhalt . "</td>
- <td></td>
- <td><input type='text' id='triggercondition' name='triggercondition' size='60' value ='"
- . $triggercondition . "' onClick=\"javascript:bigwindow(this.id);\" >";
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1' ) {
- $ret = $ret
- . " <input name='info' type='button' value='check condition' onclick=\"javascript: checkcondition('triggercondition','$Name:trigger:conditiontest')\">";
- }
- $ret = $ret . "</td></tr>";
- $ret = $ret . "<tr class=\"even\">
- <td colspan=\"3\"><left>
- <input type=\"button\" id=\"aw_trig\" value=\"modify Trigger Device\"$disable>
- </td>
- </tr>
- </table></p>";
- ####################
- # triggerdetails
- my $selectedcheck3 = "";
- my $testlog = ReadingsVal( $Name, 'Trigger_log', 'on' );
- if ( $testlog eq 'on' ) {
- $selectedcheck3 = "checked=\"checked\"";
- }
- if ( ReadingsVal( $Name, 'Trigger_device', 'no_trigger' ) ne 'no_trigger' )
- {
- $ret .=
- "<table border='$border' class='block wide' id='MSwitchWebTRDT' nm='$hash->{NAME}'>
- <tr class=\"even\">
- <td id =\"triggerdetails\">trigger details :</td>
- <td></td>
- <td></td>
- </tr>
- <tr class=\"even\">
- <td></td>
- <td></td>
- <td></td>
- </tr>";
- $ret .= "<tr " . $displaynot . " class=\"even\"><td>";
- $ret .= $inhalt5 . "</td><td>
- Trigger " . $Triggerdevice . " :
- </td>
- <td>
- <select id = \"trigon\" name=\"trigon\">" . $optionon . "</select>
- </td>
- </tr>
- <tr " . $displaynot . $displayntog . "class=\"even\">
- <td>
- switch " . $Name . " off + execute 'cmd2'</td>
- <td>
- Trigger " . $Triggerdevice . " :
- </td>
- <td>
- <select id = \"trigoff\" name=\"trigoff\">" . $optionoff . "</select>
- </td>
- </tr>";
- $ret .= "<tr class=\"even\">
- <td colspan=\"3\" > </td>
- </tr>
- <tr " . $displayntog . " class=\"even\">
- <td>" . $inhalt2 . "</td>
- <td>
- Trigger " . $Triggerdevice . " :
- </td>
- <td>
- <select id = \"trigcmdon\" name=\"trigcmdon\">" . $optioncmdon . "</select>
- </td>
- </tr>
- <tr " . $displayntog . "class=\"even\">
- <td>" . $inhalt3 . "</td>
- <td>
- Trigger " . $Triggerdevice . " :
- </td>
- <td>
- <select id = \"trigcmdoff\" name=\"trigcmdoff\">"
- . $optioncmdoff . "</select>
- </td>
- </tr>
-
- <tr class=\"even\">
- <td colspan=\"1\"><left>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('saveevent')\"> ";
- }
- $ret = $ret . "Save incomming events :
-
- </td>
- <td><input $selectedcheck3 name=\"aw_save\" type=\"checkbox\" $disable></td>
- <td></td>
- </tr>
-
- <tr class=\"even\">
- <td colspan=\"1\"><left>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret = $ret
- . "<input name='info' type='button' value='?' onclick=\"javascript: info('addevent')\"> ";
- }
- $ret .= "Add event manually :
- </td>
- <td><left>
- <input type='text' id='add_event' name='add_event' size='40' value =''>
- <input type=\"button\" id=\"aw_addevent\" value=\"add event\"$disable>";
- $ret .= "</td>
- <td><left>
- </td>
- </tr>
- <tr class=\"even\">
- <td colspan=\"2\"><left>
- <input type=\"button\" id=\"aw_md\" value=\"modify Trigger\"$disable>
- <input type=\"button\" id=\"aw_md1\" value=\"apply filter to saved events\" $disable>
- <input type=\"button\" id=\"aw_md2\" value=\"clear saved events\"$disable>
- </td>
- <td><left>";
- if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1'
- && $optiongeneral ne '' )
- {
- $ret .=
- "<select id = \"eventtest\" name=\"eventtest\">"
- . $optiongeneral
- . "</select><input type=\"button\" id=\"aw_md2\" value=\"test event\"$disable onclick=\"javascript: checkevent(document.querySelector('#eventtest').value)\">";
- }
- $ret .= "</td></tr> </table></p>";
- }
- else {
- $ret .= "<p id=\"MSwitchWebTRDT\"></p>";
- }
- # affected devices
- $ret .=
- "<table border='$border' class='block wide' id='MSwitchWebAF' nm='$hash->{NAME}'>
- <tr class=\"even\">
- <td>affected devices :</td>
- <td></td>
- <td></td>
- </tr>
- <tr class=\"even\">
- <td>
- </td>
- <td>
- </td>
- <td></td>
- </tr>
- <tr class=\"even\">
- <td>";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $ret .=
- "<input name='info' type='button' value='?' onclick=\"javascript: info('affected')\"> ";
- }
- $ret .= "multiple selection with ctrl + mousebutton</td>
- <td><p id =\"textfie\">
- <select id =\"devices\" multiple=\"multiple\" name=\"affected_devices\" size=\"6\" disabled >";
- $ret .= $deviceoption;
- $ret .= "</select>
- </p>
- </td>
- <td><center>
- <input type=\"button\" id=\"aw_great\"
- value=\"edit list\" onClick=\"javascript:deviceselect();\">
- <br>
- <input onChange=\"javascript:switchlock();\" checked=\"checked\" id=\"lockedit\" name=\"lockedit\" type=\"checkbox\" value=\"lockedit\" /> quickedit locked
- <br>
- <br>
- </td>
- </tr>
- <tr class=\"even\">
- <td><leftt>
- <input type=\"button\" id=\"aw_dev\" value=\"modify Devices\"$disable>
- </td>
- <td> </td>
- <td> </td>
- </tr>
- </table>";
- ####################
- #javascript$jsvarset
- my $triggerdevicehtml = $Triggerdevice;
- $triggerdevicehtml =~ s/\(//g;
- $triggerdevicehtml =~ s/\)//g;
- $j1 = "<script type=\"text/javascript\">{";
- if ( AttrVal( $Name, 'MSwitch_Lock_Quickedit', "1" ) eq '0' ) {
- $j1 .= "
- \$(\"#devices\").prop(\"disabled\", false);
- document.getElementById('aw_great').value='schow greater list';
- document.getElementById('lockedit').checked = false ;
- ";
- }
- if ( $affecteddevices[0] ne 'no_device' ) {
- $j1 .= "
- var affected = document.getElementById('affected').value
- var devices = affected.split(\",\");
- var i;
- var len = devices.length;
- for (i=0; i<len; i++)
- {
- testname = devices[i].split(\"-\");
- if (testname[0] == \"FreeCmd\") {
- continue;
- }
- sel = devices[i] + '_on';
- sel1 = devices[i] + '_on_sel';
- sel2 = 'cmdonopt' + devices[i] + '1';
- sel3 = 'cmdseton' + devices[i];
- aktcmd = document.getElementById(sel).value;
- aktset = document.getElementById(sel3).value;
- activate(document.getElementById(sel).value,sel1,aktset,sel2);
- sel = devices[i] + '_off';
- sel1 = devices[i] + '_off_sel';
- sel2 = 'cmdoffopt' + devices[i] + '1';
- sel3 = 'cmdsetoff' + devices[i];
- aktcmd = document.getElementById(sel).value;
- aktset = document.getElementById(sel3).value;
- activate(document.getElementById(sel).value,sel1,aktset,sel2);
- };"
- }
- # java wird bei seitenaufruf ausgeführt
- $j1 .= "
- var globallock='';
- var randomdev=[];
- var x = document.getElementsByClassName('randomidclass');
- for (var i = 0; i < x.length; i++)
- {
- var t = x[i].id;
- randomdev.push(t);
- }";
- $j1 .= "
- var globaldetails2='undefined';
- var x = document.getElementsByClassName('devdetails2');
- for (var i = 0; i < x.length; i++)
- {
- var t = x[i].id;
- globaldetails2 +=document.getElementById(t).value;
- }
- var globaldetails='undefined';
- var x = document.getElementsByClassName('devdetails');
- for (var i = 0; i < x.length; i++)
- {
- var t = x[i].id;
- globaldetails +=document.getElementById(t).value;
-
- document.getElementById(t).onchange = function()
- {
- //alert('changed');
- var changedetails;
- var y = document.getElementsByClassName('devdetails');
- for (var i = 0; i < y.length; i++)
- {
- var t = y[i].id;
- changedetails +=document.getElementById(t).value;
- }
- if( changedetails != globaldetails)
- {
- globallock =' unsaved device actions';
- [ \"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\",\"aw_dev\"].forEach (lock,);
- randomdev.forEach (lock);
- }
- if( changedetails == globaldetails)
- {
- [ \"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\",\"aw_dev\"].forEach (unlock,);
- randomdev.forEach (unlock);
- }
- }
- }
- ";
- # triggerlock
- $j1 .= "
- var triggerdetails = document.getElementById('MSwitchWebTRDT').innerHTML;
- var saveddevice = '" . $triggerdevicehtml . "';
- var sel = document.getElementById('trigdev');
- sel.onchange = function()
- {
- trigdev = this.value;
- if (trigdev != '";
- $j1 .= $triggerdevicehtml;
- $j1 .= "')
- {
- //document.getElementById('savetrigger').innerHTML = '<font color=#FF0000>trigger device : unsaved!</font> ';
- //document.getElementById('MSwitchWebTRDT').innerHTML = '';
-
- globallock =' unsaved trigger';
- [\"aw_dev\", \"aw_det\"].forEach (lock);
- randomdev.forEach (lock,);
- }
- else
- {
- //alert (randomdev);
- [\"aw_dev\", \"aw_det\"].forEach (unlock);
- randomdev.forEach (unlock);
- document.getElementById('savetrigger').innerHTML = 'trigger device :';
- document.getElementById('MSwitchWebTRDT').innerHTML = triggerdetails;
- }
-
- if (trigdev == 'all_events')
- {
- document.getElementById(\"triggerwhitelist\").style.visibility = \"visible\";
- }
- else
- {
- document.getElementById(\"triggerwhitelist\").style.visibility = \"collapse\";
- }
- }
- ";
- #####################
- $j1 .= "
-
-
- if (document.getElementById('trigon')){
- var trigonfirst = document.getElementById('trigon').value;
- var sel2 = document.getElementById('trigon');
- sel2.onchange = function()
- {
- if (trigonfirst != document.getElementById('trigon').value)
- {
- closetrigger();
- }
- else{
- opentrigger();
- }
- }
- }
-
- if (document.getElementById('trigoff')){
- var trigofffirst = document.getElementById('trigoff').value;
- var sel3 = document.getElementById('trigoff');
- sel3.onchange = function()
- {
- if (trigofffirst != document.getElementById('trigoff').value)
- {
- closetrigger();
- }
- else{
- opentrigger();
- }
- }
- }
-
- if (document.getElementById('trigcmdoff')){
- var trigcmdofffirst = document.getElementById('trigcmdoff').value;
- var sel4 = document.getElementById('trigcmdoff');
- sel4.onchange = function()
- {
- if (trigcmdofffirst != document.getElementById('trigcmdoff').value)
- {
- closetrigger();
- }
- else{
- opentrigger();
- }
- }
- }
-
- if (document.getElementById('trigcmdon')){
- var trigcmdonfirst = document.getElementById('trigcmdon').value;
- var sel5 = document.getElementById('trigcmdon');
- sel5.onchange = function()
- {
- if (trigcmdonfirst != document.getElementById('trigcmdon').value)
- {
- closetrigger();
- }
- else{
- opentrigger();
- }
- }
- }
-
- function closetrigger(){
- globallock =' unsaved trigger details';
- [\"aw_dev\", \"aw_det\",\"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\"].forEach (lock,);
- randomdev.forEach (lock);
- }
-
- function opentrigger(){
- //alert('call unlock');
- [ \"aw_dev\",\"aw_det\",\"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\"].forEach (unlock,);
- randomdev.forEach (unlock);
- }
-
- ";
- #####################
- #affected lock
- $j1 .= "
- var globalaffected;
- var auswfirst=document.getElementById('devices');
- for (i=0; i<auswfirst.options.length; i++)
- {
- var pos=auswfirst.options[i];
- if(pos.selected)
- {
- //alert (pos.value);
- globalaffected +=pos.value;
- }
- }
- //alert (globalaffected);
- var sel1 = document.getElementById('devices');";
- $j1 .= "
- globallock =' this device is locked !';
- [ \"aw_dev\",\"aw_det\",\"aw_trig\",\"aw_md\",\"aw_md1\",\"aw_md2\",\"aw_addevent\"].forEach (lock,);
- randomdev.forEach (lock);"
- if ( ReadingsVal( $Name, '.lock', 'undef' ) ne "undef" );
- $j1 .= "
- sel1.onchange = function()
- {
- var actaffected;
- var auswfirst=document.getElementById('devices');
- for (i=0; i<auswfirst.options.length; i++)
- {
- var pos=auswfirst.options[i];
- if(pos.selected)
- {
- //alert (pos.value);
- actaffected +=pos.value;
- }
- }
- if (actaffected != globalaffected)
- {
- globallock =' unsaved affected device';
- [ \"aw_det\",\"aw_trig\",\"aw_md\",\"aw_md1\",\"aw_md2\",\"aw_addevent\"].forEach (lock,);
- randomdev.forEach (lock);
- }
- else
- {
- [ \"aw_det\",\"aw_trig\",\"aw_md\",\"aw_md1\",\"aw_md2\",\"aw_addevent\"].forEach (unlock,);
- randomdev.forEach (unlock);
- }
-
- }
- ";
- #function lock unlock
- $j1 .= "function lock (elem, text){
-
- if (document.getElementById(elem)){
- document.getElementById(elem).style.backgroundColor = \"#ADADAD\"
- document.getElementById(elem).disabled = true;
-
- if (!document.getElementById(elem).model)
- {
- document.getElementById(elem).model=document.getElementById(elem).value;
- }
- document.getElementById(elem).value = 'N/A'+globallock;
- }
-
- }";
- $j1 .= "function unlock (elem, index){
- if (document.getElementById(elem)){
- document.getElementById(elem).style.backgroundColor = \"\"
- document.getElementById(elem).disabled = false;
- document.getElementById(elem).value=document.getElementById(elem).model;
- }
- }";
- #####################
- $j1 .= "function saveconfig(conf){
-
- conf = conf.replace(/\\n/g,'#[EOL]');
- conf = conf.replace(/:/g,'#c[dp]');
- conf = conf.replace(/;/g,'#c[se]');
- conf = conf.replace(/ /g,'#c[sp]');
-
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" saveconfig \"+encodeURIComponent(conf);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "function vupdate(){
- conf='';
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" VUpdate \"+encodeURIComponent(conf);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "function clearlog(){
- conf='';
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" clearlog \"+encodeURIComponent(conf);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "function savesys(conf){
- conf = conf.replace(/:/g,'#[dp]');
- conf = conf.replace(/;/g,'#[se]');
- conf = conf.replace(/ /g,'#[sp]');
- conf = conf.replace(/'/g,'#[st]');
-
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" savesys \"+encodeURIComponent(conf);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }";
- $j1 .= "function checkcondition(condition,event){
- //alert(condition,event);
- var selected =document.getElementById(condition).value;
- // event = \"test:test:test\";
- if (selected == '')
- {
- var textfinal = \"<div style ='font-size: medium;'>Es ist keine Bedingung definiert, das Kommando wird immer ausgeführt.</div>\";
- FW_okDialog(textfinal);
- return;
- }
- selected = selected.replace(/\\|/g,'(DAYS)');
- selected = selected.replace(/\\./g,'#[pt]');
- selected = selected.replace(/:/g,'#[dp]');
- selected= selected.replace(/~/g,'#[ti]');
- selected = selected.replace(/ /g,'#[sp]');
- event = event.replace(/~/g,'#[ti]');
- event = event.replace(/ /g,'#[sp]');
- cmd ='get " . $Name . " checkcondition '+selected+'|'+event;
- FW_cmd(FW_root+'?cmd='+encodeURIComponent(cmd)+'&XHR=1', function(resp){FW_okDialog(resp);});
- }
- function checkevent(event){
- event = event.replace(/ /g,'~');
- cmd ='get " . $Name . " checkevent '+event;
- FW_cmd(FW_root+'?cmd='+encodeURIComponent(cmd)+'&XHR=1');
- }
- ";
- if ( AttrVal( $Name, 'MSwitch_Help', "0" ) eq '1' ) {
- $j1 .= "
- function info(from){
- text='Help: ' + from +'<br><br>';
-
- if (from == 'exit'){
- text = text + 'Bei Auswahl dieses Feldes ergolgt ein Abbruch des Programms, nach Ausfuehrung dieses Befehles (in Abhaengigkeit der Conditions).<br>Folgende Befehle werden nur dann ausgefuehrt, wenn dieser Befehl nicht ausgefuehrt wurde.<br>Diese Option macht im Grunde nur Sinn in Zusammenhang mit der Priority-Funktion';}
-
-
- if (from == 'timer'){
- text = text + 'Hier kann entweder eine direkte Angabe einer Verzögerungszeit (delay with Cond_check) angegeben werden, oder es kann eine Ausführungszeit (at with Cond-check) für den Befehl angegeben werden<br> Bei der Angabe einer Ausführungszeit wird der Schaltbefehl beim nächsten erreichen der angegebenen Zeit ausgeführt. Ist die Zeit am aktuellen Tag bereits überschritten , wird der angegebene Zeitpunkt am Folgetag gesetzt.<br>Die Auswahl \"with Conf-check\" oder \"without Conf-check\" legt fest, ob unmittelbar vor Befehlsausführung nochmals die Condition für den Befehl geprüft wird oder nicht.<br><brAlternativ kann hier auch ein Verweis auf ein beliebiges Reading eines Devices erfolgen, das entsprechenden Wert enthält. Dieser Verweis muss in folgendem Format erfolgen:<br><br>[NAME.reading] des Devices ->z.B. [dummy.state]<br>Das Reading muss in folgendem Format vorliegen: hh:mm:ss ';}
-
- if (from == 'trigger'){
- text = text + 'Trigger ist das Gerät, oder die Zeit, auf die das Modul reagiert, um andere devices anzusprechen.<br>Das Gerät kann aus der angebotenen Liste ausgewählt werden, sobald dieses ausgewählt ist werden weitere Optionen angeboten.<br>Soll auf mehrereGerät gleichzeitig getriggert werden , so ist dieses ebenfalls möglich. Hierzu muss das Attribut \"MSwitch_Expert\" auf 1 gesetzt sein und als Auswahl \"GLOBAL\" erfolgen.<br><br>Zeitangaben können ebenso als Trigger genutzt werden, das Format muss wie folgt lauten:<br><br> [STUNDEN:MINUTEN|TAGE] - Tage werden von 1-7 gezählt, wobei 1 für Montag steht, 7 für Sonntag.<br /><br>Die Variable \$we ist anstatt der Tagesangabe verwendbar<br> [STUNDEN:MINUTEN|\$we] - Schaltvorgang nur an Wochenenden.<br>[STUNDEN:MINUTEN|!\$we] - Schaltvorgang nur an Werktagen.<br><br>Mehrere Zeitvorgaben können aneinandergereiht werden.<br>[17:00|1][18:30|23] würde den Trigger Montags um 17 Uhr auslösen und Dienstags,Mittwochs um 18 Uhr 30.<br><br>Sunset - Zeitangaben können mit folgender Sytax eingebunden werden: z.B [{sunset()}] , [{sunrise(+1800)}].<br><br>Es ist eine gleichzeitige Nutzung für Trigger durch Zeitangaben und Trigger durch Deviceevents möglich.<br><br>Sonderformate:<br>[?20:00-21:00|5] - Zufälliger Schaltvorgang zwischen 20 Uhr und 21 Uhr am Freitag<br>[00:02*04:10-06:30] - Schaltvorgang alle 2 Minuten zwischen 4.10 Uhr und 6.30 Uhr';}
-
- if (from == 'triggercondition'){
- text = text + 'Hier kann die Angabe von Bedingungen erfolgen, die zusätzlich zu dem triggernden Device erfuellt sein müssen.<br> Diese Bedingunge sind eng an DOIF- Bedingungen angelehnt .<br>Zeitabhängigkeit: [19.10-23:00] - Trigger des Devices erfolgt nur in angegebenem Zeitraum<br>Readingabhängige Trigger [Devicename:Reading] =/>/< X oder [Devicename:Reading] eq \"x\" - Trigger des Devicec erfolgt nur bei erfüllter Bedingung.<br>Achtung ! Bei der Abfrage von Readings nach Strings ( on,off,etc. ) ist statt \"=\" \"eq\" zu nutzen und der String muss in \"\" gesetzt werden!<br>Die Kombination mehrerer Bedingungen und Zeiten ist durch AND oder OR möglich.<br>[19.10-23:00] AND [Devicename:Reading] = 10 - beide Bedingungen müssen erfüllt sein<br>[19.10-23:00] OR [Devicename:Reading] = 10 - eine der Bedingungen muss erfüllt sein.<br>Es ist auf korrekte Eingabe der Leerzeichen zu achten.<br><br>sunset - Bedingungen werden mit zusätzlichen {} eingefügt z.B. : [{ sunset() }-23:00].<br><br>Variable \$we:<br>Die globlae Variable \$we ist nutzbar und muss in {} gesetzt werden .<br>{ !\$we } löst den Schaltvorgang nur Werktagen an aus<br>{ \$we } löst den Schaltvorgang nur an Wochenenden, Feiertagen aus<br><br>Soll nur an bestimmten Wochentagen geschaltet werden, muss eine Zeitangsbe gemacht werden und durch z.B. |135 ergänzt werden.<br>[10:00-11:00|13] würde den Schaltvorgang z.B nur Montag und Mitwoch zwischen 10 uhr und 11 uhr auslösen. Hierbei zählen die Wochentage von 1-7 für Montag-Sonntag.<br>Achtung: Bei Anwendung der geschweiften Klammern zur einletung eines Perlasdrucks ist unbedingt auf die Leerzeichen hinter und vor der Klammer zu achten !<br> Überschreitet die Zeitangabe die Tagesgrenze (24.00 Uhr ), so gelten die angegebenen Tage noch bis zum ende der angegebenen Schaltzeit,<br> d.H. es würde auch am Mitwoch noch der schaltvorgang erfolgen, obwohl als Tagesvorgabe Dienstag gesetzt wurde.<br><br>Wird in diesem Feld keine Angabe gemacht , so erfolgt der Schaltvorgang nur durch das triggernde Device ohne weitere Bedingungen.<br><br>Achtung: Conditions gelten nur für auslösende Trigger eines Devices und habe keinen Einfluss auf zeitgesteuerte Auslöser. Um Zeitgesteuerte Auslösr ebenfalls an Bedingungen zu Knüpfen muss dieses in den Attributen aktiviert werden.';}
-
- if (from == 'whitelist'){
- text = text + 'Bei der Auswahl \\\'GLOBAL\\\' als Triggerevent werde alle von Fhem erzeugten Events an dieses Device weitergeleitet. Dieses kann eine erhöhte Systemlast erzeugen.<br>In dem Feld \\\'Trigger Device Global Whitelist:\\\' kann dieses eingeschränkt werden , indem Devices oder Module benannt werden , deren Events Berücksichtigt werden. Sobald hier ein Eintrag erfolgt , werden nur noch Diese berücksichtigt , gibt es keinen Eintrag , werden alle berücksichtigt ( Whitelist ).<br> Format: Die einzelnen Angaben müssen durch Komma getrennt werden .<br><br>Mögliche Angaben :<br>Modultypen: TYPE=CUL_HM<br>Devicenamen: NAME<br><br>';}
-
- if (from == 'addevent'){
- text = text + 'Hier können manuell Events zugefügt werden , die in den Auswahllisten verfügbar sein sollen und auf die das Modul reagiert.<br>Grundsätzlich ist zu unterscheiden , ob das Device im Normal-, oder Globalmode betrieben wird<br>Im Normalmode bestehen die Events aus 2 Teilen , dem Reading und dem Wert \"state:on\"<br>Wenn sich das Device im GLOBAL Mode befindet müssen die Events aus 3 Teilen bestehen , dem Devicename, dem Reading und dem Wert \"device:state:on\".<br>Wird hier nur ein \"*\" angegeben , reagiert der entsprechende Zweig auf alle eingehenden Events.<br>Weitherhin sind folgende Syntaxmöglichkeiten vorgesehen :<br> device:state:*, device:*:*, *:state:* , etc.<br>Der Wert kann mehrere Auswahlmöglichkeiten haben , durch folgende Syntax: \"device:state:(on/off)\". In diesem Fal reagiert der Zweig sowohl auf den Wert on, als auch auf off.<br><br>Es können mehrere Evebts gleichzeitig angelegt werden . Diese sind durch Komma zu trennen .<br><br>Seit V1.7 kann hier die gängige RegEx-Formulierung erfolgen.';}
-
- if (from == 'condition'){
- text = text + 'Hier kann die Angabe von Bedingungen erfolgen, die erfüllt sein müssen um den Schaltbefehl auszuführen.<br>Diese Bedingunge sind eng an DOIF- Bedingungen angelehnt.<br><br>Zeitabhängiges schalten: [19.10-23:00] - Schaltbefehl erfolgt nur in angegebenem Zeitraum<br>Readingabhängiges schalten [Devicename:Reading] =/>/< X oder [Devicename:Reading] eq \"x\" - Schaltbefehl erfolgt nur bei erfüllter Bedingung.<br>Achtung! Bei der Abfrage von Readings nach Strings ( on,off,etc. ) ist statt \"=\" \"eq\" zu nutzen und der String muss in \"x\" gesetzt werden!<br> Die Kombination mehrerer Bedingungen und Zeiten ist durch AND oder OR möglich:<br> [19.10-23:00] AND [Devicename:Reading] = 10 - beide Bedingungen müssen erfüllt sein<br>[19.10-23:00] OR [Devicename:Reading] = 10 - eine der Bedingungen muss erfüllt sein.<br>Es ist auf korrekte Eingabe der Leerzeichen zu achten.<br><br>sunset - Bedingungen werden mit zusätzlichen {} eingefügt z.B. : [{ sunset() }-23:00].<br><br>Variable \$we:<br>Die globlae Variable \$we ist nutzbar und muss {} gesetzt werden .<br>{ !\$we } löst den Schaltvorgang nur Werktagen aus<br>{ \$we } löst den Schaltvorgang nur Wochenenden, Feiertagen aus<br><br>Soll nur an bestimmten Wochentagen geschaltet werden, muss eine Zeitangsbe gemacht werden und durch z.B. |135 ergänzt werden.<br>[10:00-11:00|13] würde den Schaltvorgang z.B nur Montag und Mitwoch zwischen 10 uhr und 11 uhr auslösen. Hierbei zählen die Wochentage von 1-7 für Montag-Sonntag.<br>Achtung: Bei Anwendung der geschweiften Klammern zur einletung eines Perlasdrucks ist unbedingt auf die Leerzeichen hinter und vor der Klammer zu achten !<br>Überschreitet die Zeitangabe die Tagesgrenze (24.00 Uhr ), so gelten die angegebenen Tage noch bis zum ende der angegebenen Schaltzeit , d.H. es würde auch am Mitwoch noch der schaltvorgang erfolgen, obwohl als Tagesvorgabe Dienstag gesetzt wurde.<br><br>\$EVENT Variable: Die Variable EVENT enthält den auslösenden Trigger, d.H. es kann eine Reaktion in direkter Abhängigkeit zum auslösenden Trigger erfolgen.<br>[\$EVENT] eq \"state:on\" würde den Kommandozweig nur dann ausführen, wenn der auslösende Trigger \"state:on\" war.<br>Wichtig ist dieses, wenn bei den Triggerdetails nicht schon auf ein bestimmtes Event getriggert wird, sondern hier durch die Nutzung eines wildcards (*) auf alle Events getriggert wird, oder auf alle Events eines Readings z.B. (state:*)<br><br>Bei eingestellter Delayfunktion werden die Bedingungen je nach Einstellung sofort,verzögert oder sowohl-als-auch überprüft, d.H hiermit sind verzögerte Ein-, und Ausschaltbefehle möglich die z.B Nachlauffunktionen oder verzögerte Einschaltfunktionen ermöglichen, die sich selbst überprüfen. z.B. [wenn Licht im Bad an -> schalte Lüfter 2 Min später an -> nur wenn Licht im Bad noch an ist]<br><br>Anstatt einer Verzögerung kann hier auch eine festgelegte Schaltzeit erfolgen.';}
-
- if (from == 'onoff'){
- text = text + 'Einstellung des auzuführenden Kommandos bei entsprechendem getriggerten Event.<br>Bei angebotenen Zusatzfeldern kann ein Verweis auf ein Reading eines anderen Devices gesetzt werden mit [Device:Reading].<br>\$NAME wird ersetzt durch den Namen des triggernden Devices.<br><br>Bei Nutzung von FreeCmd kann hier entweder reiner FhemCode, oder reiner Perlcode verwendet werden. Perlcode muss mit geschweiften Klammern beginnen und enden. Das Mischen beider Codes ist nicht zulässig.';}
-
- if (from == 'affected'){
- text = text + 'Einstellung der Geräte, die auf ein Event oder zu einer bestimmten Zeit reagieren sollen.<br>Die Auswahl von FreeCmd ermöglicht eine deviceungebundene Befehlseingabe oder die Eingabe von reinem Perlcode.';}
- if (from == 'repeats'){
- text = text + 'Eingabe von Befehlswiederholungen.<br>Bei Belegung der Felder wird ein Befehl um die Angabe \"Repeats\" mit der jeweiligen Verzögerung \"Repeatdelay in sec\" wiederholt.<br>In dem Feld \"Repeats\" ist eine Angabe im \"setmagic\"-Format möglich.';}
- if (from == 'priority'){
- text = text + 'priority - Auswahl der Reihenfolge der Befehlsabarbeitung. Ein Befehl mit der Nr. 1 wird als erstes ausgeführt , die höchste Nummer zuletzt.<br> Sollte mehrere Befehle die gleiche Nummer haben , so werden diese Befehle in dargestellter Reihenfolge ausgeführt.<br><br>ID - Devices denen eine ID zugewiesen ist , werden in der normalen abarbeitung der Befehle nicht mehr berücksichtigt und somit nicht ausgeführt. Wenn eine ID-Zuweisung erfolgt ist, kann dieser Befehlszweig nur noch über das cmd set DEVICE ID NR on/off erfolgen. Diese Option wird nur in Ausnahmefällen benötigt , wenn die Pipes nicht ausrechend sind um verschiedene Aktionen unter verschiedenen Bedingungen auszuführen. ';}
- if (from == 'saveevent'){
- text = text + 'Bei Anwahl dieser Option werden alle eingehenden Events des ausgewählten Triggerdevices gespeichert und sind in den Auswahlfeldern \"execute cmd1\" und \"execute cmd2\" sowie in allen \"Test-Condition\" zur Auswahl verfügbar.<br>Diese Auswahl sollte zur Resourcenschonung nach der Einrichtung des MSwitchdevices abgewählt werden , da hier je nach Trigger erhebliche Datenmengen anfallen können und gespeichert werden.';}
-
- if (from == 'execcmd'){
- text = text + 'In diesem Feld wird das Event bestimmt, welches zur Ausführung des cmd Zweiges 1 oder 2 führt. Hier stehen entweder gespeicherte Events zur Verfügung ( wenn \"Save incomming events\" aktiviert ist ) , oder es können mit \"Add event manually\" Events hinzugefügt werden. ';}
-
- var textfinal =\"<div style ='font-size: small;'>\"+ text +\"</div>\";
- FW_okDialog(textfinal);
- return;
- }";
- }
- $j1 .= "
- function aktvalue(target,cmd){
- document.getElementById(target).value = cmd;
- return;
- }
- function noarg(target,copytofield){
- document.getElementById(copytofield).value = '';
- document.getElementById(target).innerHTML = '';
- return;
- }
-
- function noaction(target,copytofield){
- document.getElementById(copytofield).value = '';
- document.getElementById(target).innerHTML = '';
- return;}
- function slider(first,step,last,target,copytofield){
- var selected =document.getElementById(copytofield).value;
- var selectfield = \" <br><input type='text' id='\" + target +\"_opt' size='3' value='' readonly> \" + first +\"<input type='range' min='\" + first +\"' max='\" + last + \"' value='\" + selected +\"' step='\" + step + \"' onchange=\\\"javascript: showValue(this.value,'\" + copytofield + \"','\" + target + \"')\\\">\" + last ;
- document.getElementById(target).innerHTML = selectfield + '<br>';
- var opt = target + '_opt';
- document.getElementById(opt).value=selected;
- return;
- }
- function showValue(newValue,copytofield,target){
- var opt = target + '_opt';
- document.getElementById(opt).value=newValue;
- document.getElementById(copytofield).value = newValue;
- }
- function showtextfield(newValue,copytofield,target){
- document.getElementById(copytofield).value = newValue;
- }
- function textfield(copytofield,target){
- //alert(copytofield,target);
- var selected =document.getElementById(copytofield).value;
- if (copytofield.indexOf('cmdonopt') != -1) {
- var selectfield = \" <br><input type='text' size='30' value='\" + selected +\"' onchange=\\\"javascript: showtextfield(this.value,'\" + copytofield + \"','\" + target + \"')\\\">\" ;
- document.getElementById(target).innerHTML = selectfield + '<br>';
- }
- else{
- var selectfield = \"<input type='text' size='30' value='\" + selected +\"' onchange=\\\"javascript: showtextfield(this.value,'\" + copytofield + \"','\" + target + \"')\\\">\" ;
- document.getElementById(target).innerHTML = selectfield + '<br>';
- }
- return;
- }
- function selectfield(args,target,copytofield){
- var cmdsatz = args.split(\",\");
- var selectstart = \"<select id=\\\"\" +target +\"1\\\" name=\\\"\" +target +\"1\\\" onchange=\\\"javascript: aktvalue('\" + copytofield + \"',document.getElementById('\" +target +\"1').value)\\\">\";
- var selectend = '<\\select>';
- var option ='<option value=\"noArg\">noArg</option>';
- var i;
- var len = cmdsatz.length;
- var selected =document.getElementById(copytofield).value;
- for (i=0; i<len; i++){
- if (selected == cmdsatz[i]){
- option += '<option selected value=\"' + cmdsatz[i] + '\">' + cmdsatz[i] + '</option>';
- }
- else{
- option += '<option value=\"' + cmdsatz[i] + '\">' + cmdsatz[i] + '</option>';
- }
- }
- var selectfield = selectstart + option + selectend;
- document.getElementById(target).innerHTML = selectfield + '<br>';
- return;
- }
- function activate(state,target,options,copytofield) ////aufruf durch selctfield
- {
- var globaldetails3='undefined';
- var x = document.getElementsByClassName('devdetails2');
- for (var i = 0; i < x.length; i++)
- {
- var t = x[i].id;
- globaldetails3 +=document.getElementById(t).value;
- }
-
- if ( globaldetails2 )
- {
- if (globaldetails3 != globaldetails2)
- {
- globallock =' unsaved device actions';
- [ \"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\",\"aw_dev\"].forEach (lock,);
- randomdev.forEach (lock);
-
- }
- else
- {
- [ \"aw_trig\",\"aw_md1\",\"aw_md2\",\"aw_addevent\",\"aw_dev\"].forEach (unlock,);
- randomdev.forEach (unlock);
- }
- }
-
- var ausgabe = target + '<br>' + state + '<br>' + options;
- if (state == 'no_action'){noaction(target,copytofield);return}
- var optionarray = options.split(\" \");
- var werte = new Array();
- for (var key in optionarray )
- {
- var satz = optionarray[key].split(\":\");
- werte[satz[0]] = satz[1];
- }
- var devicecmd = new Array();
- if (typeof werte[state] === 'undefined') {werte[state]='textField';}
- devicecmd = werte[state].split(\",\");
- if (devicecmd[0] == 'noArg'){noarg(target,copytofield);return;}
- //else if (devicecmd[0] == 'slider'){slider(devicecmd[1],devicecmd[2],devicecmd[3],target,copytofield);return;}
- else if (devicecmd[0] == 'slider'){textfield(copytofield,target);return;}
- else if (devicecmd[0] == 'undefined'){textfield(copytofield,target);return;}
- else if (devicecmd[0] == 'textField'){textfield(copytofield,target);return;}
- else if (devicecmd[0] == 'colorpicker'){textfield(copytofield,target);return;}
- else if (devicecmd[0] == 'RGB'){textfield(copytofield,target);return;}
- else if (devicecmd[0] == 'no_Action'){noaction();return;}
- else {selectfield(werte[state],target,copytofield);return;}
-
- return;
- }
-
- function changesort(){
- sortby = \$(\"[name=sort]\").val();
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" sort_device \"+sortby;
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }
-
-
- function addevice(device){
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" add_device \"+device;
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }
- function deletedevice(device){
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" del_device \"+device;
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- }
- ";
- $j1 .=
- "var t=\$(\"#MSwitchWebTR\"), ip=\$(t).attr(\"ip\"), ts=\$(t).attr(\"ts\");
- FW_replaceWidget(\"[name=aw_ts]\", \"aw_ts\", [\"time\"], \"12:00\");
- \$(\"[name=aw_ts] input[type=text]\").attr(\"id\", \"aw_ts\");
-
- // modify trigger aw_save
- \$(\"#aw_md\").click(function(){
- var nm = \$(t).attr(\"nm\");
- trigon = \$(\"[name=trigon]\").val();
- trigon = trigon.replace(/ /g,'~');
- trigoff = \$(\"[name=trigoff]\").val();
- trigoff = trigoff.replace(/ /g,'~');
- trigcmdon = \$(\"[name=trigcmdon]\").val();
- trigcmdon = trigcmdon.replace(/ /g,'~');
- trigcmdoff = \$(\"[name=trigcmdoff]\").val();
- trigcmdoff = trigcmdoff.replace(/ /g,'~');
- trigsave = \$(\"[name=aw_save]\").prop(\"checked\") ? \"ja\":\"nein\";
- trigwhite = \$(\"[name=triggerwhitelist]\").val();
- if (trigcmdon == trigon && trigcmdon != 'no_trigger' && trigon != 'no_trigger'){
- FW_okDialog('on triggers for \\'switch Test on + execute on commands\\' and \\'execute on commands only\\' may not be the same !');
- return;
- }
- if (trigcmdoff == trigoff && trigcmdoff != 'no_trigger' && trigoff != 'no_trigger'){
- FW_okDialog('off triggers for \\'switch Test off + execute on commands\\' and \\'execute off commands only\\' may not be the same !');
- return;
- }
- if (trigon == trigoff && trigon != 'no_trigger'){
- FW_okDialog('trigger for \\'switch Test on + execute on commands\\' and \\'switch Test off + execute off commands\\' must not both be \\'*\\'');
- return;
- }
- var def = nm+\" trigger \"+trigon+\" \"+trigoff+\" \"+trigsave+\" \"+trigcmdon+\" \"+trigcmdoff+\" \" ;
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- //delete trigger
- \$(\"#aw_md2\").click(function(){
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" del_trigger \";
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- //aplly filter to trigger
- \$(\"#aw_md1\").click(function(){
- var nm = \$(t).attr(\"nm\");
- var def = nm+\" filter_trigger \";
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
- \$(\"#aw_trig\").click(function(){
- var nm = \$(t).attr(\"nm\");
- trigdev = \$(\"[name=trigdev]\").val();
- //trigdev = trigdev.replace(/\:/g,'#[dp]');
- //alert(trigdev);
-
-
- timeon = \$(\"[name=timeon]\").val();
- timeoff = \$(\"[name=timeoff]\").val();
- timeononly = \$(\"[name=timeononly]\").val();
- timeoffonly = \$(\"[name=timeoffonly]\").val();
-
- trigdevcond = \$(\"[name=triggercondition]\").val();
-
- //trigdevcond = trigdevcond.replace(/:/g,'#[dp]');
-
- trigdevcond = trigdevcond.replace(/\\./g,'#[pt]');
- trigdevcond = trigdevcond.replace(/:/g,'#[dp]');
- trigdevcond= trigdevcond.replace(/~/g,'#[ti]');
- //trigdevcond = trigdevcond.replace(/ /g,'~');
- trigdevcond = trigdevcond.replace(/ /g,'#[sp]');
-
- trigdevcond = trigdevcond+':';
-
- timeon = timeon.replace(/ /g, '');
- timeoff = timeoff.replace(/ /g, '');
- timeononly = timeononly.replace(/ /g, '');
- timeoffonly = timeoffonly.replace(/ /g, '');
-
- timeon = timeon.replace(/:/g, '#[dp]');
- timeoff = timeoff.replace(/:/g, '#[dp]');
- timeononly = timeononly.replace(/:/g, '#[dp]');
- timeoffonly = timeoffonly.replace(/:/g, '#[dp]');
-
- timeon = timeon+':';
- timeoff = timeoff+':';
- timeononly = timeononly+':';
- timeoffonly = timeoffonly+':';
- trigwhite = \$(\"[name=triggerwhitelist]\").val();
- var def = nm+\" set_trigger \"+trigdev+\" \"+timeon+\" \"+timeoff+\" \"+timeononly+\" \"+timeoffonly+\" \"+trigdevcond+\" \"+trigwhite+\" \" ;
- def = encodeURIComponent(def);
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- \$(\"#aw_addevent\").click(function(){
- var nm = \$(t).attr(\"nm\");
- event = \$(\"[name=add_event]\").val();
- event= event.replace(/ /g,'~');
- event= event.replace(/\\|/g,'[bs]');
- if (event == ''){
- //alert('no event specified');
- return;
- }
- var def = nm+\" addevent \"+event+\" \";
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- \$(\"#aw_dev\").click(function(){
- var nm = \$(t).attr(\"nm\");
- devices = \$(\"[name=affected_devices]\").val();
- var def = nm+\" devices \"+devices+\" \";
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- \$(\"#aw_det\").click(function(){
- var nm = \$(t).attr(\"nm\");
- devices = '';
- $javaform
- devices = devices.replace(/:/g,'#[dp]');
- devices = devices.replace(/;/g,'#[se]');
- devices = devices.replace(/ /g,'#[sp]');
- devices = devices.replace(/%/g,'#[pr]');
- devices = encodeURIComponent(devices);
- var def = nm+\" details \"+devices+\" \";
- location = location.pathname+\"?detail=" . $Name . "&cmd=set \"+addcsrf(def);
- });
-
- function switchlock(){
- test = document.getElementById('lockedit').checked ;
- if (test){
- \$(\"#devices\").prop(\"disabled\", 'disabled');
- document.getElementById('aw_great').value='edit list';
- }
- else{
- \$(\"#devices\").prop(\"disabled\", false);
- document.getElementById('aw_great').value='schow greater list';
- }
- }
-
- function deviceselect(){
- sel ='<div style=\"white-space:nowrap;\"><br>';
- var ausw=document.getElementById('devices');
- for (i=0; i<ausw.options.length; i++)
- {
- var pos=ausw.options[i];
- if(pos.selected)
- {
- //targ.options[i].selected = true;
- sel = sel+'<input id =\"Checkbox-'+i+'\" checked=\"checked\" name=\"Checkbox-'+i+'\" type=\"checkbox\" value=\"test\" /> '+pos.value+'<br />';
- }
- else
- {
- sel = sel+'<input id =\"Checkbox-'+i+'\" name=\"Checkbox-'+i+'\" type=\"checkbox\" /> '+pos.value+'<br />';
- }
- }
- sel = sel+'</div>';
- FW_okDialog(sel,'',removeFn) ;
- }
-
- function bigwindow(targetid){
- targetval =document.getElementById(targetid).value;
- sel ='<div style=\"white-space:nowrap;\"><br>';
- sel = sel+'<textarea id=\"valtrans\" cols=\"80\" name=\"TextArea1\" rows=\"10\" onChange=\" document.getElementById(\\\''+targetid+'\\\').value=this.value; \">'+targetval+'</textarea>';
- sel = sel+'</div>';
- FW_okDialog(sel,'');
- }
-
- function removeFn() {
- var targ = document.getElementById('devices');
- for (i = 0; i < targ.options.length; i++) {
- test = document.getElementById('Checkbox-' + i).checked;
- targ.options[i].selected = false;
- if (test) {
- targ.options[i].selected = true;
- }
- }
- }
-
- \$(\"#aw_little\").click(function(){
- var veraenderung = 3; // Textfeld veraendert sich stets um 3 Zeilen
- var sel = document.getElementById('textfie').innerHTML;
- var show = document.getElementById('textfie2');
- var2 = \"size=\\\"6\\\"\";
- var result = sel.replace(/size=\\\"15\\\"/g,var2);
- document.getElementById('textfie').innerHTML = result;
- });
- }
- </script>";
- return "$ret<br>$detailhtml<br>$j1";
- }
- ####################
- sub MSwitch_makeCmdHash($) {
- my $loglevel = 5;
- my ($Name) = @_;
- # detailsatz in scalar laden
- my @devicedatails;
- @devicedatails =
- split( /#\[ND\]/,
- ReadingsVal( $Name, '.Device_Affected_Details', 'no_device' ) )
- if defined ReadingsVal( $Name, '.Device_Affected_Details', 'no_device' )
- ; #inhalt decice und cmds durch komma getrennt
- my %savedetails;
- foreach (@devicedatails) {
- # ersetzung
- $_ =~ s/#\[sp\]/ /g;
- $_ =~ s/#\[nl\]/\n/g;
- $_ =~ s/#\[se\]/;/g;
- $_ =~ s/#\[dp\]/:/g;
- $_ =~ s/\(DAYS\)/|/g;
- $_ =~ s/#\[ko\]/,/g; #neu
- $_ =~ s/#\[bs\]/\\/g; #neu
- my @detailarray = split( /#\[NF\]/, $_ )
- ; #enthält daten 0-5 0 - name 1-5 daten 7 und9 sind zeitangaben
- my $key = '';
- my $testtimestroff = $detailarray[7];
- $key = $detailarray[0] . "_delayatonorg";
- $savedetails{$key} = $detailarray[7];
- if ( $testtimestroff ne '[random]' ) {
- $testtimestroff =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtimestroff ne "[:]" && $testtimestroff ne "[\$:]" ) {
- my $hdel = ( substr( $detailarray[7], 0, 2 ) ) * 3600;
- my $mdel = ( substr( $detailarray[7], 3, 2 ) ) * 60;
- my $sdel = ( substr( $detailarray[7], 6, 2 ) ) * 1;
- $detailarray[7] = $hdel + $mdel + $sdel;
- }
- }
- my $testtimestron = $detailarray[8];
- $key = $detailarray[0] . "_delayatofforg";
- $savedetails{$key} = $detailarray[8];
- if ( $testtimestron ne '[random]' ) {
- $testtimestron =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtimestron ne "[:]" && $testtimestroff ne "[\$:]" ) {
- my $hdel = substr( $detailarray[8], 0, 2 ) * 3600;
- my $mdel = substr( $detailarray[8], 3, 2 ) * 60;
- my $sdel = substr( $detailarray[8], 6, 2 ) * 1;
- $detailarray[8] = $hdel + $mdel + $sdel;
- }
- }
- $key = $detailarray[0] . "_on";
- $savedetails{$key} = $detailarray[1];
- $key = $detailarray[0] . "_off";
- $savedetails{$key} = $detailarray[2];
- $key = $detailarray[0] . "_onarg";
- $savedetails{$key} = $detailarray[3];
- $key = $detailarray[0] . "_offarg";
- $savedetails{$key} = $detailarray[4];
- $key = $detailarray[0] . "_delayaton";
- $savedetails{$key} = $detailarray[5];
- $key = $detailarray[0] . "_delayatoff";
- $savedetails{$key} = $detailarray[6];
- $key = $detailarray[0] . "_timeon";
- $savedetails{$key} = $detailarray[7];
- $key = $detailarray[0] . "_timeoff";
- $savedetails{$key} = $detailarray[8];
- $key = $detailarray[0] . "_repeatcount";
- if ( defined $detailarray[11] ) {
- $savedetails{$key} = $detailarray[11];
- }
- else {
- $savedetails{$key} = 0;
- }
- $key = $detailarray[0] . "_repeattime";
- if ( defined $detailarray[12] ) {
- $savedetails{$key} = $detailarray[12];
- }
- else {
- $savedetails{$key} = 0;
- }
- $key = $detailarray[0] . "_priority";
- if ( defined $detailarray[13] ) {
- $savedetails{$key} = $detailarray[13];
- }
- else {
- $savedetails{$key} = 1;
- }
- $key = $detailarray[0] . "_id";
- if ( defined $detailarray[14] ) {
- $savedetails{$key} = $detailarray[14];
- }
- else {
- $savedetails{$key} = 0;
- }
- ###
- $key = $detailarray[0] . "_exit1";
- if ( defined $detailarray[16] ) {
- $savedetails{$key} = $detailarray[16];
- }
- else {
- $savedetails{$key} = 0;
- }
- ###
- $key = $detailarray[0] . "_exit2";
- if ( defined $detailarray[17] ) {
- $savedetails{$key} = $detailarray[17];
- }
- else {
- $savedetails{$key} = 0;
- }
- ###
- ###
- $key = $detailarray[0] . "_showreihe";
- if ( defined $detailarray[18] ) {
- $savedetails{$key} = $detailarray[18];
- }
- else {
- $savedetails{$key} = 0;
- }
- ###
- $key = $detailarray[0] . "_comment";
- if ( defined $detailarray[15] ) {
- $savedetails{$key} = $detailarray[15];
- }
- else {
- $savedetails{$key} = '';
- }
- $key = $detailarray[0] . "_conditionon";
- if ( defined $detailarray[9] ) {
- $savedetails{$key} = $detailarray[9];
- }
- else {
- $savedetails{$key} = '';
- }
- $key = $detailarray[0] . "_conditionoff";
- if ( defined $detailarray[10] ) {
- $savedetails{$key} = $detailarray[10];
- }
- else {
- $savedetails{$key} = '';
- }
- }
- my @pass = %savedetails;
- return @pass;
- }
- ########################################
- sub MSwitch_Delete_Triggermemory($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $events = ReadingsVal( $Name, '.Device_Events', '' );
- my $Triggerdevice = $hash->{Trigger_device};
- my $triggeron = ReadingsVal( $Name, '.Trigger_on', 'no_trigger' );
- if ( !defined $triggeron ) { $triggeron = "" }
- my $triggeroff = ReadingsVal( $Name, '.Trigger_off', 'no_trigger' );
- if ( !defined $triggeroff ) { $triggeroff = "" }
- my $triggercmdon = ReadingsVal( $Name, '.Trigger_cmd_on', 'no_trigger' );
- if ( !defined $triggercmdon ) { $triggercmdon = "" }
- my $triggercmdoff = ReadingsVal( $Name, '.Trigger_cmd_off', 'no_trigger' );
- if ( !defined $triggercmdoff ) { $triggercmdoff = "" }
- my $triggerdevice = ReadingsVal( $Name, 'Trigger_device', '' );
- delete( $hash->{helper}{events} );
- $hash->{helper}{events}{$triggerdevice}{'no_trigger'} = "on";
- $hash->{helper}{events}{$triggerdevice}{$triggeron} = "on";
- $hash->{helper}{events}{$triggerdevice}{$triggeroff} = "on";
- $hash->{helper}{events}{$triggerdevice}{$triggercmdon} = "on";
- $hash->{helper}{events}{$triggerdevice}{$triggercmdoff} = "on";
- readingsSingleUpdate( $hash, ".Device_Events", 'no_trigger', 1 );
- my $eventhash = $hash->{helper}{events}{$triggerdevice};
- $events = "";
- foreach my $name ( keys %{$eventhash} ) {
- $name =~ s/#\[tr//ig;
- $events = $events . $name . '#[tr]';
- }
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- readingsSingleUpdate( $hash, ".Device_Events", $events, 0 );
- return;
- }
- ###########################################################################
- sub MSwitch_Exec_Notif($$$$$) {
- #Inhalt Übergabe -> push @cmdarray, $own_hash . ',on,check,' . $eventcopy1
- my ( $hash, $comand, $check, $event, $execids ) = @_;
- my $name = $hash->{NAME};
- my $protokoll = '';
- my $satz;
- $execids = "0";
- my $exittest = '';
- $exittest = "1" if $comand eq "on";
- $exittest = "2" if $comand eq "off";
- my $ekey = '';
- my $out = '0';
- MSwitch_LOG( $name, 6,
- "$name: execnotif -> $hash, $comand, $check, $event,$execids " );
- return ""
- if ( IsDisabled($name) )
- ; # Return without any further action if the module is disabled
- my %devicedetails = MSwitch_makeCmdHash($name);
- # betroffene geräte suchen
- my @devices =
- split( /,/, ReadingsVal( $name, '.Device_Affected', 'no_device' ) );
- my $update = '';
- my $testtoggle = '';
- MSwitch_LOG( $name, 6,
- "$name: zu schaltende devices -> " . @devices . " @devices" );
- # liste nach priorität ändern , falls expert
- @devices = MSwitch_priority( $hash, $execids, @devices );
- LOOP45: foreach my $device (@devices) {
- $out = '0';
- if ( AttrVal( $name, 'MSwitch_Expert', "0" ) eq '1' ) {
- $ekey = $device . "_exit" . $exittest;
- $out = $devicedetails{$ekey};
- }
- if ( AttrVal( $name, 'MSwitch_Delete_Delays', '0' ) eq '1' ) {
- MSwitch_Delete_Delay( $hash, $device );
- }
- my @devicesplit = split( /-AbsCmd/, $device );
- my $devicenamet = $devicesplit[0];
- # teste auf on kommando
- my $key = $device . "_" . $comand;
- my $timerkey = $device . "_time" . $comand;
- my $testtstate = $devicedetails{$timerkey};
- $testtstate =~ s/[A-Za-z0-9#\.\-_]//g;
- if ( $testtstate eq "[:]" || $testtstate eq "[\$:]" ) {
- $devicedetails{$timerkey} =
- eval MSwitch_Checkcond_state( $devicedetails{$timerkey}, $name );
- if ( $devicedetails{$timerkey} =~ m/[0-9]\d:[0-9]\d:[0-9]\d/ ) {
- MSwitch_LOG( $name, 5, "$name: format ok " );
- my $hdel = ( substr( $devicedetails{$timerkey}, 0, 2 ) ) * 3600;
- my $mdel = ( substr( $devicedetails{$timerkey}, 3, 2 ) ) * 60;
- my $sdel = ( substr( $devicedetails{$timerkey}, 6, 2 ) ) * 1;
- $devicedetails{$timerkey} = $hdel + $mdel + $sdel;
- }
- else {
- MSwitch_LOG( $name, 1,
- "$name: ERROR Timerformat "
- . $devicedetails{$timerkey}
- . " fehlerhaf " );
- $devicedetails{$timerkey} = 0;
- }
- }
- MSwitch_LOG( $name, 6,
- "$name: timer des devices -> " . $devicedetails{$timerkey} );
- # teste auf condition
- # antwort $execute 1 oder 0 ;
- my $conditionkey = $device . "_condition" . $comand;
- if ( $devicedetails{$key} ne "" && $devicedetails{$key} ne "no_action" )
- {
- my $cs = '';
- if ( $devicenamet eq 'FreeCmd' ) {
- $cs = " $devicedetails{$device.'_'.$comand.'arg'}";
- $cs = MSwitch_makefreecmd( $hash, $cs );
- }
- else {
- $cs =
- "set $devicenamet $devicedetails{$device.'_'.$comand} $devicedetails{$device.'_'.$comand.'arg'}";
- }
- #Variabelersetzung
- $cs =~ s/\$NAME/$hash->{helper}{eventfrom}/;
- $cs =~ s/\$SELF/$name/;
- if ( $devicedetails{$timerkey} eq "0"
- || $devicedetails{$timerkey} eq "" )
- {
- # teste auf condition
- # antwort $execute 1 oder 0 ;
- $conditionkey = $device . "_condition" . $comand;
- my $execute =
- MSwitch_checkcondition( $devicedetails{$conditionkey},
- $name, $event );
- $testtoggle = 'undef';
- if ( $execute eq 'true' ) {
- $testtoggle = $cs;
- #############
- Log3( $name, 3,
- "$name MSwitch_Restartcm: Befehlsausfuehrung -> $cs "
- . __LINE__ );
- my $toggle = '';
- if ( $cs =~ m/set (.*)(MSwitchtoggle)(.*)/ ) {
- $toggle = $cs;
- $cs = MSwitch_toggle( $hash, $cs );
- }
- MSwitch_LOG( $name, 6,
- "$name: auszufuehrender Befehl -> " . $cs );
- # neu
- $devicedetails{ $device . '_repeatcount' } = 0
- if !defined $devicedetails{ $device . '_repeatcount' };
- $devicedetails{ $device . '_repeattime' } = 0
- if !defined $devicedetails{ $device . '_repeattime' };
- MSwitch_LOG( $name, 6, "$name: teste auf repeasts " );
- my $x = 0;
- while ( $devicedetails{ $device . '_repeatcount' } =~
- m/\[(.*)\:(.*)\]/ )
- {
- $x++; # exit
- last if $x > 20; # exit
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeatcount' } = $setmagic;
- }
- $x = 0;
- while ( $devicedetails{ $device . '_repeattime' } =~
- m/\[(.*)\:(.*)\]/ )
- {
- $x++; # exit
- last if $x > 20; # exit
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeattime' } = $setmagic;
- }
- if ( $devicedetails{ $device . '_repeatcount' } eq "" ) {
- $devicedetails{ $device . '_repeatcount' } = 0;
- }
- if ( $devicedetails{ $device . '_repeattime' } eq "" ) {
- $devicedetails{ $device . '_repeattime' } = 0;
- }
- MSwitch_LOG( $name, 6,
- "$name: anzahl repeats -> "
- . $devicedetails{ $device . '_repeatcount' } );
- MSwitch_LOG( $name, 6,
- "$name: delay repeats -> "
- . $devicedetails{ $device . '_repeattime' } );
- if ( AttrVal( $name, 'MSwitch_Expert', "0" ) eq '1'
- && $devicedetails{ $device . '_repeatcount' } > 0
- && $devicedetails{ $device . '_repeattime' } > 0 )
- {
- my $i;
- for (
- $i = 0 ;
- $i <= $devicedetails{ $device . '_repeatcount' } ;
- $i++
- )
- {
- my $msg = $cs . "|" . $name;
- if ( $toggle ne '' ) {
- $msg = $toggle . "|" . $name;
- }
- my $timecond =
- gettimeofday() +
- ( ( $i + 1 ) *
- $devicedetails{ $device . '_repeattime' } );
- $msg = $msg . "," . $timecond;
- $hash->{helper}{repeats}{$timecond} = "$msg";
- MSwitch_LOG( $name, 6,
- "$name: repeat gesetzt -> "
- . $timecond . " "
- . $msg );
- InternalTimer( $timecond, "MSwitch_repeat", $msg );
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von "
- . $device );
- last LOOP45;
- }
- }
- }
- my $todec = $cs;
- $cs = MSwitch_dec( $hash, $todec );
- ############################
- if ( AttrVal( $name, 'MSwitch_Debug', "0" ) eq '2' ) {
- MSwitch_LOG( $name, 6, "$name: execute -> " . $cs );
- }
- else {
- if ( $cs =~ m/{.*}/ ) {
- eval($cs);
- if ($@) {
- MSwitch_LOG( $name, 1,
- "$name MSwitch_Set: ERROR $cs: $@ "
- . __LINE__ );
- }
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von "
- . $device );
- last LOOP45;
- }
- }
- else {
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- MSwitch_LOG( $name, 1,
- "$name Absent_Exec_Notif $comand: ERROR $device: $errors -> Comand: $cs"
- );
- }
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von "
- . $device );
- last LOOP45;
- }
- }
- }
- my $msg = $cs;
- if ( length($msg) > 100 ) {
- $msg = substr( $msg, 0, 100 ) . '....';
- }
- readingsSingleUpdate( $hash, "Exec_cmd", $msg, 1 )
- if $msg ne '';
- }
- }
- else {
- if ( AttrVal( $name, 'MSwitch_RandomTime', '' ) ne ''
- && $devicedetails{$timerkey} eq '[random]' )
- {
- $devicedetails{$timerkey} =
- MSwitch_Execute_randomtimer($hash);
- # ersetzt $devicedetails{$timerkey} gegen randomtimer
- }
- elsif ( AttrVal( $name, 'MSwitch_RandomTime', '' ) eq ''
- && $devicedetails{$timerkey} eq '[random]' )
- {
- $devicedetails{$timerkey} = 0;
- }
- my $timecond = gettimeofday() + $devicedetails{$timerkey};
- my $delaykey = $device . "_delayat" . $comand;
- my $delayinhalt = $devicedetails{$delaykey};
- my $delaykey1 = $device . "_delayat" . $comand . "org";
- my $teststateorg = $devicedetails{$delaykey1};
- $conditionkey = $device . "_condition" . $comand;
- my $execute = "true";
- if ( $delayinhalt ne "delay2" && $delayinhalt ne "at02" ) {
- $execute =
- MSwitch_checkcondition( $devicedetails{$conditionkey},
- $name, $event );
- }
- if ( $execute eq "true" ) {
- if ( $delayinhalt eq 'at0' || $delayinhalt eq 'at1' ) {
- $timecond =
- MSwitch_replace_delay( $hash, $teststateorg );
- }
- if ( $delayinhalt eq 'at1' || $delayinhalt eq 'delay0' ) {
- $conditionkey = "nocheck";
- }
- $cs =~ s/,/##/g;
- my $msg =
- $cs . "#[tr]"
- . $name . "#[tr]"
- . $conditionkey . "#[tr]"
- . $event . "#[tr]"
- . $timecond . "#[tr]"
- . $device;
- $hash->{helper}{delays}{$msg} = $timecond;
- $testtoggle = 'undef';
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt -> " . $cs );
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt name -> " . $name );
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt conditionkey-> "
- . $conditionkey );
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt event-> " . $event );
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt timecond-> " . $timecond );
- MSwitch_LOG( $name, 6,
- "$name: timer gesetzt -> device " . $device );
- InternalTimer( $timecond, "MSwitch_Restartcmd", $msg );
- if ( $out eq '1' ) {
- MSwitch_LOG( $name, 6,
- "$name: Abbruchbefehl erhalten von " . $device );
- last LOOP45;
- }
- }
- }
- }
- if ( $testtoggle ne '' && $testtoggle ne 'undef' ) {
- $satz .= $testtoggle . ',';
- }
- }
- MSwitch_LOG( $name, 6, "$name: return aus execnotif -> " . $satz );
- return $satz;
- }
- ####################
- sub MSwitch_Filter_Trigger($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- MSwitch_LOG( $Name, 5, "$Name: filter saved vents " );
- my $Triggerdevice = $hash->{Trigger_device};
- my $triggeron = ReadingsVal( $Name, '.Trigger_on', 'no_trigger' );
- if ( !defined $triggeron ) { $triggeron = "" }
- my $triggeroff = ReadingsVal( $Name, '.Trigger_off', 'no_trigger' );
- if ( !defined $triggeroff ) { $triggeroff = "" }
- my $triggercmdon = ReadingsVal( $Name, '.Trigger_cmd_on', 'no_trigger' );
- if ( !defined $triggercmdon ) { $triggercmdon = "" }
- my $triggercmdoff = ReadingsVal( $Name, '.Trigger_cmd_off', 'no_trigger' );
- if ( !defined $triggercmdoff ) { $triggercmdoff = "" }
- my $triggerdevice = ReadingsVal( $Name, 'Trigger_device', '' );
- delete( $hash->{helper}{events}{$Triggerdevice} );
- $hash->{helper}{events}{$Triggerdevice}{'no_trigger'} = "on";
- $hash->{helper}{events}{$Triggerdevice}{$triggeron} = "on";
- $hash->{helper}{events}{$Triggerdevice}{$triggeroff} = "on";
- $hash->{helper}{events}{$Triggerdevice}{$triggercmdon} = "on";
- $hash->{helper}{events}{$Triggerdevice}{$triggercmdoff} = "on";
- my $events = ReadingsVal( $Name, '.Device_Events', '' );
- MSwitch_LOG( $Name, 5, "$Name: eventfile " . $events );
- my @eventsall = split( /#\[tr\]/, $events );
- EVENT: foreach my $eventcopy (@eventsall) {
- MSwitch_LOG( $Name, 5, "$Name: getestetes event " . $eventcopy );
- my @filters =
- split( /,/, AttrVal( $Name, 'MSwitch_Trigger_Filter', '' ) )
- ; # beinhaltet filter durch komma getrennt
- foreach my $filter (@filters) {
- if ( $filter eq "*" ) { $filter = ".*"; }
- MSwitch_LOG( $Name, 5, "$Name: getesteter Filter -> " . $filter );
- if ( $eventcopy =~ m/$filter/ ) {
- MSwitch_LOG( $Name, 5,
- "$Name: eingehendes Event ausgefiltert " );
- next EVENT;
- }
- }
- $hash->{helper}{events}{$Triggerdevice}{$eventcopy} = "on";
- }
- my $eventhash = $hash->{helper}{events}{$Triggerdevice};
- $events = "";
- foreach my $name ( keys %{$eventhash} ) {
- $events = $events . $name . '#[tr]';
- }
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- chop($events);
- readingsSingleUpdate( $hash, ".Device_Events", $events, 0 );
- return;
- }
- ####################
- sub MSwitch_Restartcmd($) {
- my $incomming = $_[0];
- my @msgarray = split( /#\[tr\]/, $incomming );
- my $name = $msgarray[1];
- my $hash = $modules{MSwitch}{defptr}{$name};
- return "" if ( IsDisabled($name) );
- $hash->{eventsave} = 'unsaved';
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- MSwitch_LOG( $name, 5, "$name: aufruf restartcmd -> " . $incomming );
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- # checke versionskonflikt der datenstruktur
- if ( ReadingsVal( $name, '.V_Check', $vupdate ) ne $vupdate ) {
- my $ver = ReadingsVal( $name, '.V_Check', '' );
- MSwitch_LOG( $name, 5, "$name: Versionskonflikt - aktion abgebrochen" );
- return;
- }
- my $cs = $msgarray[0];
- $cs =~ s/##/,/g;
- my $conditionkey = $msgarray[2];
- my $event = $msgarray[2];
- my $device = $msgarray[5];
- MSwitch_LOG( $name, 5, "$name: erstelle cmdhash -> " . $name );
- my %devicedetails = MSwitch_makeCmdHash($name);
- if ( AttrVal( $name, 'MSwitch_RandomNumber', '' ) ne '' ) {
- MSwitch_Createnumber1($hash);
- }
- ############ teste auf condition
- ### antwort $execute 1 oder 0 ;
- my $execute = "true";
- MSwitch_LOG( $name, 5,
- "$name: kein aufruf checkcondition - nicht gesetzt ->" . $execute )
- if $devicedetails{$conditionkey} eq ''
- || $devicedetails{$conditionkey} eq 'nocheck';
- if ( $msgarray[2] ne 'nocheck' ) {
- MSwitch_LOG( $name, 5,
- "$name: aufruf checkcondition mit -> "
- . $devicedetails{$conditionkey} );
- $execute = MSwitch_checkcondition( $devicedetails{$conditionkey}, $name,
- $event );
- MSwitch_LOG( $name, 5,
- "$name: ergebniss checkcondition -> " . $execute );
- }
- my $toggle = '';
- if ( $execute eq 'true' ) {
- Log3( $name, 3,
- "$name MSwitch_Restartcm: Befehlsausfuehrung -> $cs " . __LINE__ );
- if ( $cs =~ m/set (.*)(MSwitchtoggle)(.*)/ ) {
- $toggle = $cs;
- $cs = MSwitch_toggle( $hash, $cs );
- }
- MSwitch_LOG( $name, 5,
- "$name: teste repeat -> "
- . $devicedetails{ $device . '_repeatcount' } );
- my $x = 0;
- while (
- $devicedetails{ $device . '_repeatcount' } =~ m/\[(.*)\:(.*)\]/ )
- {
- $x++; # notausstieg notausstieg
- last if $x > 20; # notausstieg notausstieg
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeatcount' } = $setmagic;
- }
- $x = 0;
- while ( $devicedetails{ $device . '_repeattime' } =~ m/\[(.*)\:(.*)\]/ )
- {
- $x++; # notausstieg notausstieg
- last if $x > 20; # notausstieg notausstieg
- my $setmagic = ReadingsVal( $1, $2, 0 );
- $devicedetails{ $device . '_repeattime' } = $setmagic;
- }
- MSwitch_LOG( $name, 5,
- "$name: repetcount nach test -> "
- . $devicedetails{ $device . '_repeatcount' } );
- MSwitch_LOG( $name, 5,
- "$name: repeattime nach test -> "
- . $devicedetails{ $device . '_repeattime' } );
- ######################################
- if ( AttrVal( $name, 'MSwitch_Expert', "0" ) eq '1'
- && $devicedetails{ $device . '_repeatcount' } > 0
- && $devicedetails{ $device . '_repeattime' } > 0 )
- {
- my $i;
- for (
- $i = 0 ;
- $i <= $devicedetails{ $device . '_repeatcount' } ;
- $i++
- )
- {
- my $msg = $cs . "|" . $name;
- if ( $toggle ne '' ) {
- $msg = $toggle . "|" . $name;
- }
- my $timecond = gettimeofday() +
- ( ( $i + 1 ) * $devicedetails{ $device . '_repeattime' } );
- $msg = $msg . "|" . $timecond;
- $hash->{helper}{repeats}{$timecond} = "$msg";
- MSwitch_LOG( $name, 5,
- "$name: repeat gesetzt -> " . $timecond . " - " . $msg );
- InternalTimer( $timecond, "MSwitch_repeat", $msg );
- }
- }
- my $todec = $cs;
- $cs = MSwitch_dec( $hash, $todec );
- ############################
- if ( AttrVal( $name, 'MSwitch_Debug', "0" ) eq '2' ) {
- MSwitch_LOG( $name, 5, "$name: exec comand -> " . $cs );
- }
- else {
- if ( $cs =~ m/{.*}/ ) {
- MSwitch_LOG( $name, 5,
- "$name: exec als perlcode -> " . $cs );
- eval($cs);
- if ($@) {
- MSwitch_LOG( $name, 1,
- "$name MSwitch_Set: ERROR $cs: $@ " . __LINE__ );
- }
- }
- else {
- MSwitch_LOG( $name, 5,
- "$name: execute als fhemcode -> " . $cs );
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- MSwitch_LOG( $name, 1,
- "$name MSwitch_Restartcmd :Fehler bei Befehlsausfuehrung ERROR $errors "
- . __LINE__ );
- }
- }
- }
- if ( length($cs) > 100
- && AttrVal( $name, 'MSwitch_Debug', "0" ) ne '4' )
- {
- $cs = substr( $cs, 0, 100 ) . '....';
- }
- readingsSingleUpdate( $hash, "Exec_cmd", $cs, 1 ) if $cs ne '';
- }
- RemoveInternalTimer($incomming);
- delete( $hash->{helper}{delays}{$incomming} );
- return;
- }
- ####################
- sub MSwitch_checkcondition($$$) {
- # antwort execute 0 oder 1
- my ( $condition, $name, $event ) = @_;
- my $hash = $modules{MSwitch}{defptr}{$name};
- #### kompatibilität v < 2.01
- $condition =~ s/\[\$EVENT\]/"\$EVENT"/g;
- $condition =~ s/\[\$EVTFULL\]/"\$EVTFULL"/g;
- $condition =~ s/\[\$EVTPART1\]/"\$EVTPART1"/g;
- $condition =~ s/\[\$EVTPART2\]/"\$EVTPART2"/g;
- $condition =~ s/\[\$EVTPART3\]/"\$EVTPART3"/g;
- MSwitch_LOG( $name, 6,
- "$name: Checkcondition - Parameter condition -> " . $condition );
- MSwitch_LOG( $name, 6,
- "$name: Checkcondition - Parameter event -> " . $event );
- if ( !defined($condition) ) { return 'true'; }
- if ( $condition eq '' ) { return 'true'; }
-
-
-
- ###### perlersetzung
- ##############
-
- # my $x = 0;
- # while ( $condition =~ m/(.*?){(.*)}(.*)?/ ) {
- # my $firstpart = $1;
- # my $secondpart = $2;
- # my $lastpart = $3;
- # $condition = $firstpart . "test" . $lastpart;
- # $x++;
- # last if $x > 10; #notausstieg
- # }
- #####################################
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if ( AttrVal( $name, 'MSwitch_RandomNumber', '' ) ne '' ) {
- MSwitch_Createnumber($hash);
- }
- my $anzahlk1 = $condition =~ tr/{//;
- my $anzahlk2 = $condition =~ tr/}//;
- if ( $anzahlk1 ne $anzahlk2 ) {
- $hash->{helper}{conditioncheck} = "Klammerfehler";
- return "false";
- }
- $anzahlk1 = $condition =~ tr/(//;
- $anzahlk2 = $condition =~ tr/)//;
- if ( $anzahlk1 ne $anzahlk2 ) {
- $hash->{helper}{conditioncheck} = "Klammerfehler";
- return "false";
- }
- $anzahlk1 = $condition =~ tr/[//;
- $anzahlk2 = $condition =~ tr/]//;
- if ( $anzahlk1 ne $anzahlk2 ) {
- $hash->{helper}{conditioncheck} = "Klammerfehler";
- return "false";
- }
- my $arraycount = '0';
- my $finalstring;
- my $answer;
- my $i;
- my $pos;
- my $pos1;
- my $part;
- my $part1;
- my $part2;
- my $part3;
- my $lenght;
- # wildcardcheck
- my $we = AnalyzeCommand( 0, '{return $we}' );
- my @perlarray;
- ### perlteile trennen
- #######################
- my @evtparts = split( /:/, $event );
- my $evtsanzahl = @evtparts;
- if ( $evtsanzahl < 3 ) {
- my $eventfrom = $hash->{helper}{eventfrom};
- unshift( @evtparts, $eventfrom );
- $evtsanzahl = @evtparts;
- }
- my $evtfull = join( ':', @evtparts );
- $evtparts[2] = '' if !defined $evtparts[2];
- $condition =~ s/\$EVENT/$event/ig;
- $condition =~ s/\$EVTFULL/$evtfull/ig;
- $condition =~ s/\$EVTPART1/$evtparts[0]/ig;
- $condition =~ s/\$EVTPART2/$evtparts[1]/ig;
- $condition =~ s/\$EVTPART3/$evtparts[2]/ig;
- Log3( $name, 5, "condition: " . $condition );
- ######################################
- $condition =~ s/{!\$we}/ !\$we /ig;
- $condition =~ s/{\$we}/ \$we /ig;
- $condition =~ s/{sunset\(\)}/{ sunset\(\) }/ig;
- $condition =~ s/{sunrise\(\)}/{ sunrise\(\) }/ig;
- my $x = 0;
- while ( $condition =~ m/(.*?)(\$NAME)(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $condition = $firstpart . $name . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- $x = 0;
- while ( $condition =~ m/(.*?)(\$SELF)(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $condition = $firstpart . $name . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- my $searchstring;
- $x = 0;
- while ( $condition =~
- m/(.*?)(\[\[[a-zA-Z][a-zA-Z0-9_]{0,30}:[a-zA-Z0-9_]{0,30}\]-\[[a-zA-Z][a-zA-Z0-9_]{0,30}:[a-zA-Z0-9_]{0,30}\]\])(.*)?/
- )
- {
- my $firstpart = $1;
- $searchstring = $2;
- my $lastpart = $3;
- $x++;
- last if $x > 10; #notausstieg
- my $x = 0;
- # Searchstring -> [[t1:state]-[t2:state]]
- while ( $searchstring =~
- m/(.*?)(\[[a-zA-Z][a-zA-Z0-9_]{0,30}:[a-zA-Z0-9_]{0,30}\])(.*)?/ )
- {
- my $read1 = '';
- my $firstpart = $1;
- my $secsearchstring = $2;
- my $lastpart = $3;
- if ( $secsearchstring =~ m/\[(.*):(.*)\]/ ) {
- $read1 = ReadingsVal( $1, $2, 'undef' );
- }
- $searchstring = $firstpart . $read1 . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- $condition = $firstpart . $searchstring . $lastpart;
- }
- $x = 0;
- while ( $condition =~ m/(.*)({ )(.*)(\$we)( })(.*)/ ) {
- last if $x > 20; # notausstieg
- $condition = $1 . " " . $3 . $4 . " " . $6;
- }
- ###################################################
- # ersetzte sunset sunrise
- $x = 0; # notausstieg
- while (
- $condition =~ m/(.*)({ )(sunset\([^}]*\)|sunrise\([^}]*\))( })(.*)/ )
- {
- $x++; # notausstieg
- last if $x > 20; # notausstieg
- if ( defined $2 ) {
- my $part2 = eval $3;
- chop($part2);
- chop($part2);
- chop($part2);
- my ( $testhour, $testmin ) = split( /:/, $part2 );
- if ( $testhour > 23 ) {
- $testhour = $testhour - 24;
- $testhour = '0' . $testhour if $testhour < 10;
- $part2 = $testhour . ':' . $testmin;
- }
- $condition = $part2;
- $condition = $1 . $condition if ( defined $1 );
- $condition = $condition . $5 if ( defined $5 );
- }
- }
- my $conditioncopy = $condition;
- my @argarray;
- $arraycount = '0';
- $pos = '';
- $pos1 = '';
- $part = '';
- $part1 = '';
- $part2 = '';
- $part3 = '';
- $lenght = '';
- ## verursacht fehlerkennung bei angabe von regex [a-zA-Z]
- ARGUMENT: for ( $i = 0 ; $i <= 10 ; $i++ ) {
- $pos = index( $condition, "[", 0 );
- my $x = $pos;
- if ( $x == '-1' ) { last ARGUMENT; }
- $pos1 = index( $condition, "]", 0 );
- $argarray[$arraycount] =
- substr( $condition, $pos, ( $pos1 + 1 - $pos ) );
- $lenght = length($condition);
- $part1 = substr( $condition, 0, $pos );
- $part2 = 'ARG' . $arraycount;
- $part3 =
- substr( $condition, ( $pos1 + 1 ), ( $lenght - ( $pos1 + 1 ) ) );
- $condition = $part1 . $part2 . $part3;
- $arraycount++;
- }
- $condition =~ s/ AND / && /ig;
- $condition =~ s/ OR / || /ig;
- #$condition =~ s/~/ /ig;
- $condition =~ s/ = / == /ig;
- END:
- # teste auf typ
- my $count = 0;
- my $testarg;
- my @newargarray;
- foreach my $args (@argarray) {
- $testarg = $args;
- $testarg =~ s/[0-9]+//gs;
- if ( $testarg eq '[:-:|]' || $testarg eq '[:-:]' ) {
- # timerformatierung erkannt - auswerten über sub
- # my $param = $argarray[$count];
- $newargarray[$count] = MSwitch_Checkcond_time( $args, $name );
- }
- elsif ( $testarg =~ '[.*:.*]' ) {
- # my $param = $argarray[$count];
- # stateformatierung erkannt - auswerten über sub
- $newargarray[$count] = MSwitch_Checkcond_state( $args, $name );
- }
- else {
- $newargarray[$count] = $args;
- }
- $count++;
- }
- $count = 0;
- my $tmp;
- foreach my $args (@newargarray) {
- $tmp = 'ARG' . $count;
- $condition =~ s/$tmp/$args/ig;
- $count++;
- }
- $finalstring =
- "if (" . $condition . "){\$answer = 'true';} else {\$answer = 'false';} ";
- MSwitch_LOG( $name, 6,
- "$name: Checkcondition - finalstring -> " . $finalstring );
- my $ret = eval $finalstring;
- MSwitch_LOG( $name, 6, "$name: Checkcondition - return -> " . $ret );
- if ($@) {
- MSwitch_LOG( $name, 1, "ERROR: $@ " . __LINE__ );
- MSwitch_LOG( $name, 1, "$finalstring " . __LINE__ );
- $hash->{helper}{conditionerror} = $@;
- return 'false';
- }
- my $test = ReadingsVal( $name, 'last_event', 'undef' );
- $hash->{helper}{conditioncheck} = $finalstring;
- return $ret;
- }
- ####################
- ####################
- sub MSwitch_Checkcond_state($$) {
- my ( $condition, $name ) = @_;
- MSwitch_LOG( $name, 6, "----------------------------------------" );
- MSwitch_LOG( $name, 6, "$name: MSwitch_Checkcond_state -> " . $condition );
- MSwitch_LOG( $name, 6, "----------------------------------------" );
- my $x = 0;
- while ( $condition =~ m/(.*?)(\$SELF)(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $condition = $firstpart . $name . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- $condition =~ s/\[//;
- $condition =~ s/\]//;
- my @reading = split( /:/, $condition );
- my $return = "ReadingsVal('$reading[0]', '$reading[1]', '00:00:00')";
- my $test = ReadingsVal( $reading[0], $reading[1], 'undef' );
- MSwitch_LOG( $name, 6, "$name: MSwitch_Checkcond_state OUT -> " . $return );
- return $return;
- }
- ####################
- sub MSwitch_Checkcond_time($$) {
- my ( $condition, $name ) = @_;
- $condition =~ s/\[//;
- $condition =~ s/\]//;
- my $adday = 0;
- my $days = '';
- my $daycondition = '';
- ( $condition, $days ) = split( /\|/, $condition )
- if index( $condition, "|", 0 ) > -1;
- my $hour1 = substr( $condition, 0, 2 );
- my $min1 = substr( $condition, 3, 2 );
- my $hour2 = substr( $condition, 6, 2 );
- my $min2 = substr( $condition, 9, 2 );
- if ( $hour1 eq "24" ) # test auf 24 zeitangabe
- {
- $hour1 = "00";
- }
- if ( $hour2 eq "24" ) {
- $hour2 = "00";
- }
- my $time = localtime;
- $time =~ s/\s+/ /g;
- my ( $day, $month, $date, $n, $time1 ) = split( / /, $time );
- my ( $akthour, $aktmin, $aktsec ) = split( /:/, $n );
- ############ timecondition 1
- my $timecondtest;
- my $timecond1;
- #my $time1;
- my ( $tday, $tmonth, $tdate, $tn ); #my ($tday,$tmonth,$tdate,$tn,$time1);
- if ( ( $akthour < $hour1 && $akthour < $hour2 ) && $hour2 < $hour1 ) # und
- {
- use constant SECONDS_PER_DAY => 60 * 60 * 24;
- $timecondtest = localtime( time - SECONDS_PER_DAY );
- $timecondtest =~ s/\s+/ /g;
- ( $tday, $tmonth, $tdate, $tn, $time1 ) = split( / /, $timecondtest );
- $timecond1 = timelocal( '00', $min1, $hour1, $tdate, $tmonth, $time1 );
- $adday = 1;
- }
- else {
- $timecondtest = localtime;
- $timecondtest =~ s/\s+/ /g;
- ( $tday, $tmonth, $tdate, $tn, $time1 ) = split( / /, $timecondtest );
- $timecond1 = timelocal( '00', $min1, $hour1, $tdate, $tmonth, $time1 );
- }
- ############# timecondition 2
- my $timecond2;
- $timecondtest = localtime;
- if ( $hour2 < $hour1 ) {
- if ( $akthour < $hour1 && $akthour < $hour2 ) {
- $timecondtest = localtime;
- $timecondtest =~ s/\s+/ /g;
- ( $tday, $tmonth, $tdate, $tn, $time1 ) =
- split( / /, $timecondtest );
- $timecond2 =
- timelocal( '00', $min2, $hour2, $tdate, $tmonth, $time1 );
- }
- else {
- use constant SECONDS_PER_DAY => 60 * 60 * 24;
- $timecondtest = localtime( time + SECONDS_PER_DAY );
- $timecondtest =~ s/\s+/ /g;
- my ( $tday, $tmonth, $tdate, $tn, $time1 ) =
- split( / /, $timecondtest );
- $timecond2 =
- timelocal( '00', $min2, $hour2, $tdate, $tmonth, $time1 );
- $adday = 1;
- }
- }
- else {
- $timecondtest = localtime;
- $timecondtest =~ s/\s+/ /g;
- ( $tday, $tmonth, $tdate, $tn, $time1 ) = split( / /, $timecondtest );
- $timecond2 = timelocal( '00', $min2, $hour2, $tdate, $tmonth, $time1 );
- }
- my $timeaktuell =
- timelocal( '00', $aktmin, $akthour, $date, $month, $time1 );
- my $return = "($timecond1 < $timeaktuell && $timeaktuell < $timecond2)";
- if ( $days ne '' ) {
- $daycondition = MSwitch_Checkcond_day( $days, $name, $adday, $day );
- $return = "($return $daycondition)";
- }
- return $return;
- }
- ####################
- sub MSwitch_Checkcond_day($$$$) {
- my ( $days, $name, $adday, $day ) = @_;
- my %daysforcondition = (
- "Mon" => 1,
- "Tue" => 2,
- "Wed" => 3,
- "Thu" => 4,
- "Fri" => 5,
- "Sat" => 6,
- "Sun" => 7
- );
- $day = $daysforcondition{$day};
- my @daycond = split //, $days;
- my $daycond = '';
- foreach my $args (@daycond) {
- if ( $adday == 1 ) { $args++; }
- if ( $args == 8 ) { $args = 1 }
- $daycond = $daycond . "($day == $args) || ";
- }
- chop $daycond;
- chop $daycond;
- chop $daycond;
- chop $daycond;
- $daycond = "&& ($daycond)";
- return $daycond;
- }
- ####################
- sub MSwitch_Createtimer($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- # keine timer vorhenden
- my $condition = ReadingsVal( $Name, '.Trigger_time', '' );
- $condition =~ s/#\[dp\]/:/g;
- my $x = 0;
- while ( $condition =~ m/(.*)(\[)([0-9]?[a-zA-Z]{1}.*)\:(.*)(\])(.*)/ ) {
- $x++; # notausstieg notausstieg
- last if $x > 20; # notausstieg notausstieg
- my $setmagic = ReadingsVal( $3, $4, 0 );
- $condition = $1 . '[' . $setmagic . ']' . $6;
- #MSwitch_LOG( $Name, 0,"create timer: ".$condition);
- }
- my $lenght = length($condition);
- #remove all timers
- MSwitch_Clear_timer($hash);
- if ( $lenght == 0 ) {
- return;
- }
- # trenne timerfile
- my $key = 'on';
- $condition =~ s/$key//ig;
- $key = 'off';
- $condition =~ s/$key//ig;
- $key = 'ly';
- $condition =~ s/$key//ig;
- $x = 0;
- # achtung perl 5.30
- while ( $condition =~ m/(.*)\{(.*)\}(.*)/ ) {
- $x++; # notausstieg
- last if $x > 20; # notausstieg
- if ( defined $2 ) {
- my $part1 = $1;
- my $part3 = $3;
- my $part2 = eval $2 ;
- if ($part2 !~ m/^[0-9]{2}:[0-9]{2}$|^[0-9]{2}:[0-9]{2}:[0-9]{2}$/)
- {
- MSwitch_LOG( $Name, 1, "$Name: ERROR wrong format in set timer. There are no timers running. Format must be HH:MM. Format is: $part2 " );
- return;
- }
- $part2 = substr( $part2, 0, 5 );
- my $test = substr( $part2, 0, 2 ) * 1;
- $part2 = "" if $test > 23;
- $condition = $part1 . $part2 . $part3;
- }
- }
- my @timer = split /~/, $condition;
- $timer[0] = '' if ( !defined $timer[0] );
- $timer[1] = '' if ( !defined $timer[1] );
- $timer[2] = '' if ( !defined $timer[2] );
- $timer[3] = '' if ( !defined $timer[3] );
- # lösche bei notify und toggle
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Notify" ) {
- $timer[0] = '';
- $timer[1] = '';
- }
- if ( AttrVal( $Name, 'MSwitch_Mode', 'Full' ) eq "Toggle" ) {
- $timer[1] = '';
- $timer[2] = '';
- $timer[3] = '';
- }
- my $akttimestamp = TimeNow();
- my ( $aktdate, $akttime ) = split / /, $akttimestamp;
- my ( $aktyear, $aktmonth, $aktmday ) = split /-/, $aktdate;
- $aktmonth = $aktmonth - 1;
- $aktyear = $aktyear - 1900;
- my $jetzt = gettimeofday();
- # aktuelle zeit setzen
- my $time = localtime;
- $time =~ s/\s+/ /g;
- my ( $day, $month, $date, $n, $time1 ) =
- split( / /, $time ); # day enthält aktuellen tag als wochentag
- my $aktday = $day;
- my %daysforcondition = (
- "Mon" => 1,
- "Tue" => 2,
- "Wed" => 3,
- "Thu" => 4,
- "Fri" => 5,
- "Sat" => 6,
- "Sun" => 7
- );
- $day = $daysforcondition{$day}; # enthält aktuellen tag
- ###
- ## für jeden Timerfile ( 0 -4 )
- my $i = 0;
- LOOP2: foreach my $option (@timer) {
- $i++;
- #### inhalt array für eine option on , off ...
- $key = '\]\[';
- $option =~ s/$key/ /ig;
- $key = '\[';
- $option =~ s/$key//ig;
- $key = '\]';
- $option =~ s/$key//ig;
- if ( $option =~
- m/(.*?)([0-9]{2}):([0-9]{2})\*([0-9]{2}:[0-9]{2})-([0-9]{2}:[0-9]{2})\|?([0-9]{0,7})(.*)?/
- )
- {
- my $part1 = '';
- $part1 = $1 . ' ' if defined $1;
- my $part6 = '';
- if ( defined $6 && $part6 ne '' ) { $part6 = '|' . $6 }
- my $part7 = '';
- $part7 = ' ' . $7 if defined $7;
- my $sectoadd = $2 * 3600 + $3 * 60;
- my $t1 = $4;
- my $t2 = $5;
- my $timecondtest = localtime;
- $timecondtest =~ s/\s+/ /g;
- my ( $tday, $tmonth, $tdate, $tn, $time1 ) =
- split( / /, $timecondtest );
- my $timecond1 = timelocal(
- '00',
- substr( $t1, 3, 2 ),
- substr( $t1, 0, 2 ),
- $tdate, $tmonth, $time1
- );
- my $timecond2 = timelocal(
- '00',
- substr( $t2, 3, 2 ),
- substr( $t2, 0, 2 ),
- $tdate, $tmonth, $time1
- );
- my @newarray;
- while ( $timecond1 < $timecond2 ) {
- #my $timestamp = FmtDateTime($timecond1);
- my $timestamp =
- substr( FmtDateTime($timecond1), 11, 5 ) . $part6;
- $timecond1 = $timecond1 + $sectoadd;
- push( @newarray, $timestamp );
- }
- my $newopt = join( ' ', @newarray );
- my $newoption = $part1 . $newopt . $part7;
- $newoption =~ s/ / /g;
- $option = $newoption;
- }
- my @optionarray = split / /, $option;
- # für jede angabe eines files
- LOOP3: foreach my $option1 (@optionarray) {
- if ( $option1 =~
- m/\?(.*)(-)([0-9]{2}:[0-9]{2})(\|[0-9]{0,7})?(.*)?/ )
- {
- my $testrandom = $1 . $2 . $3;
- my $part4 = '';
- $part4 = $4 if defined $4;
- my $opdays = $part4;
- #testrandomsaved erstellen
- my $newoption1 = MSwitch_Createrandom( $hash, $1, $3 );
- $option1 = $newoption1 . $opdays;
- }
- if ( $option1 =~ m/{/i || $option1 =~ m/}/i ) {
- my $newoption1 = MSwitch_ChangeCode( $hash, $option1 );
- $option1 = $newoption1;
- }
- my ( $time, $days ) = split /\|/, $option1;
- $time = '' if ( !defined $time );
- $days = '' if ( !defined $days );
- if ( $days eq '!$we' || $days eq '$we' ) {
- my $we = AnalyzeCommand( 0, '{return $we}' );
- if ( $days eq '$we' && $we == 1 ) { $days = $day; }
- if ( $days eq '!$we' && $we == 0 ) { $days = $day; }
- }
- if ( !defined($days) ) { $days = '' }
- if ( $days eq '' ) { $days = '1234567' }
- if ( index( $days, $day, 0 ) == -1 ) {
- next LOOP3;
- }
- $time = $time . ':00';
- delete( $hash->{helper}{error} );
- my $timecond = timelocal(
- substr( $time, 6, 2 ),
- substr( $time, 3, 2 ),
- substr( $time, 0, 2 ),
- $date, $aktmonth, $aktyear
- );
- my $test = FmtDateTime($timecond);
- my $sectowait = $timecond - $jetzt;
- if ( $timecond > $jetzt ) {
- my $inhalt = $timecond . "-" . $i;
- $hash->{helper}{timer}{$inhalt} = "$inhalt";
- my $msg = $Name . " " . $timecond . " " . $i;
- my $gettime = gettimeofday();
- InternalTimer( $timecond, "MSwitch_Execute_Timer", $msg );
- }
- }
- }
- # berechne zeit bis 23,59 und setze timer auf create timer
- my $newask = timelocal( '00', '59', '23', $date, $aktmonth, $aktyear );
- $newask = $newask + 70;
- my $newassktest = FmtDateTime($newask);
- my $msg = $Name . " " . $newask . " " . 5;
- my $inhalt = $newask . "-" . 5;
- $hash->{helper}{timer}{$newask} = "$inhalt";
- InternalTimer( $newask, "MSwitch_Execute_Timer", $msg );
- }
- ##############################
- sub MSwitch_Createrandom($$$) {
- my ( $hash, $t1, $t2 ) = @_;
- my $Name = $hash->{NAME};
- my $testrandom = $t1 . "-" . $t2;
- my $testt1 = $t1;
- my $testt2 = $t2;
- $testt1 =~ s/\://g;
- $testt2 =~ s/\://g;
- my $timecondtest = localtime;
- $timecondtest =~ s/\s+/ /g;
- my ( $tday, $tmonth, $tdate, $tn, $time1 ) = split( / /, $timecondtest );
- my $timecond1 = timelocal(
- '00',
- substr( $t1, 3, 2 ),
- substr( $t1, 0, 2 ),
- $tdate, $tmonth, $time1
- );
- my $timecond2 = timelocal(
- '00',
- substr( $t2, 3, 2 ),
- substr( $t2, 0, 2 ),
- $tdate, $tmonth, $time1
- );
- if ( $testt2 < $testt1 ) { $timecond2 = $timecond2 + 86400 }
- my $newtime = int( rand( $timecond2 - $timecond1 ) ) + $timecond1;
- my $timestamp = FmtDateTime($newtime);
- my $timestamp1 = substr( $timestamp, 11, 5 );
- return $timestamp1;
- }
- ###########################
- sub MSwitch_Execute_Timer($) {
- my ($input) = @_;
- my ( $Name, $timecond, $param ) = split( / /, $input );
- my $hash = $defs{$Name};
- return "" if ( IsDisabled($Name) );
- $hash->{eventsave} = 'unsaved';
- if ( ReadingsVal( $Name, '.V_Check', $vupdate ) ne $vupdate ) {
- my $ver = ReadingsVal( $Name, '.V_Check', '' );
- Log3( $Name, 1,
- $Name
- . ' Versionskonflikt, aktion abgebrochen ! erwartet:'
- . $vupdate
- . ' vorhanden:'
- . $ver );
- return;
- }
- if ( AttrVal( $Name, 'MSwitch_RandomNumber', '' ) ne '' ) {
- MSwitch_Createnumber1($hash);
- }
- if ( $param eq '5' ) {
- MSwitch_Createtimer($hash);
- return;
- }
- if ( AttrVal( $Name, 'MSwitch_Condition_Time', "0" ) eq '1' ) {
- my $triggercondition = ReadingsVal( $Name, '.Trigger_condition', '' );
- # $triggercondition =~ s/\./:/g;
- $triggercondition =~ s/#\[dp\]/:/g;
- $triggercondition =~ s/#\[pt\]/./g;
- $triggercondition =~ s/#\[ti\]/~/g;
- $triggercondition =~ s/#\[sp\]/ /g;
- if ( $triggercondition ne '' ) {
- my $ret = MSwitch_checkcondition( $triggercondition, $Name, '' );
- if ( $ret eq 'false' ) {
- return;
- }
- }
- }
- my $extime = POSIX::strftime( "%H:%M", localtime );
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, "EVENT",
- $Name . ":execute_timer_P" . $param . ":" . $extime );
- readingsBulkUpdate( $hash, "EVTFULL",
- $Name . ":execute_timer_P" . $param . ":" . $extime );
- readingsBulkUpdate( $hash, "EVTPART1", $Name );
- readingsBulkUpdate( $hash, "EVTPART2", "execute_timer_P" . $param );
- readingsBulkUpdate( $hash, "EVTPART3", $extime );
- readingsEndUpdate( $hash, 1 );
- if ( $param eq '1' ) {
- my $cs = "set $Name on";
- Log3( $Name, 3,
- "$Name MSwitch_Execute_Timer: Befehlsausfuehrung -> $cs"
- . __LINE__ );
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $Name, 1,
- "$Name MSwitch_Execute_Timer: Fehler bei Befehlsausfuehrung ERROR $Name: $errors "
- . __LINE__ );
- }
- return;
- }
- if ( $param eq '2' ) {
- my $cs = "set $Name off";
- Log3( $Name, 3,
- "$Name MSwitch_Execute_Timer: Befehlsausfuehrung -> $cs"
- . __LINE__ );
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $Name, 1,
- "$Name MSwitch_Execute_Timer: Fehler bei Befehlsausfuehrung ERROR $Name: $errors "
- . __LINE__ );
- }
- return;
- }
- if ( $param eq '3' ) {
- MSwitch_Exec_Notif( $hash, 'on', 'nocheck', '', 0 );
- return;
- }
- if ( $param eq '4' ) {
- MSwitch_Exec_Notif( $hash, 'off', 'nocheck', '', 0 );
- return;
- }
- return;
- }
- ####################
- sub MSwitch_ChangeCode($$) {
- my ( $hash, $option ) = @_;
- my $Name = $hash->{NAME};
- my $x = 0; # exit secure
- #achtung perl5.30
- while ( $option =~ m/(.*)\{(sunset|sunrise)(.*)\}(.*)/ )
- #while ( $option =~ m/(.*){(sunset|sunrise)(.*)}(.*)/ )
- {
- $x++; # exit secure
- last if $x > 20; # exit secure
- if ( defined $2 ) {
- my $part2 = eval $2 . $3;
- chop($part2);
- chop($part2);
- chop($part2);
- $option = $part2;
- $option = $1 . $option if ( defined $1 );
- $option = $option . $4 if ( defined $4 );
- }
- }
- return $option;
- }
- ####################
- sub MSwitch_Add_Device($$) {
- my ( $hash, $device ) = @_;
- my $Name = $hash->{NAME};
- my @olddevices = split( /,/, ReadingsVal( $Name, '.Device_Affected', '' ) );
- my $count = 1;
- LOOP7: foreach (@olddevices) {
- my ( $devicename, $devicecmd ) = split( /-AbsCmd/, $_ );
- if ( $device eq $devicename ) { $count++; }
- }
- my $newdevices .= ',' . $device . '-AbsCmd' . $count;
- my $newset = ReadingsVal( $Name, '.Device_Affected', '' ) . $newdevices;
- $newdevices = join( ',', @olddevices ) . ',' . $newdevices;
- my @sortdevices = split( /,/, $newdevices );
- @sortdevices = sort @sortdevices;
- $newdevices = join( ',', @sortdevices );
- $newdevices = substr( $newdevices, 1 );
- readingsSingleUpdate( $hash, ".Device_Affected", $newdevices, 1 );
- return;
- }
- ###################################
- sub MSwitch_Del_Device($$) {
- my ( $hash, $device ) = @_;
- my $Name = $hash->{NAME};
- my @olddevices = split( /,/, ReadingsVal( $Name, '.Device_Affected', '' ) );
- my @olddevicesset =
- split( /#\[ND\]/, ReadingsVal( $Name, '.Device_Affected_Details', '' ) );
- my @newdevice;
- my @newdevicesset;
- my $count = 0;
- LOOP8: foreach (@olddevices) {
- if ( $device eq $_ ) {
- $count++;
- next LOOP8;
- }
- push( @newdevice, $olddevices[$count] );
- push( @newdevicesset, $olddevicesset[$count] );
- $count++;
- }
- my ( $devicemaster, $devicedeleted ) = split( /-AbsCmd/, $device );
- $count = 1;
- my @newdevice1;
- LOOP9: foreach (@newdevice) {
- my ( $devicename, $devicecmd ) = split( /-AbsCmd/, $_ );
- if ( $devicemaster eq $devicename ) {
- my $newname = $devicename . '-AbsCmd' . $count;
- $count++;
- push( @newdevice1, $newname );
- next LOOP9;
- }
- push( @newdevice1, $_ );
- }
- $count = 1;
- my @newdevicesset1;
- LOOP10: foreach (@newdevicesset) {
- my ( $name, @comands ) = split( /#\[NF\]/, $_ );
- my ( $devicename, $devicecmd ) = split( /-AbsCmd/, $name );
- if ( $devicemaster eq $devicename ) {
- my $newname =
- $devicename
- . '-AbsCmd'
- . $count . '#[NF]'
- . join( '#[NF]', @comands );
- push( @newdevicesset1, $newname );
- $count++;
- next LOOP10;
- }
- push( @newdevicesset1, $_ );
- }
- my $newaffected = join( ',', @newdevice1 );
- if ( $newaffected eq '' ) { $newaffected = 'no_device' }
- my $newaffecteddet = join( '#[ND]', @newdevicesset1 );
- #return;
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, ".Device_Affected", $newaffected );
- readingsBulkUpdate( $hash, ".Device_Affected_Details", $newaffecteddet );
- readingsEndUpdate( $hash, 0 );
- my $devices = MSwitch_makeAffected($hash);
- my $devhash = $hash->{DEF};
- my @dev = split( /#/, $devhash );
- $hash->{DEF} = $dev[0] . ' # ' . $devices;
- }
- ###################################
- sub MSwitch_Debug($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $debug1 = ReadingsVal( $Name, '.Device_Affected', 0 );
- my $debug2 = ReadingsVal( $Name, '.Device_Affected_Details', 0 );
- my $debug3 = ReadingsVal( $Name, '.Device_Events', 0 );
- $debug2 =~ s/:/ /ig;
- $debug3 =~ s/,/, /ig;
- readingsBeginUpdate($hash);
- readingsBulkUpdate( $hash, "Device_Affected", $debug1 );
- readingsBulkUpdate( $hash, "Device_Affected_Details", $debug2 );
- readingsBulkUpdate( $hash, "Device_Events", $debug3 );
- readingsEndUpdate( $hash, 0 );
- }
- ###################################
- sub MSwitch_Delete_Delay($$) {
- my ( $hash, $device ) = @_;
- my $Name = $hash->{NAME};
- my $timehash = $hash->{helper}{delays};
- MSwitch_LOG( $Name, 5, "$Name: Delays geloescht ! " );
- if ( $device eq 'all' ) {
- foreach my $a ( keys %{$timehash} ) {
- my $inhalt = $hash->{helper}{delays}{$a};
- RemoveInternalTimer($a);
- RemoveInternalTimer($inhalt);
- delete( $hash->{helper}{delays}{$a} );
- }
- }
- else {
- foreach my $a ( keys %{$timehash} ) {
- my $pos = index( $a, "$device", 0 );
- if ( $pos != -1 ) {
- RemoveInternalTimer($a);
- my $inhalt = $hash->{helper}{delays}{$a};
- RemoveInternalTimer($a);
- RemoveInternalTimer($inhalt);
- delete( $hash->{helper}{delays}{$a} );
- }
- }
- }
- }
- ###################################
- sub MSwitch_Clear_timer($) {
- my ( $hash, $device ) = @_;
- my $name = $hash->{NAME};
- my $timehash = $hash->{helper}{timer};
- foreach my $a ( keys %{$timehash} ) {
- my $inhalt = $hash->{helper}{timer}{$a};
- RemoveInternalTimer($inhalt);
- $inhalt = $hash->{helper}{timer}{$a};
- $inhalt =~ s/-/ /g;
- $inhalt = $name . ' ' . $inhalt;
- RemoveInternalTimer($inhalt);
- }
- delete( $hash->{helper}{timer} );
- }
- ##################################
- # Eventsimulation
- sub MSwitch_Check_Event($$) {
- my ( $hash, $eventin ) = @_;
- my $Name = $hash->{NAME};
- $eventin =~ s/~/ /g;
- my $dev_hash = "";
- if ( ReadingsVal( $Name, 'Trigger_device', '' ) eq "all_events" ) {
- my @eventin = split( /:/, $eventin );
- $dev_hash = $defs{ $eventin[0] };
- $hash->{helper}{testevent_device} = $eventin[0];
- $hash->{helper}{testevent_event} = $eventin[1] . ":" . $eventin[2];
- $hash->{helper}{testevent_event} = $eventin[1] . ":" . $eventin[2];
- }
- else {
- my @eventin = split( /:/, $eventin );
- $dev_hash = $defs{ ReadingsVal( $Name, 'Trigger_device', '' ) };
- $hash->{helper}{testevent_device} =
- ReadingsVal( $Name, 'Trigger_device', '' );
- $hash->{helper}{testevent_event} = $eventin[0] . ":" . $eventin[1];
- }
- my $we = AnalyzeCommand( 0, '{return $we}' );
- MSwitch_Notify( $hash, $dev_hash );
- delete( $hash->{helper}{testevent_device} );
- delete( $hash->{helper}{testevent_event} );
- delete( $hash->{helper}{testevent_event1} );
- return;
- }
- #########################################
- sub MSwitch_makeAffected($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $devices = '';
- my %saveaffected;
- my @affname;
- my $affected = ReadingsVal( $Name, '.Device_Affected', 'nodevices' );
- my @affected = split( /,/, $affected );
- LOOP30: foreach (@affected) {
- @affname = split( /-/, $_ );
- $saveaffected{ $affname[0] } = 'on';
- }
- foreach my $a ( keys %saveaffected ) {
- $devices = $devices . $a . ' ';
- }
- chop($devices);
- return $devices;
- }
- #############################
- sub MSwitch_checktrigger(@) {
- my ( $own_hash, $ownName, $eventstellen, $triggerfield, $device, $zweig,
- $eventcopy, @eventsplit )
- = @_;
- my $triggeron = ReadingsVal( $ownName, '.Trigger_on', '' );
- my $triggeroff = ReadingsVal( $ownName, '.Trigger_off', '' );
- my $triggercmdon = ReadingsVal( $ownName, '.Trigger_cmd_on', '' );
- my $triggercmdoff = ReadingsVal( $ownName, '.Trigger_cmd_off', '' );
- my $answer = "";
- #$triggerfield =~ s/\(//g;
- #$triggerfield =~ s/\)//g;
- unshift( @eventsplit, $device )
- if ReadingsVal( $ownName, 'Trigger_device', '' ) eq "all_events";
- if ( ReadingsVal( $ownName, 'Trigger_device', '' ) eq "all_events" ) {
- $eventcopy = $device . ":" . $eventcopy;
- if ( $triggerfield eq "*" ) {
- $triggerfield = "*:*:*";
- }
- }
- if ( $triggerfield eq "*"
- && ReadingsVal( $ownName, 'Trigger_device', '' ) ne "all_events" )
- {
- $triggerfield = "*:*";
- }
- $triggerfield =~ s/\*/.*/g;
- # erkennunhg der formartierung bis v1.66 ( <1.67)
- my $x = 0;
- while ( $triggerfield =~ m/(.*)(\()(.*)(\/)(.*)(\))(.*)/ ) {
- $x++; # exit secure
- last if $x > 20; # exit secure
- $triggerfield = $1 . $3 . "|" . $5 . $7;
- }
- ################
- if ( $eventcopy =~ m/^$triggerfield/ ) {
- $answer = "wahr";
- }
- return 'on'
- if $zweig eq 'on'
- && $answer eq 'wahr'
- && $eventcopy ne $triggercmdoff
- && $eventcopy ne $triggercmdon
- && $eventcopy ne $triggeroff;
- return 'off'
- if $zweig eq 'off'
- && $answer eq 'wahr'
- && $eventcopy ne $triggercmdoff
- && $eventcopy ne $triggercmdon
- && $eventcopy ne $triggeron;
- return 'offonly' if $zweig eq 'offonly' && $answer eq 'wahr';
- return 'ononly' if $zweig eq 'ononly' && $answer eq 'wahr';
- return 'undef';
- }
- ###############################
- sub MSwitch_VUpdate($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- readingsSingleUpdate( $hash, ".V_Check", $vupdate, 0 );
- my $devs = ReadingsVal( $Name, '.Device_Affected_Details', '' );
- # encode from old format
- $devs =~ s/,/#[NF]/g;
- $devs =~ s/\|/#[ND]/g;
- $devs =~ s/~/ /g;
- $devs =~ s/\[cnl\]/\n/g;
- $devs =~ s/\[se\]/;/g;
- $devs =~ s/#\[ko\]/,/g;
- $devs =~ s/#\[sp\]/ /g;
- # decode to new format
- $devs =~ s/#\[wa\]/|/g;
- $devs =~ s/\n/#[nl]/g;
- $devs =~ s/;/#[se]/g;
- $devs =~ s/\:/#[dp]/g;
- $devs =~ s/\t/ /g;
- $devs =~ s/ /#[sp]/g;
- $devs =~ s/\\/#[bs]/g;
- $devs =~ s/,/#[ko]/g;
- $devs =~ s/^#\[/#[eo]/g;
- $devs =~ s/^#\]/#[ec]/g;
- $devs =~ s/\|/#[wa]/g;
- # change timerkey to new format
- my $x = 0;
- while ( $devs =~ m/(.*#\[NF\])([0-9]{2})([0-9]{2})([0-9]{2})(#\[NF\].*)/ ) {
- $x++; # exit
- last if $x > 20; # exit
- $devs = $1 . $2 . "#[dp]" . $3 . "#[dp]" . $4 . $5;
- }
- readingsSingleUpdate( $hash, ".Device_Affected_Details", $devs, 0 );
- return;
- }
- ################################
- sub MSwitch_backup($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my @areadings =
- qw(.Device_Affected .Device_Affected_Details .Device_Events .First_init .Trigger_Whitelist .Trigger_cmd_off .Trigger_cmd_on .Trigger_condition .Trigger_off .Trigger_on .Trigger_time .V_Check Exec_cmd Trigger_device Trigger_log last_event state .sysconf Sys_Extension .sortby)
- ; #alle readings
- my %keys;
- open( BACKUPDATEI, ">MSwitch_backup_$vupdate.cfg" )
- ; # Datei zum Schreiben öffnen
- print BACKUPDATEI "# Mswitch Devices\n"; #
- foreach my $testdevice ( keys %{ $modules{MSwitch}{defptr} } ) #
- {
- print BACKUPDATEI "$testdevice\n";
- }
- print BACKUPDATEI "# Mswitch Devices END\n"; #
- print BACKUPDATEI "\n"; # HTML-Datei schreiben
- foreach my $testdevice ( keys %{ $modules{MSwitch}{defptr} } ) #
- {
- print BACKUPDATEI "#N -> $testdevice\n"; #
- foreach my $key (@areadings) {
- my $tmp = ReadingsVal( $testdevice, $key, 'undef' );
- print BACKUPDATEI "#S $key -> $tmp\n";
- }
- my %keys;
- foreach my $attrdevice ( keys %{ $attr{$testdevice} } ) #geht
- {
- print BACKUPDATEI "#A $attrdevice -> "
- . AttrVal( $testdevice, $attrdevice, '' ) . "\n";
- }
- print BACKUPDATEI "#E -> $testdevice\n";
- print BACKUPDATEI "\n";
- }
- close(BACKUPDATEI);
- }
- ################################
- sub MSwitch_backup_this($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $Zeilen = ("");
- my $Zeilen1 = "";
- open( BACKUPDATEI, "<MSwitch_backup_$vupdate.cfg" )
- || return "no Backupfile found!\n";
- while (<BACKUPDATEI>) {
- $Zeilen = $Zeilen . $_;
- }
- close(BACKUPDATEI);
- $Zeilen =~ s/\n/[NL]/g;
- if ( $Zeilen !~ m/#N -> $Name\[NL\](.*)#E -> $Name\[NL\]/ ) {
- return "no Backupfile found\n";
- }
- my @found = split( /\[NL\]/, $1 );
- foreach (@found) {
- if ( $_ =~ m/#S (.*) -> (.*)/ ) # setreading
- {
- # Log3( $Name, 0, "s1 $1" );
- # Log3( $Name, 0, "s2 $2" );
- if ( $2 eq 'undef' || $2 eq '' || $2 eq ' ' ) {
- }
- else {
- $Zeilen1 = $2;
- readingsSingleUpdate( $hash, "$1", $Zeilen1, 0 );
- }
- }
- if ( $_ =~ m/#A (.*) -> (.*)/ ) # setattr
- {
- my $cs = "attr $Name $1 $2";
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $Name, 1, "ERROR $cs" );
- }
- }
- }
- MSwitch_LoadHelper($hash);
- return "MSwitch $Name restored.\nPlease refresh device.";
- }
- # ################################
- sub MSwitch_Getsupport($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $out = '';
- $out .= "Modulversion: $version\\n";
- $out .= "Datenstruktur: $vupdate\\n";
- $out .= "\\n----- Devicename -----\\n";
- $out .= "$Name\\n";
- $out .= "\\n----- Attribute -----\\n";
- my %keys;
- foreach my $attrdevice ( keys %{ $attr{$Name} } ) #geht
- {
- my $tmp = AttrVal( $Name, $attrdevice, '' );
- $tmp =~ s/</\\</g;
- $tmp =~ s/>/\\>/g;
- $tmp =~ s/'/\\'/g;
- $out .= "Attribut $attrdevice: " . $tmp . "\\n";
- }
- $out .= "\\n----- Trigger -----\\n";
- $out .= "Trigger device: ";
- my $tmp = ReadingsVal( $Name, 'Trigger_device', 'undef' );
- $out .= "$tmp\\n";
- $out .= "Trigger time: ";
- $tmp = ReadingsVal( $Name, '.Trigger_time', 'undef' );
- $tmp =~ s/~/ /g;
- $out .= "$tmp\\n";
- $out .= "Trigger condition: ";
- $tmp = ReadingsVal( $Name, '.Trigger_condition', 'undef' );
- $out .= "$tmp\\n";
- $out .= "Trigger Device Global Whitelist: ";
- $tmp = ReadingsVal( $Name, '.Trigger_Whitelist', 'undef' );
- $out .= "$tmp\\n";
- $out .= "\\n----- Trigger Details -----\\n";
- $out .= "Trigger cmd1: ";
- $tmp = ReadingsVal( $Name, '.Trigger_on', 'undef' );
- $out .= "$tmp\\n";
- $out .= "Trigger cmd2: ";
- $tmp = ReadingsVal( $Name, '.Trigger_off', 'undef' );
- $out .= "$tmp\\n";
- $out .= "Trigger cmd3: ";
- $tmp = ReadingsVal( $Name, '.Trigger_cmd_on', 'undef' );
- $out .= "$tmp\\n";
- $out .= "Trigger cmd4: ";
- $tmp = ReadingsVal( $Name, '.Trigger_cmd_off', 'undef' );
- $out .= "$tmp\\n";
- my %savedetails = MSwitch_makeCmdHash($hash);
- $out .= "\\n----- Device Actions -----\\n";
- my @affecteddevices = split( /#\[ND\]/,
- ReadingsVal( $Name, '.Device_Affected_Details', 'no_device' ) );
- foreach (@affecteddevices) {
- my @devicesplit = split( /#\[NF\]/, $_ );
- $devicesplit[4] =~ s/'/\\'/g;
- $devicesplit[5] =~ s/'/\\'/g;
- $out .= "\\nDevice: " . $devicesplit[0] . "\\n";
- $out .= "cmd1: " . $devicesplit[1] . " " . $devicesplit[3] . "\\n";
- $out .= "cmd2: " . $devicesplit[2] . " " . $devicesplit[4] . "\\n";
- $out .= "cmd1 condition: " . $devicesplit[9] . "\\n";
- $out .= "cmd2 condition: " . $devicesplit[10] . "\\n";
- $out .= "cmd1 delay: " . $devicesplit[7] . "\\n";
- $out .= "cmd2 delay: " . $devicesplit[8] . "\\n";
- $out .= "repeats: " . $devicesplit[11] . "\\n";
- $out .= "repeats delay: " . $devicesplit[12] . "\\n";
- $out .= "priority: " . $devicesplit[13] . "\\n";
- $out .= "id: " . $devicesplit[14] . "\\n";
- $out .= "comment: " . $devicesplit[15] . "\\n";
- $out .= "cmd1 exit: " . $devicesplit[16] . "\\n";
- $out .= "cmd2 exit: " . $devicesplit[17] . "\\n";
- }
- $out =~ s/#\[dp\]/:/g;
- $out =~ s/#\[pt\]/./g;
- $out =~ s/#\[ti\]/~/g;
- $out =~ s/#\[sp\]/ /g;
- $out =~ s/#\[nl\]/\\n/g;
- $out =~ s/#\[se\]/;/g;
- $out =~ s/#\[dp\]/:/g;
- $out =~ s/\(DAYS\)/|/g;
- $out =~ s/#\[ko\]/,/g; #neu
- $out =~ s/#\[bs\]/\\/g; #neu
- asyncOutput( $hash->{CL},
- "<html><center>Supportanfragen bitte im Forum stellen:<a href=\"https://forum.fhem.de/index.php/topic,86199.0.html\">Fhem-Forum</a><br>Bei Devicespezifischen Fragen bitte untenstehene Datei anhängen, das erleichtert Anfragen erheblich.<br> <br><textarea name=\"edit1\" id=\"edit1\" rows=\""
- . "40\" cols=\"180\" STYLE=\"font-family:Arial;font-size:9pt;\">"
- . $out
- . "</textarea><br></html>" );
- return;
- }
- ##################
- sub MSwitch_Getconfig($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my @areadings =
- qw(.Device_Affected .Device_Affected_Details .Device_Events .First_init .Trigger_Whitelist .Trigger_cmd_off .Trigger_cmd_on .Trigger_condition .Trigger_off .Trigger_on .Trigger_time .V_Check Trigger_device Trigger_log last_event .sysconf state Sys_Extension .sortby);
- my $count = 0;
- my $out = "#V $version\\n";
- $out .= "#VS $vupdate\\n";
- my $testdevice = $Name;
- foreach my $key (@areadings) {
- my $tmp = ReadingsVal( $testdevice, $key, 'undef' );
- if ( $key eq ".Device_Affected_Details" ) {
- $tmp =~ s/#\[nl\]/;;/g;
- $tmp =~ s/#\[sp\]/ /g;
- $tmp =~ s/#\[nl\]/\\n/g;
- $tmp =~ s/#\[se\]/;/g;
- $tmp =~ s/#\[dp\]/:/g;
- $tmp =~ s/\(DAYS\)/|/g;
- $tmp =~ s/#\[ko\]/,/g; #neu
- $tmp =~ s/#\[wa\]/|/g;
- $tmp =~ s/#\[st\]/\\'/g;
- $tmp =~ s/'/\\'/g;
- $tmp =~ s/#\[bs\]/\\\\/g;
- }
- if ( $key eq ".sysconf" ) {
- }
- if ( $key eq ".Device_Events" ) {
- $tmp =~ s/#\[tr\]/ /g;
- }
- $out .= "#S $key -> $tmp\\n";
- $count++;
- }
- # my %keys;
- foreach my $attrdevice ( keys %{ $attr{$testdevice} } ) #geht
- {
- my $tmp = AttrVal( $testdevice, $attrdevice, '' );
- $tmp =~ s/</\\</g;
- $tmp =~ s/>/\\>/g;
- $tmp =~ s/'/\\'/g;
- # $out .= "#A $attrdevice -> ". AttrVal( $testdevice, $attrdevice, '' ) . "\\n";
- $out .= "#A $attrdevice -> " . $tmp . "\\n";
- $count++;
- }
- $count++;
- $count++;
- my $client_hash = $hash->{CL};
- Log3( $Name, 0, "MSWITCH-CONFIG: " . $out );
- asyncOutput( $hash->{CL},
- "<html>Änderungen sollten hier nur von erfahrenen Usern durchgeführt werden.<textarea name=\"edit1\" id=\"edit1\" rows=\""
- . $count
- . "\" cols=\"160\" STYLE=\"font-family:Arial;font-size:9pt;\">"
- . $out
- . "</textarea><br><input name\"edit\" type=\"button\" value=\"save changes\" onclick=\" javascript: saveconfig(document.querySelector(\\\'#edit1\\\').value) \"></html>"
- );
- return;
- }
- #######################################################
- sub MSwitch_Sysextension($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $count = 30;
- my $out = ReadingsVal( $Name, '.sysconf', '' );
- $out =~ s/#\[sp\]/ /g;
- $out =~ s/#\[nl\]/\\n/g;
- $out =~ s/#\[se\]/;/g;
- $out =~ s/#\[dp\]/:/g;
- $out =~ s/#\[st\]/\\'/g;
- $out =~ s/#\[dst\]/\"/g;
- $out =~ s/#\[tab\]/ /g;
- $out =~ s/#\[ko\]/,/g;
- $out =~ s/#\[wa\]/|/g;
- $out =~ s/#\[bs\]/\\\\/g;
- my $client_hash = $hash->{CL};
- asyncOutput( $hash->{CL},
- "<html><center>Achtung! Hier angegebener Code greift direkt in das Programm 98_MSwitch ein und wird unmittelbar zu beginn der Routine X_Set ausgeführt<br><textarea name=\"sys\" id=\"sys\" rows=\""
- . $count
- . "\" cols=\"160\" STYLE=\"font-family:Arial;font-size:9pt;\">"
- . $out
- . "</textarea><br><input type=\"button\" value=\"save changes\" onclick=\" javascript: savesys(document.querySelector(\\\'#sys\\\').value) \"></html>"
- );
- return;
- }
- ################################
- sub MSwitch_backup_all($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $answer = '';
- my $Zeilen = ("");
- open( BACKUPDATEI, "<MSwitch_backup_$vupdate.cfg" )
- || return "$Name|no Backupfile MSwitch_backup_$vupdate.cfg found\n";
- while (<BACKUPDATEI>) {
- $Zeilen = $Zeilen . $_;
- }
- close(BACKUPDATEI);
- foreach my $testdevice ( keys %{ $modules{MSwitch}{defptr} } ) #
- {
- Log3( $testdevice, 0, "MSWITCH-RESTORE: " . $testdevice );
- my $devhash = $defs{$testdevice};
- $Zeilen =~ s/\n/[NL]/g;
- if ( $Zeilen !~ m/#N -> $testdevice\[NL\](.*)#E -> $testdevice\[NL\]/ )
- {
- $answer = $answer . "no Backupfile found for $testdevice\n";
- }
- my @found = split( /\[NL\]/, $1 );
- foreach (@found) {
- if ( $_ =~ m/#S (.*) -> (.*)/ ) # setreading
- {
- if ( $2 eq 'undef' || $2 eq '' || $2 eq ' ' ) {
- }
- else {
- readingsSingleUpdate( $devhash, "$1", $2, 0 );
- }
- }
- if ( $_ =~ m/#A (.*) -> (.*)/ ) # setattr
- {
- my $cs = "attr $testdevice $1 $2";
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $testdevice, 1, "ERROR $cs" );
- }
- }
- }
- my $cs = "attr $testdevice verbose 0";
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- Log3( $testdevice, 1, "ERROR $cs" );
- }
- MSwitch_LoadHelper($devhash);
- Log3( $testdevice, 0, "MSWITCH-RESTORE ready -> " . $testdevice );
- $answer = $answer . "MSwitch $testdevice restored.\n";
- }
- return $answer;
- }
- ################################################
- sub MSwitch_savesys($$) {
- my ( $hash, $cont ) = @_;
- my $name = $hash->{NAME};
- $cont = urlDecode($cont);
- $cont =~ s/\n/#[nl]/g;
- $cont =~ s/\t/ /g;
- $cont =~ s/ /#[sp]/g;
- $cont =~ s/\\/#[bs]/g;
- $cont =~ s/,/#[ko]/g;
- $cont =~ s/^#\[/#[eo]/g;
- $cont =~ s/^#\]/#[ec]/g;
- $cont =~ s/\|/#[wa]/g;
- if ( !defined $cont ) { $cont = ""; }
- if ( $cont ne '' ) {
- readingsSingleUpdate( $hash, ".sysconf", $cont, 0 );
- }
- else {
- fhem("deletereading $name .sysconf");
- }
- return;
- }
- ################################################
- sub MSwitch_saveconf($$) {
- my ( $hash, $cont ) = @_;
- my $name = $hash->{NAME};
- my $contcopy = $cont;
- $cont =~ s/#c\[sp\]/ /g;
- $cont =~ s/#c\[se\]/;/g;
- $cont =~ s/#c\[dp\]/:/g;
- my @changes;
- my $info = "";
- my @found = split( /#\[EOL\]/, $cont );
- foreach (@found) {
- if ( $_ =~ m/#Q (.*)/ ) # setattr
- {
- push( @changes, $1 );
- }
- if ( $_ =~ m/#I (.*)/ ) # setattr
- {
- $info = $1;
- }
- if ( $_ =~ m/#VS (.*)/ ) # setattr
- {
- if ( $1 ne $vupdate ) {
- readingsSingleUpdate( $hash, ".wrong_version", $1, 0 );
- return;
- }
- }
- if ( $_ =~ m/#S (.*) -> (.*)/ ) # setreading
- {
- if ( $2 eq 'undef' || $2 eq '' || $2 eq ' ' ) {
- }
- else {
- my $newstring = $2;
- if ( $1 eq ".Device_Affected_Details" ) {
- $newstring =~ s/;/#[se]/g;
- $newstring =~ s/:/#[dp]/g;
- $newstring =~ s/\t/ /g;
- $newstring =~ s/ /#[sp]/g;
- $newstring =~ s/\\/#[bs]/g;
- $newstring =~ s/,/#[ko]/g;
- $newstring =~ s/^#\[/#[eo]/g;
- $newstring =~ s/^#\]/#[ec]/g;
- $newstring =~ s/\|/#[wa]/g;
- $newstring =~ s/#\[se\]#\[se\]#\[se\]/#[se]#[nl]/g;
- $newstring =~ s/#\[se\]#\[se\]/#[nl]/g;
- }
- if ( $1 eq ".sysconf" ) {
- }
- if ( $1 eq ".Device_Events" ) {
- $newstring =~ s/ /#[tr]/g;
- }
- readingsSingleUpdate( $hash, "$1", $newstring, 0 );
- }
- }
- if ( $_ =~ m/#A (.*) -> (.*)/ ) # setattr
- {
- $attr{$name}{$1} = $2;
- }
- }
- MSwitch_set_dev($hash);
- if ( @changes > 0 ) {
- my $save = join( '|', @changes );
- readingsSingleUpdate( $hash, ".change", $save, 0 );
- }
- if ( $info ne "" ) {
- readingsSingleUpdate( $hash, ".change_info", $info, 0 );
- }
- return;
- }
- ################################################
- sub MSwitch_backup_done($) {
- my ($string) = @_;
- return unless ( defined($string) );
- my @a = split( "\\|", $string );
- my $Name = $a[0];
- my $answer = $a[1];
- my $hash = $defs{$Name};
- delete( $hash->{helper}{RUNNING_PID} );
- my $client_hash = $hash->{helper}{RESTORE_ANSWER};
- $answer =~ s/\[nl\]/\n/g;
- foreach my $testdevice ( keys %{ $modules{MSwitch}{defptr} } ) #
- {
- my $devhash = $defs{$testdevice};
- MSwitch_Createtimer($devhash);
- }
- asyncOutput( $client_hash, $answer );
- return;
- }
- ###########################################
- sub MSwitch_Execute_randomtimer($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $param = AttrVal( $Name, 'MSwitch_RandomTime', '0' );
- my $min = substr( $param, 0, 2 ) * 3600;
- $min = $min + substr( $param, 3, 2 ) * 60;
- $min = $min + substr( $param, 6, 2 );
- my $max = substr( $param, 9, 2 ) * 3600;
- $max = $max + substr( $param, 12, 2 ) * 60;
- $max = $max + substr( $param, 15, 2 );
- my $sekmax = $max - $min;
- my $ret = $min + int( rand $sekmax );
- return $ret;
- }
- ############################################
- sub MSwitch_replace_delay($$) {
- my ( $hash, $timerkey ) = @_;
- my $name = $hash->{NAME};
- my $time = time;
- my $ltime = TimeNow();
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- MSwitch_LOG( $name, 5, "$name: MSwitch_replace_delay-> $timerkey" );
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- my ( $aktdate, $akttime ) = split / /, $ltime;
- my $hh = ( substr( $timerkey, 0, 2 ) );
- my $mm = ( substr( $timerkey, 2, 2 ) );
- my $ss = ( substr( $timerkey, 4, 2 ) );
- my $referenz = time_str2num("$aktdate $hh:$mm:$ss");
- if ( $referenz < $time ) {
- $referenz = $referenz + 86400;
- }
- if ( $referenz >= $time ) {
- }
- $referenz = $referenz - $time;
- my $timestampGMT = FmtDateTimeRFC1123($referenz);
- return $referenz;
- }
- ############################################################
- sub MSwitch_repeat($) {
- my ( $msg, $name ) = @_;
- my $incomming = $_[0];
- my @msgarray = split( /\|/, $incomming );
- $name = $msgarray[1];
- my $time = $msgarray[2];
- my $cs = $msgarray[0];
- my $hash = $defs{$name};
- $cs =~ s/\n//g;
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- MSwitch_LOG( $name, 5, "$name: Repeat -> " . $cs );
- MSwitch_LOG( $name, 5, "----------------------------------------" );
- if ( $cs =~ m/set (.*)(MSwitchtoggle)(.*)/ ) {
- $cs = MSwitch_toggle( $hash, $cs );
- MSwitch_LOG( $name, 5, "$name: fround toggle -> " . $cs );
- }
- MSwitch_LOG( $name, 5, "$name: execute repeat $time -> " . $cs );
- if ( AttrVal( $name, 'MSwitch_Debug', "0" ) ne '2' ) {
- if ( $cs =~ m/{.*}/ ) {
- eval($cs);
- if ($@) {
- MSwitch_LOG( $name, 1,
- "$name MSwitch_repeat: ERROR $cs: $@ " . __LINE__ );
- }
- }
- else {
- my $errors = AnalyzeCommandChain( undef, $cs );
- if ( defined($errors) ) {
- MSwitch_LOG( $name, 1,
- "$name Absent_repeat $cs: ERROR : $errors -> Comand: $cs" );
- }
- }
- }
- delete( $hash->{helper}{repeats}{$time} );
- }
- #########################
- sub MSwitch_Createnumber($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $number = AttrVal( $Name, 'MSwitch_RandomNumber', '' ) + 1;
- my $number1 = int( rand($number) );
- readingsSingleUpdate( $hash, "RandomNr", $number1, 1 );
- return;
- }
- ################################
- sub MSwitch_Createnumber1($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- my $number = AttrVal( $Name, 'MSwitch_RandomNumber', '' ) + 1;
- my $number1 = int( rand($number) );
- readingsSingleUpdate( $hash, "RandomNr1", $number1, 1 );
- return;
- }
- ###############################
- sub MSwitch_Safemode($) {
- my ($hash) = @_;
- my $Name = $hash->{NAME};
- if ( AttrVal( $Name, 'MSwitch_Safemode', '0' ) == 0 ) { return; }
- my $time = gettimeofday();
- $time =~ s/\.//g;
- my $time1 = int($time);
- my $count = 0;
- my $timehash = $hash->{helper}{savemode};
- foreach my $a ( keys %{$timehash} ) {
- $count++;
- if ( $a < $time1 - 1000000 ) # für 10 sekunden
- {
- delete( $hash->{helper}{savemode}{$a} );
- $count = $count - 1;
- }
- }
- $hash->{helper}{savemode}{$time1} = $time1;
- if ( $count > $savecount ) {
- Log3( $Name, 1,
- "Das Device "
- . $Name
- . " wurde automatisch deaktiviert ( Safemode )" );
- $hash->{helper}{savemodeblock}{blocking} = 'on';
- readingsSingleUpdate( $hash, "Safemode", 'on', 1 );
- foreach my $a ( keys %{$timehash} ) {
- delete( $hash->{helper}{savemode}{$a} );
- }
- $attr{$Name}{disable} = '1';
- }
- return;
- }
- ###############################################################
- sub MSwitch_EventBulk($$$$) {
- my ( $hash, $event, $update, $from ) = @_;
- my $name = $hash->{NAME};
- MSwitch_LOG( $name, 5, "aufruf eventbulk eventin: " . $event );
- return if !defined $event;
- return if !defined $hash;
- if ( $hash eq "" ) { return; }
- my @evtparts = split( /:/, $event );
- $update = '1';
- my $evtsanzahl = @evtparts;
- MSwitch_LOG( $name, 5, "aufruf eventzahl: " . $evtsanzahl );
- if ( $evtsanzahl < 3 ) {
- my $eventfrom = $hash->{helper}{eventfrom};
- unshift( @evtparts, $eventfrom );
- $evtsanzahl = @evtparts;
- }
- my $evtfull = join( ':', @evtparts );
- $evtparts[2] = '' if !defined $evtparts[2];
- MSwitch_LOG( $name, 5, "aufruf eventbulk eventfullout: " . $evtfull );
- MSwitch_LOG( $name, 5, "aufruf eventbulk event " . $event );
- MSwitch_LOG( $name, 5, "aufruf eventbulk eventset " . $hash->{eventsave} );
- if ( ReadingsVal( $name, 'last_event', '' ) ne $event
- && $event ne ''
- && $hash->{eventsave} ne 'saved' )
- {
- #$hash-Bulkfrom} ="saved";
- $hash->{eventsave} = "saved";
- readingsBeginUpdate($hash);
- # if ( AttrVal( $name, 'MSwitch_Debug', "0" ) eq '4' )
- # {
- # readingsBulkUpdate( $hash, "Bulkfrom", "von:".$from ) ;
- # }
- readingsBulkUpdate( $hash, "EVENT", $event ) if $event ne '';
- readingsBulkUpdate( $hash, "EVTFULL", $evtfull ) if $evtfull ne '';
- readingsBulkUpdate( $hash, "EVTPART1", $evtparts[0] )
- if $evtparts[0] ne '';
- readingsBulkUpdate( $hash, "EVTPART2", $evtparts[1] )
- if $evtparts[1] ne '';
- readingsBulkUpdate( $hash, "EVTPART3", $evtparts[2] )
- if $evtparts[2] ne '';
- readingsBulkUpdate( $hash, "last_event", $event ) if $event ne '';
- readingsEndUpdate( $hash, $update );
- }
- return;
- }
- ##########################################################
- # setzt reihenfolge und testet ID
- sub MSwitch_priority(@) {
- my ( $hash, $execids, @devices ) = @_;
- my $name = $hash->{NAME};
- MSwitch_LOG( $name, 5, "$name: zuweisung der reihenfolge und der id" );
- if ( AttrVal( $name, 'MSwitch_Expert', "0" ) ne '1' ) {
- return @devices;
- }
- my %devicedetails = MSwitch_makeCmdHash($name);
- # my $execids = "0" if !defined $execids;
- my %new;
- foreach my $device (@devices) {
- # $execids beinhaltet auszuführende ids gesetzt bei init
- my $key1 = $device . "_id";
- Log3( $name, 5,
- "$name: device hat die ID $device - $devicedetails{$key1}" );
- next if $devicedetails{$key1} ne $execids;
- my $key = $device . "_priority";
- my $prio = $devicedetails{$key};
- MSwitch_LOG( $name, 5,
- "$name: device hat die priority $device - $devicedetails{$key1}"
- );
- $new{$device} = $prio;
- }
- my @new = %new;
- my @newlist;
- for my $key ( sort { $new{$a} <=> $new{$b} } keys %new ) {
- if ( $key ne "" && $key ne " " ) {
- push( @newlist, $key );
- }
- }
- my $anzahl = @newlist;
- MSwitch_LOG( $name, 5, "$name: anzahl $anzahl" );
- @devices = @newlist if $anzahl > 0;
- return @devices;
- }
- ##########################################################
- ##########################################################
- # setzt reihenfolge und testet ID
- sub MSwitch_sort(@) {
- my ( $hash, $typ, @devices ) = @_;
- my $name = $hash->{NAME};
- MSwitch_LOG( $name, 5, "$name: zuweisung der reihenfolge" );
- my %devicedetails = MSwitch_makeCmdHash($name);
- my %new;
- foreach my $device (@devices) {
- my $key = $device . $typ;
- my $prio = $devicedetails{$key};
- MSwitch_LOG( $name, 5,
- "$name: device hat $typ $device - $devicedetails{$key}" );
- $new{$device} = $prio;
- }
- my @new = %new;
- my @newlist;
- for my $key ( sort { $new{$a} <=> $new{$b} } keys %new ) {
- if ( $key ne "" && $key ne " " ) {
- push( @newlist, $key );
- }
- }
- my $anzahl = @newlist;
- MSwitch_LOG( $name, 5, "$name: anzahl $anzahl" );
- @devices = @newlist if $anzahl > 0;
- return @devices;
- }
- ##########################################################
- sub MSwitch_set_dev($) {
- # setzt NOTIFYDEF
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $not = ReadingsVal( $name, 'Trigger_device', '' );
- if ( $not ne 'no_trigger' ) {
- if ( $not eq "all_events" ) {
- delete( $hash->{NOTIFYDEV} );
- if ( ReadingsVal( $name, '.Trigger_Whitelist', '' ) ne '' ) {
- $hash->{NOTIFYDEV} =
- ReadingsVal( $name, '.Trigger_Whitelist', '' );
- }
- }
- else {
- $hash->{NOTIFYDEV} = $not;
- my $devices = MSwitch_makeAffected($hash);
- $hash->{DEF} = $not . ' # ' . $devices;
- }
- }
- else {
- $hash->{NOTIFYDEV} = 'no_trigger';
- delete $hash->{DEF};
- }
- }
- ##############################################################
- sub MSwitch_dec($$) {
- # ersetzungen direkt vor befehlsausführung
- my ( $hash, $todec ) = @_;
- my $name = $hash->{NAME};
- $todec =~ s/\n//g;
- $todec =~ s/#\[wa\]/|/g;
- $todec =~ s/\$NAME/$hash->{helper}{eventfrom}/;
- $todec =~ s/MSwitch_Self/$name/;
- my $x = 0;
- while ( $todec =~ m/(.*?)(\$SELF)(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $todec = $firstpart . $name . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- # setmagic ersetzun
- $x = 0;
- while ( $todec =~ m/(.*)\[(.*)\:(.*)\](.*)/ ) {
- $x++; # notausstieg notausstieg
- last if $x > 20; # notausstieg notausstieg
- my $setmagic = ReadingsVal( $2, $3, 0 );
- $todec = $1 . $setmagic . $4;
- }
- return $todec;
- }
- ################################################################
- sub MSwitch_clearlog($) {
- my ( $hash, $cs ) = @_;
- my $name = $hash->{NAME};
- open( BACKUPDATEI, ">./log/MSwitch_debug_$name.log" );
- print BACKUPDATEI localtime() . " Starte Log\n"; #
- close(BACKUPDATEI);
- }
- ################################################################
- sub MSwitch_debug2($$) {
- my ( $hash, $cs ) = @_;
- my $name = $hash->{NAME};
- return if $cs eq '';
- open( BACKUPDATEI, ">>./log/MSwitch_debug_$name.log" )
- ; # Datei zum Schreiben öffnen
- print BACKUPDATEI localtime() . ": -> $cs\n"; #
- close(BACKUPDATEI);
- }
- ##################################
- sub MSwitch_LOG($$$) {
- my ( $name, $level, $cs ) = @_;
- my $hash = $defs{$name};
- if (
- (
- AttrVal( $name, 'MSwitch_Debug', "0" ) eq '2'
- || AttrVal( $name, 'MSwitch_Debug', "0" ) eq '3'
- )
- && ( $level eq "6" || $level eq "1" )
- )
- {
- MSwitch_debug2( $hash, $cs );
- }
- $level = 5 if $level eq "6";
- Log3( $name, $level, $cs );
- }
- #########################
- sub MSwitch_confchange($$) {
- # change wenn folgende einträge vorhanden
- #I testinfo
- #Q dummy1#zu schaltendes geraet#device
- my ( $hash, $cs ) = @_;
- my $name = $hash->{NAME};
- MSwitch_clearlog($hash);
- $cs = urlDecode($cs);
- $cs =~ s/#\[sp\]/ /g;
- my @changes = split( /\|/, $cs );
- foreach my $change (@changes) {
- #MSwitch_LOG( $name, 5, "zu ersetzen: ".$change );
- my @names = split( /#/, $change );
- # afected devices
- my $tochange1 = ReadingsVal( $name, ".Device_Affected", "" );
- my $oldname = $names[0] . "-";
- my $newname = $names[1] . "-";
- my @devices = split( /,/, $tochange1 );
- my $x = 0;
- foreach (@devices) {
- $_ =~ s/$oldname/$newname/g;
- $devices[$x] = $_;
- $x++;
- }
- my $newdevices = join( ',', @devices );
- readingsSingleUpdate( $hash, ".Device_Affected", $newdevices, 0 );
- #details
- my $tochange2 = ReadingsVal( $name, ".Device_Affected_Details", "" );
- my @devicesdetails = split( /#\[ND\]/, $tochange2 );
- $x = 0;
- foreach (@devicesdetails) {
- $_ =~ s/$oldname/$newname/g;
- $devicesdetails[$x] = $_;
- $x++;
- }
- $tochange2 = join( '#[ND]', @devicesdetails );
- $x = 0;
- while ( $tochange2 =~ m/(.*?)($names[0])(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $tochange2 = $firstpart . $names[1] . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- readingsSingleUpdate( $hash, ".Device_Affected_Details", $tochange2,
- 0 );
- }
- fhem("deletereading $name .change");
- fhem("deletereading $name .change_info");
- }
- #########################
- sub MSwitch_makefreecmd($$) {
- #ersetzungen und variablen für freecmd
- my ( $hash, $cs ) = @_;
- my $name = $hash->{NAME};
- my $ersetzung = "";
- # entferne kommntarzeilen
- $cs =~ s/#.*\n//g;
- # entferne zeilenumbruch
- $cs =~ s/\n//g;
- # ersetze Eventvariablen
- $ersetzung = ReadingsVal( $name, "EVTPART3", "" );
- $cs =~ s/\$EVTPART3/$ersetzung/g;
- $ersetzung = ReadingsVal( $name, "EVTPART2", "" );
- $cs =~ s/\$EVTPART2/$ersetzung/g;
- $ersetzung = ReadingsVal( $name, "EVTPART1", "" );
- $cs =~ s/\$EVTPART1/$ersetzung/g;
- $ersetzung = ReadingsVal( $name, "EVENT", "" );
- $cs =~ s/\$EVENT/$ersetzung/g;
- $ersetzung = ReadingsVal( $name, "EVENTFULL", "" );
- $cs =~ s/\$EVENTFULL/$ersetzung/g;
- $cs =~ s/\$NAME/$hash->{helper}{eventfrom}/;
- my $x = 0;
- while ( $cs =~ m/(.*?)(\$SELF)(.*)?/ ) {
- my $firstpart = $1;
- my $secondpart = $2;
- my $lastpart = $3;
- $cs = $firstpart . $name . $lastpart;
- $x++;
- last if $x > 10; #notausstieg
- }
- # setmagic ersetzun
- MSwitch_LOG( $name, 5, "vor freecmd: " . $cs );
- $x = 0;
- while ( $cs =~ m/(.*)\[(.*)\:(.*)\](.*)/ ) {
- $x++; # notausstieg notausstieg
- last if $x > 20; # notausstieg notausstieg
- my $setmagic = ReadingsVal( $2, $3, 0 );
- $cs = $1 . $setmagic . $4;
- }
- MSwitch_LOG( $name, 5, "after freecmd: " . $cs );
- return $cs;
- }
- #################################
- 1;
- =pod
- =item helper
- =item summary MultiswitchModul
- =item summary_DE Modul zum event und zeitgesteuerten Schalten von Devices etc.
- =begin html
- <a name="MSwitch"></a>
- <h3>MSwitch</h3>
- <ul>
- <u><b>MSwitch</b></u>
- <br />
- MSwitch is an auxiliary module that works both event- and time-controlled. <br />
- For a detailed description see Wiki
- <br /><br />
- <a name="MSwitchdefine"></a>
- <b>Define</b>
- <ul><br />
- <code>define < Name > MSwitch;</code>
- <br /><br />
- Beispiel:
- <ul><br />
- <code>define Schalter MSwitch</code><br />
- </ul>
- <br />
- The command creates a device of type MSwitch named Switch. <br />
- All further configuration takes place at a later time and can be modified and adjusted within the device at any time
- </ul>
- <br /><br />
- <a name="MSwitch set"></a>
- <b>Set</b>
- <ul>
- <li> inactive - sets the device inactive </li>
- <li> active - sets the device active </li>
- <li> backup MSwitch - creates a backup file with the configuration of all MSwitch devices </li>
- <li> del_delays - deletes all pending timed commands </li>
- <li> exec_cmd1 - immediate execution of the command branch1 </li>
- <li> exec_cmd2 - immediate execution of command branch2 </li>
- <li> fakeevent [event] - simulation of an incoming event </li>
- <li> wait [sec] - no acceptance of events for given period </li>
- <br />
- </ul>
- <br /><br />
- <a name="MSwitch get"></a>
- <b>Get</b>
- <ul>
- <li> active_timer show - displays a list of all pending timers and delays </li>
- <li> active_timer delete - deletes all pending timers and delays. Timers are recalculated </li>
- <li> get_config - shows the config set associated with the device</li>
- <li> restore_Mswitch_date this_device - restore the device from the backupfile </li>
- <li> restore_Mswitch_date all_devices - restore all MSwitchdevices from the backupfile </li>
- <br />
- </ul>
- <br /><br />
- <a name="MSwitch attribut"></a>
- <b>Attribute</b>
- <ul>
- <li> MSwitch_Help: 0.1 - displays help buttons for all relevant fields </li>
- <li> MSwitch_Debug: 0,1,2,3 - 1. switches test fields to Conditions etc. / 2. Testmode, no active cmds / 3. pure development mode </li>
- <li> MSwitch_Expert: 0.1 - 1. enables additional options such as global triggering, priority selection, command repetition, etc. </li>
- <li> MSwitch_Delete_Delays: 0.1 - 1. deletes all pending delays when another suitable event arrives</li>
- <li> MSwitch_Include_Devicecmds: 0,1 - 1. all devices with own command set (set?) are included in affected devices </li>
- <li> MSwitch_Include_Webcmds: 0.1 - 1. all devices with existing WbCmds are included in affected devices </li>
- <li> MSwitch_Include_MSwitchcmds: 0.1 - 1. all devices with existing MSwitchcmds are included in affected devices </li>
- <li> MSwitch_Activate_MSwitchcmds: 0.1 - 1. activates the attribute MSwitchcmds in all devices </li>
- <li> MSwitch_Lock_Quickedit: 0,1 - 1. activates the lock of the selection field 'affected devices' </li>
- <li> MSwitch_Ignore_Types: - List of all device types that are not displayed in the 'affected devices' </li>
- <li> MSwitch_Trigger_Filter - List of events to ignore </li>
- <li> MSwitch_Extensions: 0.1 - 1. Enables additional option Devicetogggle </li>
- <li>MSwitch_Startdelay - delays the start of MSwitch after Fhemstart by the specified time in seconds. Recommended: 30 seconds</li>
- <li> MSwitch_Inforoom - contains a room name where MSwitches are displayed in detail </li>
- <li> MSwitch_Mode: Full, Notify, Toggle - Device Operation Mode </li>
- <li> MSwitch_Condition_Time: 0.1 - activation of the trigger conditions for timed triggering </li>
- <li> MSwitch_Safemode: 0.1 - 1. aborts all actions of the device if more than 20 calls per second take place </li>
- <li> MSwitch_RandomTime - see Wiki </li>
- <li> MSwitch_RandomNumber - see Wiki </li>
- </ul>
- </ul>
- =end html
- =begin html_DE
- <a name="MSwitch"></a>
- <h3>MSwitch</h3>
- <ul>
- <u><b>MSwitch</b></u>
- <br />
- MSwitch ist ein Hilfsmodul , das sowohl event-, als auch zeitgesteuert arbeitet.<br />
- Für eine umfangreche Beschreibung siehe Wiki: https://wiki.fhem.de/wiki/MSwitch
- <br /><br />
- <a name="MSwitchdefine"></a>
- <b>Define</b>
- <ul><br />
- <code>define < Name > MSwitch;</code>
- <br /><br />
- Beispiel:
- <ul><br />
- <code>define Schalter MSwitch</code><br />
- </ul>
- <br />
- Der Befehl legt ein Device vom Typ MSwitch an mit dem Namen Schalter.<br />
- sämtliche weitere Konfiguration erfolgt zu einem späteren Zeitpunkt und kann innerhalb des Devices jerderzeit verändert und angepasst werden
- </ul>
- <br /><br />
- <a name="MSwitch set"></a>
- <b>Set</b>
- <ul>
- <li>inactive - setzt das Device inaktiv</li>
- <li>active - setzt das Device aktiv</li>
- <li>backup MSwitch - legt eine Backupdatei mit der Konfiguration aller MSwitchdevices an</li>
- <li>del_delays - löscht alle anstehenden timer für zeitversetzte Befehle</li>
- <li>exec_cmd1 - sofortiges Ausführen des Kommandozweiges1</li>
- <li>exec_cmd2 - sofortiges Ausführen des Kommandozweiges2</li>
- <li>fakeevent [event] - simulation eines eingehenden Events</li>
- <li>wait [sek] - keine annahme von Events für vorgegebenen Zeitraum</li>
- <br />
- </ul>
- <br /><br />
- <a name="MSwitch get"></a>
- <b>Get</b>
- <ul>
- <li>active_timer show - zeigt eine Liste aller anstehenden Timer und Delays</li>
- <li>active_timer delete - löscht alle anstehenden Timer und Delays. Timer werden neu berechnet</li>
- <li>get_config - zeigt den dem Device zugeordneten Configsatz</li>
- <li>restore_Mswitch_date this_device - restore des Devices aus dem Backupfile</li>
- <li>restore_Mswitch_date all_devices - restore aller MSwitchdevices aus dem Backupfile</li>
- <br />
- </ul>
- <br /><br />
- <a name="MSwitch attribut"></a>
- <b>Attribute</b>
- <ul>
- <li>MSwitch_Help:0,1 - zeigt Hilfebuttons zu allen relevanten Feldern</li>
- <li>MSwitch_Debug:0,1,2 - 1. schaltet Prüffelder zu Conditions etc. an / 2. Testmode shreibt alle Aktionen in ein seperates Log, führt diese aber nicht aus / 3. reiner Entwicklungsmode</li>
- <li>MSwitch_Expert:0,1 - 1. aktiviert Zusatzoptionenv wi z.B globales triggern, prioritätsauswahl, Befehlswiederholungesn etc. </li>
- <li>MSwitch_Delete_Delays:0,1 - 1. löscht alle anstehenden Delays bei erneutem eintreffen eines passenden Events</li>
- <li>MSwitch_Include_Devicecmds:0,1 - 1. alles Devices mit eigenem Befehlssatz (set ?) werden in affected Devices einbezogen</li>
- <li>MSwitch_Include_Webcmds:0,1 - 1. alles Devices mit vorhandenen WbCmds werden in affected Devices einbezogen</li>
- <li>MSwitch_Include_MSwitchcmds:0,1 - 1. alles Devices mit vorhandenen MSwitchcmds werden in affected Devices einbezogen</li>
- <li>MSwitch_Activate_MSwitchcmds:0,1 - 1. aktiviert in allen Devices das Attribut MSwitchcmds</li>
- <li>MSwitch_Lock_Quickedit:0,1 - 1. aktiviert die sperre des Auswahlfeldes 'affected devices'</li>
- <li>MSwitch_Ignore_Types: - Liste aller DeviceTypen , die nicht in den 'affected devices' dargestellt werden'</li>
- <li>MSwitch_Trigger_Filter - Liste aller zu ignorierenden Events</li>
- <li>MSwitch_Extensions:0,1 - 1. aktiviert zusatzoption Devicetogggle</li>
- <li>MSwitch_Startdelay - verzögert den Start von MSwitch nach Fhemstart um die angegebene Zeit in Sekunden . Empfohlen:30 sekunden</li>
- <li>MSwitch_Inforoom - beinhalttet einen Raumnamen , in dem MSwitches detailiert dargestellt werden</li>
- <li>MSwitch_Mode:Full,Notify,Toggle - Betriebsmodus des Devices</li>
- <li>MSwitch_Condition_Time:0,1 - zuschaltung der Triggerconditions für zeitgesteuertes Auslösen</li>
- <li>MSwitch_Safemode:0,1 - 1. bricht alle Aktionen des Devices ab, wenn mehr als 20 Aufrufe pro Sekunde erfolgen</li>
- <li>MSwitch_RandomTime - siehe Wiki</li>
- <li>MSwitch_RandomNumber - siehe Wiki</li>
- </ul>
- </ul>
- =end html_DE
- =cut
|