| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424 |
- ################################################################
- #
- # Copyright notice
- #
- # (c) 2013 Alexander Schulz
- #
- # This script 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.
- #
- # The GNU General Public License can be found at
- # http://www.gnu.org/copyleft/gpl.html.
- # A copy is found in the textfile GPL.txt and important notices to the license
- # from the author is found in LICENSE.txt distributed with these scripts.
- #
- # This script 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.
- #
- # This copyright notice MUST APPEAR in all copies of the script!
- #
- ################################################################
- #
- # SSH support by PitpatV
- #
- ################################################################
- # $Id: 42_SYSMON.pm 15910 2018-01-16 23:07:56Z hexenmeister $
- package main;
- use strict;
- use warnings;
- use Scalar::Util qw(looks_like_number);
- use Blocking;
- use Data::Dumper;
- my $missingModulRemote;
- eval "use Net::Telnet;1" or $missingModulRemote .= "Net::Telnet ";
- my $VERSION = "2.3.3";
- use constant {
- PERL_VERSION => "perl_version",
- DATE => "date",
- UPTIME => "uptime",
- UPTIME_TEXT => "uptime_text",
- STARTTIME_TEXT => "starttime_text",
- STARTTIME => "starttime",
- FHEMSTARTTIME_TEXT => "fhemstarttime_text",
- FHEMSTARTTIME => "fhemstarttime",
- FHEMUPTIME => "fhemuptime",
- FHEMUPTIME_TEXT => "fhemuptime_text",
- IDLETIME => "idletime",
- IDLETIME_TEXT => "idletime_text"
- };
- use constant {
- CPU_CORE_CNT => "cpu_core_count",
- CPU_FREQ => "cpu_freq",
- CPU0_FREQ => "cpu0_freq",
- CPU1_FREQ => "cpu1_freq",
- CPU2_FREQ => "cpu2_freq",
- CPU3_FREQ => "cpu3_freq",
- CPU4_FREQ => "cpu4_freq",
- CPU5_FREQ => "cpu5_freq",
- CPU6_FREQ => "cpu6_freq",
- CPU7_FREQ => "cpu7_freq",
- CPU_BOGOMIPS => "cpu_bogomips",
- CPU_MODEL_NAME=>"cpu_model_name",
- CPU_TEMP => "cpu_temp",
- CPU0_TEMP => "cpu0_temp",
- CPU1_TEMP => "cpu1_temp",
- CPU2_TEMP => "cpu2_temp",
- CPU3_TEMP => "cpu3_temp",
- CPU4_TEMP => "cpu4_temp",
- CPU5_TEMP => "cpu5_temp",
- CPU6_TEMP => "cpu6_temp",
- CPU7_TEMP => "cpu7_temp",
- CPU_TEMP_AVG => "cpu_temp_avg",
- CPU0_TEMP_AVG => "cpu0_temp_avg",
- CPU1_TEMP_AVG => "cpu1_temp_avg",
- CPU2_TEMP_AVG => "cpu2_temp_avg",
- CPU3_TEMP_AVG => "cpu3_temp_avg",
- CPU4_TEMP_AVG => "cpu4_temp_avg",
- CPU5_TEMP_AVG => "cpu5_temp_avg",
- CPU6_TEMP_AVG => "cpu6_temp_avg",
- CPU7_TEMP_AVG => "cpu7_temp_avg",
- LOADAVG => "loadavg"
- };
- use constant {
- RAM => "ram",
- SWAP => "swap"
- };
- use constant {
- ETH0 => "eth0",
- WLAN0 => "wlan0",
- DIFF_SUFFIX => "_diff",
- SPEED_SUFFIX => "_speed",
- IP_SUFFIX => "_ip",
- IP6_SUFFIX => "_ip6",
- FB_WLAN_STATE => "wlan_state",
- FB_WLAN_GUEST_STATE => "wlan_guest_state",
- FB_INET_IP => "internet_ip",
- FB_INET_STATE => "internet_state",
- FB_N_TIME_CTRL => "night_time_ctrl",
- FB_NUM_NEW_MESSAGES => "num_new_messages",
- FB_FW_VERSION => "fw_version_info",
- FB_DECT_TEMP => "dect_temp",
-
- FB_DSL_RATE => "dsl_rate",
- FB_DSL_SYNCTIME => "dsl_synctime",
- FB_DSL_FEC_15 => "dsl_fec_15",
- FB_DSL_CRC_15 => "dsl_crc_15",
- };
- use constant FS_PREFIX => "~ ";
- #use constant FS_PREFIX_N => "fs_";
- my $DEFAULT_INTERVAL_BASE = 60;
- sub
- SYSMON_Initialize($)
- {
- my ($hash) = @_;
- SYSMON_Log($hash, 5, "");
- $hash->{DefFn} = "SYSMON_Define";
- $hash->{UndefFn} = "SYSMON_Undefine";
- $hash->{GetFn} = "SYSMON_Get";
- $hash->{SetFn} = "SYSMON_Set";
- $hash->{AttrFn} = "SYSMON_Attr";
- $hash->{AttrList} = "filesystems network-interfaces user-defined disable:0,1 nonblocking:0,1 ".
- "telnet-time-out ".
- "user-fn2 user-fn ".
- "telnet-prompt-regx telnet-login-prompt-regx ".
- "exclude ".
- $readingFnAttributes;
- }
- ### attr NAME user-defined osUpdates:1440:Aktualisierungen:cat ./updates.txt [,<readingsName>:<Interval_Minutes>:<Comment>:<Cmd>]
- sub
- SYSMON_Define($$)
- {
- my ($hash, $def) = @_;
- SYSMON_Log($hash, 5, "$def");
- my @a = split("[ \t][ \t]*", $def);
- return "Usage: define <name> SYSMON [MODE[:[USER@]HOST][:PORT]] [M1 [M2 [M3 [M4]]]]" if(@a < 2);
- # define sysmon SYSMON local
- # define sysmon SYSMON local 1 1 1 10
- # define sysmon SYSMON telnet:fritz.box
- # define sysmon SYSMON telnet:fritz.box:23
- # define sysmon SYSMON telnet:fritz.box:23 10 10 10 60
- # define sysmon SYSMON telnet:user@fritz.box:23
-
- if(int(@a)>=3)
- {
- my @na = @a[2..scalar(@a)-1];
-
- # wenn das erste Element nicht numerisch
- if(!($na[0] =~ /^\d+$/)) {
- # set mode/host/port
- my($mode, $host, $port) = split(/:/, $na[0]);
- $mode=lc($mode);
- # TODO SSH
- if(defined($mode)&&($mode eq 'local' || $mode eq 'telnet' || $mode eq 'ssh')) {
- $hash->{MODE} = $mode;
- delete($hash->{HOST});
- delete($hash->{USER});
- # erkennen, wenn User angegeben ist
- if($host) {
- my($user,$th) = split(/@/,$host);
- if(defined($th)) {
- $hash->{USER} = lc($user);
- $host = $th;
- }
- $hash->{HOST} = lc($host) if(defined($host));
- # DefaultPort je nach Protokol
- if(!defined($port)) {
- $port = '23' if($mode eq 'telnet');
- $port = '22' if($mode eq 'ssh');
- }
- $hash->{PORT} = lc($port);
- }
- } else {
- return "unexpected mode. Use local, ssh or telnet only.";
- }
- shift @na;
- } else {
- $hash->{MODE}='local';
- }
- SYSMON_setInterval($hash, @na);
- } else {
- $hash->{MODE}='local';
- SYSMON_setInterval($hash, undef);
- }
- $hash->{STATE} = "Initialized";
- #$hash->{DEF_TIME} = time() unless defined($hash->{DEF_TIME});
- #SYSMON_updateCurrentReadingsMap($hash);
- RemoveInternalTimer($hash);
- InternalTimer(gettimeofday()+$hash->{INTERVAL_BASE}, "SYSMON_Update", $hash, 0);
- #$hash->{LOCAL} = 1;
- #SYSMON_Update($hash); #-> so nicht. hat im Startvorgang gelegentlich (oft) den Server 'aufgehaengt'
- #delete $hash->{LOCAL};
-
- return undef;
- }
- sub
- SYSMON_setInterval($@)
- {
- my ($hash, @a) = @_;
- my $interval = $DEFAULT_INTERVAL_BASE;
- $hash->{INTERVAL_BASE} = $interval;
- my $p1=1;
- my $p2=1;
- my $p3=1;
- my $p4=10;
- if(defined($a[0]) && int($a[0]) eq $a[0]) {$p1 = $a[0];}
- if(defined($a[1]) && int($a[1]) eq $a[1]) {$p2 = $a[1];} else {$p2 = $p1;}
- if(defined($a[2]) && int($a[2]) eq $a[2]) {$p3 = $a[2];} else {$p3 = $p1;}
- if(defined($a[3]) && int($a[3]) eq $a[3]) {$p4 = $a[3];} else {$p4 = $p1*10;}
- $hash->{INTERVAL_MULTIPLIERS} = $p1." ".$p2." ".$p3." ".$p4;
- }
- #my $cur_readings_map; => $hash->{helper}{cur_readings_map}
- sub
- SYSMON_updateCurrentReadingsMap($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- if( AttrVal($name, "disable", "") eq "1" ) {
- return undef;
- }
- my $rMap;
-
- # Map aktueller Namen erstellen
-
- # Feste Werte
- my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- if($mode eq 'local'){
- $rMap->{+PERL_VERSION} = "Perl Version";
- }
- $rMap->{+DATE} = "Date";
- $rMap->{+CPU_BOGOMIPS} = "BogoMIPS";
- $rMap->{+CPU_MODEL_NAME} = "CPU model name";
- if(SYSMON_isCPUFreqRPiBBB($hash)) {
- $rMap->{"cpu_freq"} = "CPU frequency";
- $rMap->{"cpu0_freq"} = "CPU frequency";
- $rMap->{"cpu_freq_stat"} = "CPU frequency stat";
- $rMap->{"cpu0_freq_stat"} = "CPU frequency stat";
- }
- foreach my $li (0..7) {
- if(SYSMON_isCPUXFreq($hash, $li)) {
- $rMap->{"cpu".$li."_freq"} = "CPU frequency (core $li)";
- $rMap->{"cpu".$li."_freq_stat"} = "CPU frequency (core $li) stat";
- }
- }
- if(SYSMON_isCPUTempRPi($hash) || SYSMON_isCPUTempBBB($hash) || SYSMON_isCPUTempFB($hash)) {
- #$rMap->{+CPU_TEMP} = "CPU Temperatur";
- #$rMap->{"cpu_temp_avg"} = "Durchschnittliche CPU Temperatur";
- $rMap->{+CPU_TEMP} = "CPU temperature";
- $rMap->{+CPU_TEMP.'_stat'}= "CPU temperature stat";
- #$rMap->{"cpu0_temp"} = "CPU temperature (core 0)";
- $rMap->{"cpu_temp_avg"} = "Average CPU temperature";
- #$rMap->{"cpu0_temp_avg"} = "Average CPU temperature (core 0)";
- }
- foreach my $li (0..7) {
- if(SYSMON_isCPUTemp_X($hash, $li)) {
- $rMap->{"cpu".$li."_temp"} = "CPU temperature (core $li)";
- $rMap->{"cpu".$li."_temp_avg"} = "Average CPU temperature (core $li)";
- $rMap->{"cpu".$li."_temp_stat"} = "CPU temperature stat (core $li)";
- }
- }
-
- $rMap->{+CPU_CORE_CNT} = "Number of CPU cores";
-
- if(SYSMON_isSysPowerAc($hash)) {
- #$rMap->{"power_ac_online"} = "AC-Versorgung Status";
- #$rMap->{"power_ac_present"} = "AC-Versorgung vorhanden";
- #$rMap->{"power_ac_current"} = "AC-Versorgung Strom";
- #$rMap->{"power_ac_voltage"} = "AC-Versorgung Spannung";
- $rMap->{"power_ac_stat"} = "AC-Versorgung Info";
- $rMap->{"power_ac_text"} = "AC-Versorgung Info";
- }
- if(SYSMON_isSysPowerUsb($hash)) {
- #$rMap->{"power_usb_online"} = "USB-Versorgung Status";
- #$rMap->{"power_usb_present"} = "USB-Versorgung vorhanden";
- #$rMap->{"power_usb_current"} = "USB-Versorgung Strom";
- #$rMap->{"power_usb_voltage"} = "USB-Versorgung Spannung";
- $rMap->{"power_usb_stat"} = "USB-Versorgung Info";
- $rMap->{"power_usb_text"} = "USB-Versorgung Info";
- }
-
- if(SYSMON_isSysPowerBat($hash)) {
- #$rMap->{"power_battery_online"} = "Batterie-Versorgung Status";
- #$rMap->{"power_battery_present"} = "Batterie-Versorgung vorhanden";
- #$rMap->{"power_battery_current"} = "Batterie-Versorgung Strom";
- #$rMap->{"power_battery_voltage"} = "Batterie-Versorgung Spannung";
- $rMap->{"power_battery_stat"} = "Batterie-Versorgung Info";
- $rMap->{"power_battery_text"} = "Batterie-Versorgung Info";
- $rMap->{"power_battery_info"} = "Batterie-Versorgung Zusatzinfo";
- }
- #$rMap->{"fhemuptime"} = "Betriebszeit FHEM";
- #$rMap->{"fhemuptime_text"} = "Betriebszeit FHEM";
- #$rMap->{"idletime"} = "Leerlaufzeit";
- #$rMap->{"idletime_text"} = "Leerlaufzeit";
- #$rMap->{"loadavg"} = "Durchschnittliche Auslastung";
- #$rMap->{"ram"} = "RAM";
- #$rMap->{"swap"} = "Swap";
- #$rMap->{"uptime"} = "Betriebszeit";
- #$rMap->{"uptime_text"} = "Betriebszeit";
- $rMap->{"fhemuptime"} = "System up time";
- $rMap->{"fhemuptime_text"} = "FHEM up time";
- $rMap->{"idletime"} = "Idle time";
- $rMap->{"idletime_text"} = "Idle time";
- $rMap->{"loadavg"} = "Load average";
- $rMap->{"loadavg_1"} = "Load average 1";
- $rMap->{"loadavg_5"} = "Load average 5";
- $rMap->{"loadavg_15"} = "Load average 15";
-
- $rMap->{"ram"} = "RAM";
- $rMap->{"ram_used_stat"} = "RAM used stat";
- $rMap->{"ram_total"} = "RAM total";
- $rMap->{"ram_used"} = "RAM used";
- $rMap->{"ram_free"} = "RAM free";
- $rMap->{"ram_free_percent"}= "RAM free %";
-
- $rMap->{"swap"} = "swap";
- $rMap->{"swap_used_stat"} = "swap used stat";
- $rMap->{"swap_total"} = "swap total";
- $rMap->{"swap_used"} = "swap used";
- $rMap->{"swap_free"} = "swap free";
- $rMap->{"swap_used_percent"}= "swap used %";
-
- $rMap->{"uptime"} = "System up time";
- $rMap->{"uptime_text"} = "System up time";
- $rMap->{+STARTTIME_TEXT} = "System start time";
- $rMap->{+STARTTIME} = "System start time";
- $rMap->{+FHEMSTARTTIME} = "Fhem start time";
- $rMap->{+FHEMSTARTTIME_TEXT} = "Fhem start time";
- # Werte fuer GesamtCPU
- $rMap->{"stat_cpu"} = "CPU statistics";
- $rMap->{"stat_cpu_diff"} = "CPU statistics (diff)";
- $rMap->{"stat_cpu_percent"} = "CPU statistics (diff, percent)";
- $rMap->{"stat_cpu_text"} = "CPU statistics (text)";
- $rMap->{"cpu_idle_stat"} = "CPU min/max/avg (idle)";
-
- $rMap->{"stat_cpu_user_percent"} = "CPU statistics user %";
- $rMap->{"stat_cpu_nice_percent"} = "CPU statistics nice %";
- $rMap->{"stat_cpu_sys_percent"} = "CPU statistics sys %";
- $rMap->{"stat_cpu_idle_percent"} = "CPU statistics idle %";
- $rMap->{"stat_cpu_io_percent"} = "CPU statistics io %";
- $rMap->{"stat_cpu_irq_percent"} = "CPU statistics irq %";
- $rMap->{"stat_cpu_sirq_percent"} = "CPU statistics sirq %";
-
- # CPU 0-7 (sollte reichen)
- for my $i (0..7) {
- $rMap->{"stat_cpu".$i} = "CPU".$i." statistics";
- $rMap->{"stat_cpu".$i."_diff"} = "CPU".$i." statistics (diff)";
- $rMap->{"stat_cpu".$i."_percent"} = "CPU".$i." statistics (diff, percent)";
- $rMap->{"stat_cpu".$i."_text"} = "CPU".$i." statistics (text)";
- $rMap->{"cpu".$i."_idle_stat"} = "CPU".$i." min/max/avg (idle)";
- }
-
- # Filesystems <readingName>[:<mountPoint>[:<Comment>]]
- my $filesystems = AttrVal($name, "filesystems", undef);
- if(defined $filesystems) {
- my @filesystem_list = split(/,\s*/, trim($filesystems));
- foreach (@filesystem_list) {
- my($fName, $fDef, $nComment) = split(/:/, $_);
- my $fPt;
- if(defined $nComment) {
- $fPt = $nComment;
- } else {
- if(defined $fDef) {
- # Benannte
- $fPt = "Filesystem ".$fDef;
- } else {
- # Unbenannte
- $fPt = "Mount point ".$fName;
- }
- }
-
- $rMap->{$fName} = $fPt;
- $rMap->{$fName."_used"} = $fPt." (used)";
- $rMap->{$fName."_used_percent"} = $fPt." (used %)";
- $rMap->{$fName."_free"} = $fPt." (free)";
-
- }
- } else {
- $rMap->{"root"} = "Filesystem /";
- }
- # Networkadapters: <readingName>[:<interfaceName>[:<Comment>]]
- my $networkadapters = AttrVal($name, "network-interfaces", undef);
- if(defined $networkadapters) {
- my @networkadapters_list = split(/,\s*/, trim($networkadapters));
- foreach (@networkadapters_list) {
- my($nName, $nDef, $nComment) = split(/:/, $_);
- my $nPt;
- if(defined $nComment) {
- $nPt = $nComment;
- } else {
- if(defined $nDef) {
- # Benannte
- $nPt = "Network ".$nDef;
- } else {
- # Unbenannte
- $nPt = "Network adapter ".$nName;
- }
- }
-
- $rMap->{$nName} = $nPt;
- $rMap->{$nName."_diff"} = $nPt." (diff)";
- $rMap->{$nName."_speed"} = $nPt." (speed)";
- $rMap->{$nName."_rx"} = $nPt." (RX)";
- $rMap->{$nName."_tx"} = $nPt." (TX)";
- $rMap->{$nName."_ip"} = $nPt." (IP)";
- $rMap->{$nName."_ip6"} = $nPt." (IP6)";
-
- }
- } else {
- # Default Networkadapters
- # Wenn nichts definiert, werden Default-Werte verwendet
- if(SYSMON_isFB($hash)) {
- my $nName = "ath0";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "ath1";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "cpmac0";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "dsl";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = ETH0;
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "guest";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "hotspot";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "lan";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = "vdsl";
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- } else {
- my $nName = ETH0;
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
-
- $nName = WLAN0;
- $rMap->{$nName} = "Network adapter ".$nName;
- $rMap->{$nName."_diff"} = "Network adapter ".$nName." (diff)";
- $rMap->{$nName."_speed"} = "Network adapter ".$nName." (speed)";
- $rMap->{$nName."_rx"} = "Network adapter ".$nName." (RX)";
- $rMap->{$nName."_tx"} = "Network adapter ".$nName." (TX)";
- $rMap->{$nName."_ip"} = "Network adapter ".$nName." (IP)";
- $rMap->{$nName."_ip6"} = "Network adapter ".$nName." (IP6)";
- }
- }
-
- if(SYSMON_isFB($hash)) {
- # FB WLAN state
- $rMap->{+FB_WLAN_STATE} = "WLAN State";
- $rMap->{+FB_WLAN_GUEST_STATE} = "WLAN Guest State";
- $rMap->{+FB_INET_IP} = "Internet IP";
- $rMap->{+FB_INET_STATE} = "Internet connection state";
- $rMap->{+FB_N_TIME_CTRL} = "night time control";
- $rMap->{+FB_NUM_NEW_MESSAGES} = "new messages";
- $rMap->{+FB_FW_VERSION} = "firmware info";
- $rMap->{+FB_DECT_TEMP} = "DECT temperatur";
-
- $rMap->{+FB_DSL_RATE} = "DSL rate",
- $rMap->{+FB_DSL_SYNCTIME} = "DSL synctime";
- $rMap->{+FB_DSL_FEC_15} = "DSL recoverable errors per 15 minutes"; # forward error correction
- $rMap->{+FB_DSL_CRC_15} = "DSL unrecoverable errors per 15 minutes"; # cyclic redundancy check
-
- }
-
- # User defined
- my $userdefined = AttrVal($name, "user-defined", undef);
- if(defined $userdefined) {
- my @userdefined_list = split(/,\s*/, trim($userdefined));
- foreach (@userdefined_list) {
- # <readingName>:<Interval_Minutes>:<Comment>:<Cmd>
- my($uName, $uInterval, $uComment, $uCmd) = split(/:/, $_);
- if(defined $uComment) {
- # Nur gueltige
- $rMap->{$uName} = $uComment;
- }
- }
- }
- # User defined functions
- my $userfn = AttrVal($name, "user-fn", undef);
- if(defined $userfn) {
- my @userfn_list = split(/,\s*/, trim($userfn));
- foreach (@userfn_list) {
- # <fnName>:<Interval_Minutes>:<reading1>:<reading2>...
- my($fnName, $uInterval, @readings) = split(/:/, $_);
- foreach my $rName (@readings) {
- $rMap->{$rName} = "user defined: $fnName";
- }
- }
- }
- # TEST: TODO
- $rMap->{"io_sda_raw"} = "TEST";
- $rMap->{"io_sda_diff"} = "TEST";
- $rMap->{"io_sda"} = "TEST";
- $hash->{helper}{cur_readings_map} = $rMap;
- return $rMap;
- }
- sub
- SYSMON_getObsoleteReadingsMap($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- my $rMap;
-
- #return $rMap; # TODO TEST
-
- if(!defined($hash->{helper}{cur_readings_map})) {
- SYSMON_updateCurrentReadingsMap($hash);
- }
- # alle READINGS durchgehen
- my @cKeys=keys (%{$defs{$name}{READINGS}});
- foreach my $aName (@cKeys) {
- if(defined ($aName)) {
- # alles hinzufuegen, was nicht in der Aktuellen Liste ist
- if(!defined($hash->{helper}{cur_readings_map}->{$aName})) {
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>> SYSMON_getObsoleteReadingsMap >>> $aName";
- $rMap->{$aName} = 1;
- }
- }
- }
-
- return $rMap;
- }
- sub
- SYSMON_Undefine($$)
- {
- my ($hash, $arg) = @_;
- SYSMON_Log($hash, 5, "$arg");
- RemoveInternalTimer($hash);
-
- BlockingKill( $hash->{helper}{READOUT_RUNNING_PID} )
- if exists $hash->{helper}{READOUT_RUNNING_PID};
-
- return undef;
- }
- sub
- SYSMON_Get($@)
- {
- my ($hash, @a) = @_;
- my $name = $a[0];
- if(@a < 2)
- {
- SYSMON_Log($hash, 3, "@a: get needs at least one parameter");
- return "$name: get needs at least one parameter";
- }
- my $cmd= $a[1];
- SYSMON_Log($hash, 5, "@a");
- if($cmd eq "update")
- {
- #$hash->{LOCAL} = 1;
- SYSMON_Update($hash, 1);
- #delete $hash->{LOCAL};
- return undef;
- }
- if($cmd eq "list") {
- my $map = SYSMON_obtainParameters($hash, 1);
- my $ret = "";
- foreach my $name (keys %{$map}) {
- my $value = $map->{$name};
- $ret = "$ret\n".sprintf("%-20s %s", $name, $value);
- }
-
- my $msg = $hash->{helper}{error_msg};
- if($msg) {
- # Problem mit der Verbindung
- return $msg;
- }
-
- return $ret;
- }
- if($cmd eq "version")
- {
- return $VERSION;
- }
- if($cmd eq "interval_base")
- {
- return $hash->{INTERVAL_BASE};
- }
- if($cmd eq "interval_multipliers")
- {
- return $hash->{INTERVAL_MULTIPLIERS};
- }
-
- if($cmd eq "list_lan_devices")
- {
- my $ret='';
- my $map = SYSMON_getFBLanDeviceList($hash);
- if(defined($map)) {
- foreach my $dname (sort keys %{$map}) {
- my $dev_ip = $map->{$dname}{ip};
- $dev_ip='' unless defined $dev_ip;
- my $dev_mac = $map->{$dname}{mac};
- my $dev_active = $map->{$dname}{active};
- my $dev_active_txt = $dev_active?'true':'false';
- #$ret.="\n"."$dname : active: $dev_active_txt, IP: $dev_ip, MAC: $dev_mac";
- $ret = "$ret\n".sprintf("%-25s : active: %-5s IP: %-16s MAC: %-17s", $dname, $dev_active_txt, $dev_ip, $dev_mac);
- }
- }
- return $ret;
- }
- my $sfb='';
- if(SYSMON_isFB($hash)) {
- $sfb=' list_lan_devices:noArg';
- }
- return "Unknown argument $cmd, choose one of list:noArg update:noArg interval_base:noArg interval_multipliers:noArg version:noArg".$sfb;
- }
- sub
- SYSMON_Set($@)
- {
- my ($hash, @a) = @_;
- my $name = $a[0];
- if(@a < 2)
- {
- SYSMON_Log($hash, 3, "@a: set needs at least one parameter");
- return "$name: set needs at least one parameter";
- }
- my $cmd= $a[1];
- SYSMON_Log($hash, 5, "@a");
- if($cmd eq "interval_multipliers")
- {
- if(@a < 3) {
- SYSMON_Log($hash, 3, "$name: not enought parameters");
- return "$name: not enought parameters";
- }
- my @na = @a[2..scalar(@a)-1];
- SYSMON_setInterval($hash, @na);
- return $cmd ." set to ".($hash->{INTERVAL_MULTIPLIERS});
- }
- if($cmd eq "clean") {
- # Nicht mehr benoetigte Readings loeschen
- my $omap = SYSMON_getObsoleteReadingsMap($hash);
- foreach my $aName (keys %{$omap}) {
- delete $defs{$name}{READINGS}{$aName};
- }
- return;
- }
-
- if($cmd eq "clear")
- {
- my $subcmd = my $cmd= $a[2];
- if(defined $subcmd) {
- delete $defs{$name}{READINGS}{$subcmd};
- return;
- }
-
- return "missing parameter. use clear <reading name>";
- }
-
- if ( lc $cmd eq 'password') {
- my $subcmd = $a[2];
- if(defined $subcmd) {
- my $ret = SYSMON_storePassword ($hash, $subcmd);
- if(!defined($hash->{helper}{error_msg})) {
- SYSMON_Update($hash, 1);
- }
- return $ret;
- }
- }
-
- # TEST
- if($cmd eq "reset")
- {
- delete $defs{$name}->{helper};
- return 'ok';
- }
- return "Unknown argument $cmd, choose one of password interval_multipliers clean:noArg clear";
- }
- sub
- SYSMON_Attr($$$)
- {
- my ($cmd, $name, $attrName, $attrVal) = @_;
- my $hash = $main::defs{$name};
- SYSMON_Log($hash, 5, "SYSMON Attr: $cmd $name ".$attrName?$attrName:''." $attrVal");
- $attrVal= "" unless defined($attrVal);
- my $orig = AttrVal($name, $attrName, "");
-
- if( $orig ne $attrVal ) {
- if( $cmd eq "set" ) {# set, del
-
- if($attrName eq "exclude") {
- my @elist = split(/,\s*/, trim($attrVal));
- my %ehash = map { $_ => 1 } @elist;
- $hash->{helper}->{excludes}=\%ehash;
- }
- if($attrName eq "disable")
- {
- RemoveInternalTimer($hash);
- if($attrVal ne "1")
- {
- InternalTimer(gettimeofday()+$hash->{INTERVAL_BASE}, "SYSMON_Update", $hash, 0);
- $hash->{STATE} = "Active";
- } else {
- $hash->{STATE} = "Inactive";
- }
- #$hash->{LOCAL} = 1;
- #SYSMON_Update($hash);
- #delete $hash->{LOCAL};
- }
- $attr{$name}{$attrName} = $attrVal;
-
- SYSMON_updateCurrentReadingsMap($hash);
-
- #return $attrName ." set to ". $attrVal;
- return undef;
- } elsif( $cmd eq "del" ) {
- if($attrName eq "exclude") {
- $hash->{helper}->{excludes}=undef;
- }
- }
- }
- return;
- }
- #my $u_first_mark = undef;
- sub
- SYSMON_Update($;$)
- {
- my ($hash, $refresh_all) = @_;
-
- $refresh_all="0" unless defined $refresh_all;
- #SYSMON_Log($hash, 5, "refresh_all: ".$refresh_all);
- my $name = $hash->{NAME};
- if(!$hash->{LOCAL}) {
- RemoveInternalTimer($hash);
- InternalTimer(gettimeofday()+$hash->{INTERVAL_BASE}, "SYSMON_Update", $hash, 1);
- }
- if( AttrVal($name, "disable", "") eq "1" )
- {
- #SYSMON_Log($hash, 5, "disabled");
- #$hash->{STATE} = "Inactive";
- } else {
- # Beim ersten mal alles aktualisieren!
- if(!$hash->{helper}{u_first_mark}) {
- $refresh_all = 1;
- }
- SYSMON_obtainLocalCPUFreq($hash);
-
- my $map;
- if(!AttrVal($name, "nonblocking", 1)) {
- # direkt call
-
- # Parameter holen
- $map = SYSMON_obtainParameters($hash, $refresh_all);
-
- # Mark setzen
- if(!$hash->{helper}{u_first_mark}) {
- $hash->{helper}{u_first_mark} = 1;
- }
-
- SYSMON_updateReadings($hash,$map);
- #$hash->{STATE} = "Active";
- } else {
- # blocking call
- if ( exists( $hash->{helper}{READOUT_RUNNING_PID} ) ) {
- SYSMON_Log($hash, 5, "blockingCall: Old readout process still running. Killing old process ".$hash->{helper}{READOUT_RUNNING_PID});
- BlockingKill( $hash->{helper}{READOUT_RUNNING_PID} );
- delete($hash->{helper}{READOUT_RUNNING_PID});
- }
-
- $hash->{helper}{READOUT_RUNNING_PID} = BlockingCall("SYSMON_blockingCall", $name."|".$refresh_all, "SYSMON_blockingFinish", 55, "SYSMON_blockingAbort", $hash);
- }
-
-
-
- }
- }
- sub SYSMON_obtainLocalCPUFreq($) {
- my ($hash) = @_;
-
- my $map;
- #--------------------------------------------------------------------------
- my $base=$DEFAULT_INTERVAL_BASE;
- my $im = "1 1 1 10";
- # Wenn wesentliche Parameter nicht definiert sind, soll aktualisierung immer vorgenommen werden
- if((defined $hash->{INTERVAL_BASE})) {
- $base = $hash->{INTERVAL_BASE};
- }
- if((defined $hash->{INTERVAL_MULTIPLIERS})) {
- $im = $hash->{INTERVAL_MULTIPLIERS};
- }
- my $ref = int(time()/$base);
- my ($m1, $m2, $m3, $m4) = split(/\s+/, $im);
-
- if($m1 gt 0) { # Nur wenn > 0
- # M1: cpu_freq, cpu_temp, cpu_temp_avg, loadavg, procstat, iostat
- if(($ref % $m1) eq 0) {
- # Sonderlocke: CPUFreq
- my $mode = $hash->{MODE};
- if ($mode eq 'local') {
- foreach my $li (0..7) {
- if(SYSMON_isCPUXFreq($hash, $li)) {
- $map = SYSMON_getCPUFreqLocal($hash, $map, $li);
- }
- }
- }
- }
- }
- #--------------------------------------------------------------------------
- SYSMON_updateReadings($hash,$map);
- }
- sub SYSMON_blockingCall($) {
- my ($tparam) = @_;
- my ($name, $refresh_all) = split(/\|/,$tparam);
- my $hash = $main::defs{$name};
- SYSMON_Log($hash, 5, "$name, ".($refresh_all?$refresh_all:''));
- my $map = SYSMON_obtainParameters($hash, $refresh_all);
- # Device-Name mitnehmen
- my $ret = "name|".$name;
-
- my $msg = $hash->{helper}{error_msg};
- if($msg) {
- # Problem mit der Verbindung
- return $ret."|error|".$msg;
- }
- # to String
- foreach my $aName (keys %{$map}) {
- my $value = $map->{$aName};
- # Nur wenn ein gueltiges Value vorliegt
- if(defined $value) {
- # Zeichen maskieren
- $value=~s/#/§²§/g;
- $value=~s/\|/§³§/g;
- $ret.="|".$aName."|".$value;
- }
- }
-
- return $ret;
- }
- sub SYSMON_test() {
-
- #foreach my $d (sort keys %defs) {
- # my $h = $defs{$d};
- # if(defined ($h->{TYPE})) {} else {return $d."-".Dumper($h);}
- #}
-
- my $map;
-
- my $name="TESTNAME";
-
- $map->{test1}="val1";
- $map->{test2}="val2";
- $map->{test3}="val3";
-
- #return Dumper($map);
-
- my $ret = "name|".$name;
- # to ret String
- foreach my $aName (keys %{$map}) {
- my $value = $map->{$aName};
- # Nur wenn ein gueltiges Value vorliegt
- if(defined $value) {
- $value=~s/#/§²§/g;
- $ret.="|".$aName."|".$value;
- }
- }
-
- my @ta = split(/\|/,$ret);
- #return Dumper(@ta);
- my %map2 = @ta;
-
- return Dumper(\%map2);
-
- return $ret;
- }
- sub SYSMON_blockingAbort($) {
- my ($hash) = @_;
- delete($hash->{helper}{READOUT_RUNNING_PID});
- SYSMON_Log($hash, 5, "");
- $hash->{STATE} = "Error: Blocking call aborted (timeout)";
- }
- sub SYSMON_blockingFinish($) {
- my ($map_str) = @_;
-
- my $map;
- # to map
- my @ta = split(/\|/,$map_str);
- my %tm = @ta;
- $map = \%tm;
-
- my $name=$map->{name};
- delete $map->{name};
-
- my $hash = $main::defs{$name};
- delete($hash->{helper}{READOUT_RUNNING_PID});
-
- SYSMON_Log($hash, 5, $map_str);
- # Mark setzen
- if(!$hash->{helper}{u_first_mark}) {
- $hash->{helper}{u_first_mark} = 1;
- }
-
- my $msg = $map->{error};
- if($msg) {
- # Im Fehlerfall State ebtsprechend setzen und nichts aktualisieren.
- $hash->{STATE} = "Error: ".$msg;
- return;
- }
-
- SYSMON_updateReadings($hash,$map);
- #$hash->{STATE} = "Active";
- }
- sub SYSMON_updateReadings($$) {
- my ($hash,$map) = @_;
- SYSMON_Log($hash, 5, "");
- my $name = $hash->{NAME};
-
- readingsBeginUpdate($hash);
-
-
- # Wenn UserFn benutzt wird, werden die erstellten Eintraege erfasst und die entsprechenden Readings nicht erhalten
- my $h_keys;
- my $uFnReadings = $map->{"xuser_fnr"};
- my @a_keys;
- if(defined($uFnReadings)) {
- delete $map->{"xuser_fnr"};
- @a_keys = split(/,\s*/, trim($uFnReadings));
- #$h_keys = map { $_ => "1" } @a_keys;
- }
-
- foreach my $aName (keys %{$map}) {
- my $value = $map->{$aName};
- # Nur aktualisieren, wenn ein gueltiges Value vorliegt
- if(defined $value) {
- # Maskierte Zeichen zuruechersetzen
- $value=~s/§²§/#/g;
- $value=~s/§³§/\|/g;
- readingsBulkUpdate($hash,$aName,$value);
- }
- }
-
- # Nicht mehr benoetigte Readings loeschen
- my $omap = SYSMON_getObsoleteReadingsMap($hash);
-
- # UserFn Keys entfernen
- foreach my $aName (@a_keys) {
- delete($omap->{$aName});
- }
- foreach my $aName (keys %{$omap}) {
- # SYSMON_Log($hash, 5, ">>>>>>>>>>>>>>>>>>>> ".$aName."->".Dumper($defs{$name}{READINGS}{$aName}));
- delete $defs{$name}{READINGS}{$aName};
- }
- readingsEndUpdate($hash,defined($hash->{LOCAL}) ? 0 : 1);
- }
- sub SYSMON_obtainParameters($$) {
- my ($hash, $refresh_all) = @_;
-
- my $name = $hash->{NAME};
- # ---
- #TODO: SSH
- my $msg = undef;
- my $openedTelnet = 0;
- my $telnet = $hash->{".telnet"};
- #$telnet = undef;
- my $mode = $hash->{MODE};
- # Wenn remote: open connection
- if ($mode eq 'telnet') {
- unless (defined $telnet) {
- SYSMON_Log($hash, 5, "$name: Open shared telnet connection");
- $msg = SYSMON_Open_Connection($hash);
- $hash->{helper}{error_msg}=$msg;
- if (!$msg) {
- $openedTelnet = 1;
- $hash->{helper}{error_msg}=undef;
- }
- }
- }
- # ---
-
- my $map;
- if (!$msg) {
- $map = SYSMON_obtainParameters_intern($hash, $refresh_all);
- }
-
- # ---
- # Wenn remote: close connection
- if ($mode eq 'telnet') {
- if($openedTelnet) {
- SYSMON_Log($hash, 5, "$name: Close shared telnet connection");
- SYSMON_Close_Connection( $hash );
- }
- }
- # ---
-
- return $map;
- }
- # Schattenmap mit den zuletzt gesammelten Werten (merged)
- #my %shadow_map;
- sub
- SYSMON_obtainParameters_intern($$)
- {
- my ($hash, $refresh_all) = @_;
- my $name = $hash->{NAME};
- my $map;
- my $base=$DEFAULT_INTERVAL_BASE;
- my $im = "1 1 1 10";
- # Wenn wesentliche Parameter nicht definiert sind, soll aktualisierung immer vorgenommen werden
- if((defined $hash->{INTERVAL_BASE})) {
- $base = $hash->{INTERVAL_BASE};
- }
- if((defined $hash->{INTERVAL_MULTIPLIERS})) {
- $im = $hash->{INTERVAL_MULTIPLIERS};
- }
- my $ref = int(time()/$base);
- my ($m1, $m2, $m3, $m4) = split(/\s+/, $im);
-
- my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- # Einmaliges
- if(!$hash->{helper}{u_first_mark}) {
- # nur lokal abfragen (macht remote keinen Sinn)
- if ($mode eq 'local') {
- # Perl version
- $map->{+PERL_VERSION} = "$^V";
- }
-
- if(SYSMON_isProcFS($hash)) {
- $map = SYSMON_getCPUInfo($hash, $map);
- }
-
- if(SYSMON_isFB($hash)) {
- $map = SYSMON_FBVersionInfo($hash, $map);
- }
- }
- # immer aktualisieren: uptime, uptime_text, fhemuptime, fhemuptime_text, idletime, idletime_text
- if(SYSMON_isProcFS($hash)) {
- $map = SYSMON_getUptime($hash, $map);
- } else {
- $map = SYSMON_getUptime2($hash, $map);
- }
-
- # nur lokal abfragen
- if ($mode eq 'local') {
- $map = SYSMON_getFHEMUptime($hash, $map);
- }
- if($m1 gt 0) { # Nur wenn > 0
- # M1: cpu_freq, cpu_temp, cpu_temp_avg, loadavg, procstat, iostat
- if($refresh_all || ($ref % $m1) eq 0) {
-
- $map = SYSMON_getCPUCoreNum($hash, $map);
-
- #Log 3, "SYSMON -----------> DEBUG: read CPU-Temp";
- if(SYSMON_isCPUTempRPi($hash)) { # Rasp
- $map = SYSMON_getCPUTemp_RPi($hash, $map);
- }
- if (SYSMON_isCPUTempBBB($hash)) {
- $map = SYSMON_getCPUTemp_BBB($hash, $map);
- }
- foreach my $li (0..7) {
- if(SYSMON_isCPUTemp_X($hash, $li)) {
- $map = SYSMON_getCPUTemp_X($hash, $map, $li);
- }
- }
- if (SYSMON_isCPUTempFB($hash)) {
- $map = SYSMON_getCPUTemp_FB($hash, $map);
- }
- #if(SYSMON_isCPUFreqRPiBBB($hash)) {
- # $map = SYSMON_getCPUFreq($hash, $map, 0);
- #}
- foreach my $li (0..7) {
- if(SYSMON_isCPUXFreq($hash, $li)) {
- $map = SYSMON_getCPUFreq($hash, $map, $li);
- }
- }
- if(SYSMON_isProcFS($hash)) {
- $map = SYSMON_getLoadAvg($hash, $map);
- $map = SYSMON_getCPUProcStat($hash, $map);
- } else {
- #TODO: Ohne ProcFS
- }
- #$map = SYSMON_getDiskStat($hash, $map);
-
- # Power info (cubietruck)
- if(SYSMON_isSysPowerAc($hash)) {
- $map = SYSMON_PowerAcInfo($hash, $map);
- }
- if(SYSMON_isSysPowerUsb($hash)) {
- $map = SYSMON_PowerUsbInfo($hash, $map);
- }
- if(SYSMON_isSysPowerBat($hash)) {
- $map = SYSMON_PowerBatInfo($hash, $map);
- }
- }
- }
- if($m2 gt 0) { # Nur wenn > 0
- # M2: ram, swap
- if($refresh_all || ($ref % $m2) eq 0) {
- if(SYSMON_isOSX()){
- $map = SYSMON_getRamAndSwapOSX($hash, $map);
- } else {
- $map = SYSMON_getRamAndSwap($hash, $map);
- }
- }
- }
- if($m3 gt 0) { # Nur wenn > 0
- # M3: eth0, eth0_diff, wlan0, wlan0_diff, wlan_on (FritzBox)
- my $update_ns = ($refresh_all || ($ref % $m3) eq 0);
- #if($refresh_all || ($ref % $m3) eq 0) {
- my $networks = AttrVal($name, "network-interfaces", undef);
- if($update_ns) {
- if(defined $networks) {
- my @networks_list = split(/,\s*/, trim($networks));
- foreach (@networks_list) {
- $map = SYSMON_getNetworkInfo($hash, $map, $_);
- }
- } else {
- # Wenn nichts definiert, werden Default-Werte verwendet
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>>>>>>>>>> NETWORK";
- if(SYSMON_isFB($hash)) {
- $map = SYSMON_getNetworkInfo($hash, $map, "ath0");
- $map = SYSMON_getNetworkInfo($hash, $map, "ath1");
- $map = SYSMON_getNetworkInfo($hash, $map, "cpmac0");
- $map = SYSMON_getNetworkInfo($hash, $map, "dsl");
- $map = SYSMON_getNetworkInfo($hash, $map, "eth0");
- $map = SYSMON_getNetworkInfo($hash, $map, "guest");
- $map = SYSMON_getNetworkInfo($hash, $map, "hotspot");
- $map = SYSMON_getNetworkInfo($hash, $map, "lan");
- $map = SYSMON_getNetworkInfo($hash, $map, "vdsl");
- } else {
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>>>>>>>>>> ".ETH0;
- $map = SYSMON_getNetworkInfo($hash, $map, ETH0);
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>>>>>>>>>> ".$map->{+ETH0};
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>>>>>>>>>> ".WLAN0;
- $map = SYSMON_getNetworkInfo($hash, $map, WLAN0);
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>>>>>>>>>> ".$map->{+WLAN0};
- }
- }
- if(SYSMON_isFB($hash)) {
- $map = SYSMON_getFBWLANState($hash, $map);
- $map = SYSMON_getFBWLANGuestState($hash, $map);
- $map = SYSMON_getFBInetIP($hash, $map);
- $map = SYSMON_getFBInetConnectionState($hash, $map);
- $map = SYSMON_getFBNightTimeControl($hash, $map);
- $map = SYSMON_getFBNumNewMessages($hash, $map);
- $map = SYSMON_getFBDECTTemp($hash, $map);
-
- #DSL-Downstream und DSL-Upstream abfragen
- $map = SYSMON_getFBStreamRate($hash, $map);
- #Sync-Zeit mit Vermittlungsstelle abfragen
- $map = SYSMON_getFBSyncTime($hash, $map);
- #Uebertragungsfehler abfragen (nicht behebbar und behebbar)
- $map = SYSMON_getFBCRCFEC($hash, $map);
- }
- }
- }
-
- if($m4 gt 0) { # Nur wenn > 0
- # M4: Filesystem-Informationen
- my $update_fs = ($refresh_all || ($ref % $m4) eq 0);
- my $filesystems = AttrVal($name, "filesystems", undef);
- if($update_fs) {
- if(defined $filesystems)
- {
- my @filesystem_list = split(/,\s*/, trim($filesystems));
- foreach (@filesystem_list)
- {
- $map = SYSMON_getFileSystemInfo($hash, $map, $_);
- }
- } else {
- $map = SYSMON_getFileSystemInfo($hash, $map, "root:/");
- }
- } else {
- # Workaround: Damit die Readings zw. den Update-Punkten nicht geloescht werden, werden die Schluessel leer angelegt
- # Wenn noch keine Update notwendig, dan einfach alte Schluessel (mit undef als Wert) angeben,
- # damit werden die Readings in der Update-Methode nicht geloescht.
- # Die ggf. notwendige Loeschung findet nur bei tatsaechlichen Update statt.
- my @cKeys=keys (%{$defs{$name}{READINGS}});
- foreach my $aName (@cKeys) {
- #if(defined ($aName) && (index($aName, FS_PREFIX) == 0 || index($aName, FS_PREFIX_N) == 0)) {
- if(defined ($aName) && (index($aName, FS_PREFIX) == 0 )) {
- $map->{$aName} = undef;
- }
- }
- }
- }
-
- #Log 3, "SYSMON >>> USER_DEFINED >>>>>>>>>>>>>>> START";
- my $userdefined = AttrVal($name, "user-defined", undef);
- if(defined $userdefined) {
- my @userdefined_list = split(/,\s*/, trim($userdefined));
- foreach (@userdefined_list) {
- # <readingName>:<Interval_Minutes>:<Comment>:<Cmd>
- my $ud = $_;
- my($uName, $uInterval, $uComment, $uCmd) = split(/:/, $ud);
- SYSMON_Log($hash, 5, "User-Defined Reading: [$uName][$uInterval][$uComment][$uCmd]");
- if(defined $uCmd) { # Also, wenn alle Parameter vorhanden
- my $iInt = int($uInterval);
- if($iInt>0) {
- my $update_ud = ($refresh_all || ($ref % $iInt) eq 0);
- if($update_ud) {
- $map = SYSMON_getUserDefined($hash, $map, $uName, $uCmd);
- } else {
- SYSMON_Log($hash, 5, "User-Defined Reading: [$uName][$uInterval][$uComment][$uCmd] out of refresh interval");
- }
- }
- }
- }
- }
-
- #Log 3, "SYSMON >>> USER_DEFINED FUNCTIONS >>>>>>>>>>>>>>> START";
- my $userfn = AttrVal($name, "user-fn", undef);
- if(defined $userfn) {
- my @userfn_list = split(/,\s+/, trim($userfn));
- foreach my $ud (@userfn_list) {
- # <fnName>:<Interval_Minutes>:<reading1>:<reading2>..., [<fn-name>:...]
- my($fnName, $uInterval, @readings) = split(/:/, $ud);
- SYSMON_Log($hash, 5, "User-Defined Fn: [$fnName][$uInterval]");
- if(defined $uInterval) {
- my $iInt = int($uInterval);
- if($iInt>0) {
- my $update_ud = ($refresh_all || ($ref % $iInt) eq 0);
- if($update_ud) {
- $map = SYSMON_getUserDefinedFn($hash, $map, $fnName, @readings);
- } else {
- SYSMON_Log($hash, 5, "User-Defined Fn: [$fnName][$uInterval] out of refresh interval");
- }
- }
- }
- }
- }
-
- # User Functions2
- my $uMap;
- $userfn = AttrVal($name, "user-fn2", undef);
- #TEST$userfn=undef;
- if(defined $userfn) {
- my @userfn_list = split(/,\s*/, trim($userfn));
- foreach (@userfn_list) {
- my $ufn = $_;
- SYSMON_Log($hash, 5, "User-Function Reading: [$ufn]");
- if(defined $ufn) {
- no strict "refs";
- $uMap = &{$ufn}($hash, $uMap);
- use strict "refs";
- }
- }
- }
- # Werte umverpacken, KeyNamen sichern
- my $uNames='';
- if(defined($uMap)) {
- foreach my $uName (keys %{$uMap}) {
- $uNames.=','.$uName;
- $map->{$uName}=$uMap->{$uName};
- }
- # Erste Komma entfernen
- $uNames=substr($uNames,1);
- $map->{"xuser_fnr"}=$uNames;
- }
-
- #TEST
- #my $rt = "#";
- #$rt=~s/#/[]/g;
- #$map->{SYS_TEST}=$rt;
-
- if(defined($map)) {
- # Aktuelle Werte in ShattenHash mergen
- my %hashT = %{$map};
- #@shadow_map{ keys %hashT } = values %hashT;
- my %shadow_map;
- @shadow_map{ keys %hashT } = values %hashT;
- $hash->{helper}{shadow_map} = \%shadow_map;
- }
- return $map;
- }
- # For test purpose only
- sub SYSMON_TestUserFn($$) {
- my ($hash, $map) = @_;
-
- $map->{"my_test_reading"}="my test";
- #$map->{"my"}="my";
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert gesammelte Werte ( = Readings)
- # Parameter: array der gewuenschten keys (Readings names)
- # Beispiele:
- # {(SYSMON_getValues("sysmon"))->{'cpu_temp'}}
- # {(SYSMON_getValues("sysmon",("cpu_freq","cpu_temp")))->{"cpu_temp"}}
- # {join(" ", values (SYSMON_getValues("sysmon")))}
- # {join(" ", values (SYSMON_getValues("sysmon",("cpu_freq","cpu_temp"))))}
- #------------------------------------------------------------------------------
- sub
- SYSMON_getValues($;@)
- {
- my ($name,@filter_keys) = @_;
-
- my $hash = $main::defs{$name};
- my %shadow_map = %{$hash->{helper}{shadow_map}};
- if(scalar(@filter_keys)>0) {
- my %clean_hash;
- #@clean_hash{ @filter_keys } = @shadow_map{ @filter_keys };
- @clean_hash{ @filter_keys } = @shadow_map{ @filter_keys };
- return \%clean_hash;
- }
- # alles liefern
- return \%shadow_map;
- }
- sub SYSMON_getComputeStat($$$$) {
- my ($hash, $map, $val, $name) = @_;
-
- if (defined($val)) {
- my $t = ReadingsVal($hash->{NAME},$name,"$val $val $val");
-
- my($min, $max, $avg) = split(/ /,$t);
- $min = $val if $min>$val;
- $max = $val if $max<$val;
- $avg = (3*$avg + $val)/4;
-
- $t = sprintf( "%.2f %.2f %.2f", $min, $max, $avg );
-
- $map->{$name} = $t;
-
- #SYSMON_Log($hash, 3, ">>>>>>>>>>>>>>>>> ".$name." => $t");
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liest Benutzerdefinierte Eintraege
- #------------------------------------------------------------------------------
- sub
- SYSMON_getUserDefined($$$$)
- {
- my ($hash, $map, $uName, $uCmd) = @_;
- SYSMON_Log($hash, 5, "Name=[$uName] Cmd=[$uCmd]");
-
- if($hash->{helper}->{excludes}{'user-defined'}) {return $map;}
-
- my @out_arr = SYSMON_execute($hash, $uCmd);
-
- my $out_str = "";
- foreach my $k (@out_arr) {
- if(defined($k)) {
- chomp($k);
- $out_str.=$k." ";
- }
- }
- #my $out_str = join(" ",@out_arr);
- ##my $out_str = SYSMON_execute($hash, $uCmd);
- ##chomp $out_str;
- #$out_str=~s/\n/ /g;
- #$out_str=~s/\r/ /g;
- $map->{$uName} = $out_str;
- SYSMON_Log($hash, 5, "User-Defined Result: $uName='$out_str'");
-
- return $map;
- }
- sub SYSMON_getUserDefinedFn($$$@) {
- my($hash, $map, $fnName, @readings) = @_;
-
- #SYSMON_Log($hash, 3, ">>>>>>>>>>>>>>>>>>>>> exclude: ".Dumper($hash->{helper}->{excludes}));
- if($hash->{helper}->{excludes}{'user-defined'}) {return $map;}
-
- SYSMON_Log($hash, 5, "call User-Function: [$fnName]");
- if(defined $fnName) {
- no strict "refs";
- my @rarr;
- if($fnName=~/^{/) {
- my $HASH = $hash;
- my $NAME = $hash->{NAME};
- @rarr = eval($fnName);
- } else {
- @rarr = &{$fnName}($hash);
- }
- use strict "refs";
- SYSMON_Log($hash, 5, "result User-Function [$fnName]: ".Dumper(@rarr));
-
- my $cnt1 = scalar(@readings);
- my $cnt2 = scalar(@rarr);
- my $cnt = min($cnt1,$cnt2);
- if($cnt1!=$cnt2) { # zu wenig readings geliefert ($cnt1>$cnt2) oder zu viel
- SYSMON_Log($hash, 3, "User-Function [$fnName]: expected readings: [$cnt1], provided [$cnt2]");
- }
- #SYSMON_Log($hash, 5, ">>>> User-Function [$fnName]: $cnt1 / $cnt2: $rarr[0]");
- for (my $i=0;$i<$cnt;$i++) {
- if(defined($rarr[$i])) {
- my $val = trim($rarr[$i]);
- #SYSMON_Log($hash, 5, ">>>> User-Function [$fnName]: put: '".$readings[$i]."' => '".$val."'");
- $map->{$readings[$i]} = $val;
- #$map->{$readings[$i]}="Dead OWTHERM devices: none";
- #SYSMON_Log($hash, 5, ">>>> User-Function [$fnName]: ok");
- }
- }
- }
-
- return $map;
- }
- #my $sys_cpu_core_num = undef;
- sub
- SYSMON_getCPUCoreNum_intern($) {
- my ($hash) = @_;
-
- return $hash->{helper}{sys_cpu_core_num} if $hash->{helper}{sys_cpu_core_num};
-
- # TODO: Umstellung auf
- # cat /sys/devices/system/cpu/present
- # cat /sys/devices/system/cpu/online
-
- # nur wenn verfuegbar
- if(SYSMON_isSysCpuNum($hash)) {
- my $str = SYSMON_execute($hash, "cat /sys/devices/system/cpu/kernel_max");
- if(defined($str)) {
- if($str ne "") {
- if(int($str)!=0) {
- $hash->{helper}{sys_cpu_core_num} = int($str)+1;
- return $hash->{helper}{sys_cpu_core_num};
- }
- }
- }
- }
-
- # Default / unbekannt
- $hash->{helper}{sys_cpu_core_num} = 1;
- return $hash->{helper}{sys_cpu_core_num};
- }
- #------------------------------------------------------------------------------
- # leifert Anzahl CPU Kerne
- #------------------------------------------------------------------------------
- sub SYSMON_getCPUCoreNum($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cpucount'}) {return $map;}
-
- my $cpuCoreCnt = SYSMON_getCPUCoreNum_intern($hash);
- $map->{+CPU_CORE_CNT}=$cpuCoreCnt;
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert Zeit seit dem Systemstart
- #------------------------------------------------------------------------------
- sub
- SYSMON_getUptime($$)
- {
- my ($hash, $map) = @_;
- if($hash->{helper}->{excludes}{'uptime'}) {return $map;}
- #my $uptime_str = qx(cat /proc/uptime );
- my $uptime_str = SYSMON_execute($hash, "cat /proc/uptime");
- if(defined($uptime_str)) {
- my ($uptime, $idle) = split(/\s+/, trim($uptime_str));
- #postfux use idle from /proc/stat instead
- my $stat_str = SYSMON_execute($hash, "cat /proc/stat|grep 'cpu '");
- my($tName, $neuCPUuser, $neuCPUnice, $neuCPUsystem, $neuCPUidle, $neuCPUiowait, $neuCPUirq, $neuCPUsoftirq) = split(/\s+/, trim($stat_str));
- if(defined($neuCPUidle)){
- $idle=$neuCPUidle/100;
- }
- #postfux
- if(defined($uptime) && int($uptime)!=0) {
- # Anzahl Cores beruecksichtigen
- my $core_num = SYSMON_getCPUCoreNum_intern($hash);
- my $idle_percent = $idle/($uptime*$core_num)*100;
-
- $idle = $idle/$core_num;
- $map->{+UPTIME}=sprintf("%d",$uptime);
- #$map->{+UPTIME_TEXT} = sprintf("%d days, %02d hours, %02d minutes, %02d seconds",SYSMON_decode_time_diff($uptime));
- $map->{+UPTIME_TEXT} = sprintf("%d days, %02d hours, %02d minutes",SYSMON_decode_time_diff($uptime));
-
- my $startTime = time()-$uptime;
- $map->{+STARTTIME} = sprintf("%d",$startTime);
- $map->{+STARTTIME_TEXT} = strftime("%d.%m.%Y %H:%M:%S", localtime($startTime));
-
- $map->{+IDLETIME}=sprintf("%d %.2f %%",$idle, $idle_percent);
- $map->{+IDLETIME_TEXT} = sprintf("%d days, %02d hours, %02d minutes",SYSMON_decode_time_diff($idle)).sprintf(" (%.2f %%)",$idle_percent);
- #$map->{+IDLETIME_PERCENT} = sprintf ("%.2f %",$idle_percent);
- }
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert Zeit seit dem Systemstart.
- # Alternative Version fuer Systemen ohne procfs (z.B. MACOS)
- #------------------------------------------------------------------------------
- sub
- SYSMON_getUptime2($$)
- {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'uptime'}) {return $map;}
- #TODO
- my $uptime = SYSMON_execute($hash,"uptime");
- if(defined($uptime)){
- #SYSMON_Log($hash, 5, ">>>>>>>>>>>>>>>>>>>>>>".$uptime."<");
-
- #$uptime = $1 if( $uptime && $uptime =~ m/[[:alpha:]]{2}\s+(((\d+)\D+,?\s+)?(\d+):(\d+))/ );
- $uptime = $1 if( $uptime && $uptime =~ m/[[:alpha:]]{2}\s+(((\d+)\D+,?\s+)?(\d+):(\d+)).*load.*: (.*)/ );
- $uptime = "0 days, $uptime" if( $uptime && !$2);
-
-
- my $days = $3?$3:0;
- my $hours = $4;
- my $minutes = $5;
-
- if(defined($days) && defined($hours) && defined($minutes)) {
- $uptime = $days * 24;
- $uptime += $hours;
- $uptime *= 60;
- $uptime += $minutes;
- $uptime *= 60;
- } else {
- $uptime = 0;
- }
-
- $map->{+UPTIME}=sprintf("%d",$uptime);
- $map->{+UPTIME_TEXT} = sprintf("%d days, %02d hours, %02d minutes",SYSMON_decode_time_diff($uptime));
-
- my $startTime = time()-$uptime;
- $map->{+STARTTIME} = sprintf("%d",$startTime);
- $map->{+STARTTIME_TEXT} = strftime("%d.%m.%Y %H:%M:%S", localtime($startTime));
-
- my $loadavg=$6;
- if(defined($loadavg)) {
- my ($la1, $la5, $la15, $prc, $lastpid) = split(/\s+/, trim($loadavg));
- if(defined($la1) && defined($la5) && defined($la15)) {
- $la1 =~ s/,$//;
- $la5 =~ s/,$//;
- $la1 =~ s/,/./;
- $la5 =~ s/,/./;
- $la15 =~ s/,/./;
- $map->{+LOADAVG}="$la1 $la5 $la15";
- }
- }
- }
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert Zeit seit FHEM-Start
- #------------------------------------------------------------------------------
- sub
- SYSMON_getFHEMUptime($$)
- {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fhemuptime'}) {return $map;}
- #if(defined ($hash->{DEF_TIME})) {
- if(defined($fhem_started)) {
- #my $fhemuptime = time()-$hash->{DEF_TIME};
- my $fhemuptime = time()-$fhem_started;
- $map->{+FHEMUPTIME} = sprintf("%d",$fhemuptime);
- $map->{+FHEMUPTIME_TEXT} = sprintf("%d days, %02d hours, %02d minutes",SYSMON_decode_time_diff($fhemuptime));
-
- my $startTime = time()-$fhemuptime;
- $map->{+FHEMSTARTTIME} = sprintf("%d",$startTime);
- $map->{+FHEMSTARTTIME_TEXT} = strftime("%d.%m.%Y %H:%M:%S", localtime($startTime));
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU-Auslastung
- #------------------------------------------------------------------------------
- sub
- SYSMON_getLoadAvg($$)
- {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'loadavg'}) {return $map;}
- my $la_str = SYSMON_execute($hash, "cat /proc/loadavg");
- if(defined($la_str)) {
- my ($la1, $la5, $la15, $prc, $lastpid) = split(/\s+/, trim($la_str));
- if(defined($la1) && defined($la5) && defined($la15)) {
- $map->{+LOADAVG}="$la1 $la5 $la15";
- #$map->{"load"}="$la1";
- #$map->{"load5"}="$la5";
- #$map->{"load15"}="$la15";
- }
- }
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # liefert CPU Temperature (Raspberry Pi)
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUTemp_RPi($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cputemp'}) {return $map;}
-
- my $val = SYSMON_execute($hash, "cat /sys/class/thermal/thermal_zone0/temp 2>&1");
- $val = int($val);
- if($val>1000) { # Manche Systeme scheinen die Daten verschieden zu skalieren (z.B. utilite)...
- $val = $val/1000;
- }
- my $val_txt = sprintf("%.2f", $val);
- $map->{+CPU_TEMP}="$val_txt";
- my $t_avg = sprintf( "%.1f", (3 * ReadingsVal($hash->{NAME},CPU_TEMP_AVG,$val_txt) + $val_txt ) / 4 );
- $map->{+CPU_TEMP_AVG}="$t_avg";
-
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, CPU_TEMP."_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Temperature (BeagleBone Black)
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUTemp_BBB($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cputemp'}) {return $map;}
-
- my $val = SYSMON_execute($hash, "cat /sys/class/hwmon/hwmon0/device/temp1_input 2>&1");
- if(!looks_like_number($val)) {return $map;}
-
- $val = int($val);
- if ($val > 200) {
- $val = $val / 1000;
- }
- my $val_txt = sprintf("%.2f", $val);
- $map->{+CPU_TEMP}="$val_txt";
- $map->{"cpu0_temp"}="$val_txt";
- my $t_avg = sprintf( "%.1f", (3 * ReadingsVal($hash->{NAME},CPU_TEMP_AVG,$val_txt) + $val_txt ) / 4 );
- $map->{+CPU_TEMP_AVG}=$t_avg;
- $t_avg = sprintf( "%.1f", (3 * ReadingsVal($hash->{NAME},"cpu0_temp_avg",$val_txt) + $val_txt ) / 4 );
- $map->{"cpu0_temp_avg"}=$t_avg;
-
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, CPU_TEMP."_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Temperature (mehrere Kerne eines ?)
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUTemp_X($$;$) {
- my ($hash, $map, $cpuNum) = @_;
-
- if($hash->{helper}->{excludes}{'cputemp'}) {return $map;}
-
- $cpuNum = 0 unless defined $cpuNum;
-
- my $val = SYSMON_execute($hash, "cat /sys/class/hwmon/hwmon0/device/hwmon/hwmon0/temp".($cpuNum+1)."_input 2>&1");
- $val = int($val);
- my $val_txt = sprintf("%.2f", $val/1000);
- $map->{"cpu".$cpuNum."_temp"}="$val_txt";
- my $t_avg = sprintf( "%.1f", (3 * ReadingsVal($hash->{NAME},"cpu".$cpuNum."_temp_avg",$val_txt) + $val_txt ) / 4 );
- $map->{"cpu".$cpuNum."_temp_avg"}=$t_avg;
-
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, "cpu".$cpuNum."_temp"."_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Temperature (FritzBox)
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUTemp_FB($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cputemp'}) {return $map;}
-
- my $val = SYSMON_execute($hash, "ctlmgr_ctl r cpu status/StatTemperature");
- if(defined($val)) {
- if($val=~m/(\d+),/) {
- my $fval = $1;
- my $val_txt = sprintf("%.2f", $fval);
- $map->{+CPU_TEMP}="$val_txt";
- my $t_avg = sprintf( "%.1f", (3 * ReadingsVal($hash->{NAME},CPU_TEMP_AVG,$val_txt) + $val_txt ) / 4 );
- $map->{+CPU_TEMP_AVG}="$t_avg";
-
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, CPU_TEMP."_stat");
-
- }
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Frequenz (Raspberry Pi, BeagleBone Black, Cubietruck, etc.)
- # Sonderlocke fuer lokale Erfassung (damit die CPU nicht auf Max. gefahren wird)
- # Dazu darf nicht in BlockingCall und keine System-Aufrufe wie 'cat' etc.
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUFreqLocal($$;$) {
- my ($hash, $map, $cpuNum) = @_;
-
- if($hash->{helper}->{excludes}{'cpufreq'}) {return $map;}
-
- $cpuNum = 0 unless defined $cpuNum;
-
- my $val;
- if(open(my $fh, '<', "/sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq")) {
- $val = <$fh>;
- close($fh);
- }
-
- $val = int($val);
- my $val_txt = sprintf("%d", $val/1000);
- if($cpuNum == 0) {
- # aus Kompatibilitaetsgruenden
- $map->{+CPU_FREQ}="$val_txt";
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, CPU_FREQ."_stat");
- }
-
- $map->{"cpu".$cpuNum."_freq"}="$val_txt";
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, "cpu".$cpuNum."_freq"."_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Frequenz (Raspberry Pi, BeagleBone Black, Cubietruck, etc.)
- # Nur Remote Aufrufe
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUFreq($$;$) {
- my ($hash, $map, $cpuNum) = @_;
-
- if($hash->{helper}->{excludes}{'cpufreq'}) {return $map;}
-
- $cpuNum = 0 unless defined $cpuNum;
-
- my $val;
-
- my $mode = $hash->{MODE};
- if ($mode eq 'local') {
- # do nothing
- return $map;
- }
- # XXX Hack: Versuch zu vermeiden, dass Frequenz immer als Maximum gelesen wird
- #my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- #if ($mode eq 'local') {
- # if(open(my $fh, '<', "/sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq")) {
- # $val = <$fh>;
- # close($fh);
- # }
- #} else {
- $val = SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq ] && cat /sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq 2>&1 || echo 0");
- #}
-
- $val = int($val);
- my $val_txt = sprintf("%d", $val/1000);
- if($cpuNum == 0) {
- # aus Kompatibilitaetsgruenden
- $map->{+CPU_FREQ}="$val_txt";
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, CPU_FREQ."_stat");
- }
-
- $map->{"cpu".$cpuNum."_freq"}="$val_txt";
- $map = SYSMON_getComputeStat($hash, $map, $val_txt, "cpu".$cpuNum."_freq"."_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert CPU Frequenz fuer 2te CPU (Cubietruck, etc.)
- #------------------------------------------------------------------------------
- #sub
- #SYSMON_getCPU1Freq($$)
- #{
- # my ($hash, $map) = @_;
- # my $val = SYSMON_execute($hash, "cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq 2>&1");
- # $val = int($val);
- # my $val_txt = sprintf("%d", $val/1000);
- # $map->{+CPU1_FREQ}="$val_txt";
- # return $map;
- #}
- #------------------------------------------------------------------------------
- # leifert CPU Infos (Model name & Speed in BogoMIPS)
- # TEST: {Dumper(SYSMON_getCPUInfo($defs{sysmon},undef))}
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUInfo($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cpuinfo'}) {return $map;}
-
- my $old_val1 = ReadingsVal($hash->{NAME},CPU_BOGOMIPS,undef);
- my $old_val2 = ReadingsVal($hash->{NAME},CPU_MODEL_NAME,undef);
- # nur einmalig ermitteln (wird sich ja nicht aendern
- if(!defined($old_val1) || !defined($old_val2)) {
- #my @aval = SYSMON_execute($hash, "cat /proc/cpuinfo | grep 'BogoMIPS'");
- my @aval = SYSMON_execute($hash, "cat /proc/cpuinfo");
- foreach my $line (@aval) {
- my($key, $val) = split(/\s*:\s+/, $line);
- if(defined($key)) {
- if($key=~m/Processor/ || $key=~m/model name/ || $key=~m/system type/) {
- if($val) {
- $val = trim($val);
- $map->{+CPU_MODEL_NAME}=$val;
- }
- } elsif ($key=~m/BogoMIPS/) {
- if($val) {
- $val = trim($val);
- $map->{+CPU_BOGOMIPS}=$val;
- }
- }
- }
- }
- } else {
- $map->{+CPU_BOGOMIPS}=$old_val1;
- $map->{+CPU_MODEL_NAME}=$old_val2;
- }
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert Werte aus /proc/diskstat
- # Werte:
- # 1 - major number
- # 2 - minor mumber
- # 3 - device name
- # Dann Datenwerte:
- # Field 1 -- # of reads issued
- # Field 2 -- # of reads merged
- # Field 3 -- # of sectors read
- # Field 4 -- # of milliseconds spent reading
- # Field 5 -- # of writes completed
- # Field 6 -- # of writes merged
- # Field 7 -- # of sectors written
- # Field 8 -- # of milliseconds spent writing
- # Field 9 -- # of I/Os currently in progress
- # Field 10 -- # of milliseconds spent doing I/Os
- # Field 11 -- weighted # of milliseconds spent doing I/Os
- # Interessant sind eigentlich "nur" Feld 2 (readin), Feld 5 (write)
- # Wenn es eher "um die zeit" geht, Feld 4 (reading), Feld 8 (writing), Feld 10 (Komplett)
- # Kleiner Hinweis, Fled 1 ist das 4. der Liste, das 3. Giebt den Namen an.
- # Es giebt fuer jedes Devine und jede Partition ein Eintrag.
- # A /proc/diskstats continuously updated and all that is necessary for us -
- # make measurements for "second field" and "fourth field" in two different moment of time,
- # receiving a difference of values and dividing it into an interval of time,
- # we shall have Disk I/O stats in sectors/sec. Multiply this result on 512 (number of bytes in one sector)
- # we shall have Disk I/O stats in bytes/sec.
- #
- # ...
- # https://www.kernel.org/doc/Documentation/iostats.txt
- # Field 1 -- # of reads completed
- # This is the total number of reads completed successfully.
- # Field 2 -- # of reads merged, field 6 -- # of writes merged
- # Reads and writes which are adjacent to each other may be merged for
- # efficiency. Thus two 4K reads may become one 8K read before it is
- # ultimately handed to the disk, and so it will be counted (and queued)
- # as only one I/O. This field lets you know how often this was done.
- # Field 3 -- # of sectors read
- # This is the total number of sectors read successfully.
- # Field 4 -- # of milliseconds spent reading
- # This is the total number of milliseconds spent by all reads (as
- # measured from __make_request() to end_that_request_last()).
- # Field 5 -- # of writes completed
- # This is the total number of writes completed successfully.
- # Field 6 -- # of writes merged
- # See the description of field 2.
- # Field 7 -- # of sectors written
- # This is the total number of sectors written successfully.
- # Field 8 -- # of milliseconds spent writing
- # This is the total number of milliseconds spent by all writes (as
- # measured from __make_request() to end_that_request_last()).
- # Field 9 -- # of I/Os currently in progress
- # The only field that should go to zero. Incremented as requests are
- # given to appropriate struct request_queue and decremented as they finish.
- # Field 10 -- # of milliseconds spent doing I/Os
- # This field increases so long as field 9 is nonzero.
- # Field 11 -- weighted # of milliseconds spent doing I/Os
- # This field is incremented at each I/O start, I/O completion, I/O
- # merge, or read of these stats by the number of I/Os in progress
- # (field 9) times the number of milliseconds spent doing I/O since the
- # last update of this field. This can provide an easy measure of both
- # I/O completion time and the backlog that may be accumulating.
- #
- #
- # Disks vs Partitions
- # -------------------
- #
- # There were significant changes between 2.4 and 2.6 in the I/O subsystem.
- # As a result, some statistic information disappeared. The translation from
- # a disk address relative to a partition to the disk address relative to
- # the host disk happens much earlier. All merges and timings now happen
- # at the disk level rather than at both the disk and partition level as
- # in 2.4. Consequently, you'll see a different statistics output on 2.6 for
- # partitions from that for disks. There are only *four* fields available
- # for partitions on 2.6 machines. This is reflected in the examples above.
- #
- # Field 1 -- # of reads issued
- # This is the total number of reads issued to this partition.
- # Field 2 -- # of sectors read
- # This is the total number of sectors requested to be read from this
- # partition.
- # Field 3 -- # of writes issued
- # This is the total number of writes issued to this partition.
- # Field 4 -- # of sectors written
- # This is the total number of sectors requested to be written to
- # this partition.
- #------------------------------------------------------------------------------
- sub SYSMON_getDiskStat($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'diskstat'}) {return $map;}
-
- my @values = SYSMON_execute($hash, "cat /proc/diskstats");
- for my $entry (@values){
- $map = SYSMON_getDiskStat_intern($hash, $map, $entry);
- #Log 3, "SYSMON-DEBUG-IOSTAT: ".$entry;
- }
- return $map;
- }
- sub
- SYSMON_getDiskStat_intern($$$)
- {
- my ($hash, $map, $entry) = @_;
-
- my ($d1, $d2, $pName, $nf1, $nf2, $nf3, $nf4, $nf5, $nf6, $nf7, $nf8, $nf9, $nf10, $nf11) = split(/\s+/, trim($entry));
-
- SYSMON_Log($hash, 5, "SYSMON-DEBUG-IOSTAT: ".$pName." = ".$nf1." ".$nf2." ".$nf3." ".$nf4." ".$nf5." ".$nf6." ".$nf7." ".$nf8." ".$nf9." ".$nf10." ".$nf11);
-
- # Nur nicht-null-Werte
- if($nf1 eq "0") {
- return $map;
- }
-
- $pName = "io_".$pName;
- #Log 3, "SYSMON-DEBUG-IOSTAT: ".$pName;
-
- # Partition and 2.6-Kernel?
- if(defined($nf5)) {
- # no
- $map->{$pName."_raw"}=$nf1." ".$nf2." ".$nf3." ".$nf4." ".$nf5." ".$nf6." ".$nf7." ".$nf8." ".$nf9." ".$nf10." ".$nf11;
- } else {
- $map->{$pName."_raw"}=$nf1." ".$nf2." ".$nf3." ".$nf4;
- }
- #$map->{"iostat_test"}="TEST";
- my $lastVal = ReadingsVal($hash->{NAME},$pName."_raw",undef);
- if(defined($lastVal)) {
- SYSMON_Log($hash,5, "SYSMON-DEBUG-IOSTAT: lastVal: $pName=".$lastVal);
- }
- if(defined $lastVal) {
- # Diff. ausrechnen, falls vorherigen Werte vorhanden sind.
- my($af1, $af2, $af3, $af4, $af5, $af6, $af7, $af8, $af9, $af10, $af11) = split(/\s+/, $lastVal);
-
- SYSMON_Log($hash,5, "SYSMON-DEBUG-IOSTAT: X: ".$pName." = ".$af1." ".$af2." ".$af3." ".$af4." ".$af5." ".$af6." ".$af7." ".$af8." ".$af9." ".$af10." ".$af11);
-
- my $sectorsRead;
- my $sectorsWritten;
-
- my $df1 = $nf1-$af1;
- my $df2 = $nf2-$af2;
- my $df3 = $nf3-$af3;
- my $df4 = $nf4-$af4;
- # Partition and 2.6-Kernel?
- if(defined($nf5)) {
- # no
- my $df5 = $nf5-$af5;
- my $df6 = $nf6-$af6;
- my $df7 = $nf7-$af7;
- my $df8 = $nf8-$af8;
- my $df9 = $nf9-$af9;
- my $df10 = $nf10-$af10;
- my $df11 = $nf11-$af11;
- $map->{$pName."_diff"}=$df1." ".$df2." ".$df3." ".$df4." ".$df5." ".$df6." ".$df7." ".$df8." ".$df9." ".$df10." ".$df11;
-
- $sectorsRead = $df3;
- $sectorsWritten = $df7;
- } else {
- $map->{$pName."_diff"}=$df1." ".$df2." ".$df3." ".$df4;
-
- $sectorsRead = $df2;
- $sectorsWritten = $df4;
- }
-
- my $sectorBytes = 512;
-
- my $BytesRead = $sectorsRead*$sectorBytes;
- my $BytesWritten = $sectorsWritten*$sectorBytes;
-
- # TODO: Summenwerte
- $map->{$pName.""}=sprintf("bytes read: %d bytes written: %d",$BytesRead, $BytesWritten);
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # leifert Werte aus /proc/stat
- # Werte:
- # neuCPUuser, neuCPUnice, neuCPUsystem, neuCPUidle, neuCPUiowait, neuCPUirq, neuCPUsoftirq
- # Differenzberechnung:
- # CPUuser = neuCPUuser - altCPUuser (fuer alle anderen analog)
- # GesammtCPU = CPUuser + CPUnice + CPUsystem + CPUidle + CPUiowait + CPUirq + CPUsoftirq
- # Belastung in %:
- # ProzCPUuser = (CPUuser / GesammtCPU) * 100
- #------------------------------------------------------------------------------
- sub
- SYSMON_getCPUProcStat($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'cpustat'}) {return $map;}
-
- my @values = SYSMON_execute($hash, "cat /proc/stat");
-
- for my $entry (@values){
- if (index($entry, "cpu") < 0){
- last;
- }
- $map = SYSMON_getCPUProcStat_intern($hash, $map, $entry);
- }
-
- # Wenn nur eine CPU vorhanden ist, loeschen Werte fuer CPU0 (nur Gesamt belassen)
- if(!defined($map->{"stat_cpu1"})){
- delete $map->{"stat_cpu0"};
- delete $map->{"stat_cpu0_diff"};
- delete $map->{"stat_cpu0_percent"};
- }
-
- return $map;
- }
- sub
- SYSMON_getCPUProcStat_intern($$$)
- {
- my ($hash, $map, $entry) = @_;
-
- my($tName, $neuCPUuser, $neuCPUnice, $neuCPUsystem, $neuCPUidle, $neuCPUiowait, $neuCPUirq, $neuCPUsoftirq) = split(/\s+/, trim($entry));
- my $pName = "stat_".$tName;
- $map->{$pName}=$neuCPUuser." ".$neuCPUnice." ".$neuCPUsystem." ".$neuCPUidle." ".$neuCPUiowait." ".$neuCPUirq." ".$neuCPUsoftirq;
-
- my $lastVal = ReadingsVal($hash->{NAME},$pName,undef);
- if(defined $lastVal) {
- # Diff. ausrechnen, falls vorherigen Werte vorhanden sind.
- my($altCPUuser, $altCPUnice, $altCPUsystem, $altCPUidle, $altCPUiowait, $altCPUirq, $altCPUsoftirq) = split(/\s+/, $lastVal);
-
- my ($CPUuser, $CPUnice, $CPUsystem, $CPUidle, $CPUiowait, $CPUirq, $CPUsoftirq);
- if($neuCPUuser < $altCPUuser) {
- $CPUuser = $neuCPUuser;
- $CPUnice = $neuCPUnice;
- $CPUsystem = $neuCPUsystem;
- $CPUidle = $neuCPUidle;
- $CPUiowait = $neuCPUiowait;
- $CPUirq = $neuCPUirq;
- $CPUsoftirq = $neuCPUsoftirq;
- }
- else {
- $CPUuser = $neuCPUuser - $altCPUuser;
- $CPUnice = $neuCPUnice - $altCPUnice;
- $CPUsystem = $neuCPUsystem - $altCPUsystem;
- $CPUidle = $neuCPUidle - $altCPUidle;
- $CPUiowait = $neuCPUiowait - $altCPUiowait;
- $CPUirq = $neuCPUirq - $altCPUirq;
- $CPUsoftirq = $neuCPUsoftirq - $altCPUsoftirq;
- }
-
- $map->{$pName."_diff"}=$CPUuser." ".$CPUnice." ".$CPUsystem." ".$CPUidle." ".$CPUiowait." ".$CPUirq." ".$CPUsoftirq;
-
- my $GesammtCPU = $CPUuser + $CPUnice + $CPUsystem + $CPUidle + $CPUiowait + $CPUirq + $CPUsoftirq;
- my $PercentCPUuser = ($CPUuser / $GesammtCPU) * 100;
- my $PercentCPUnice = ($CPUnice / $GesammtCPU) * 100;
- my $PercentCPUsystem = ($CPUsystem / $GesammtCPU) * 100;
- my $PercentCPUidle = ($CPUidle / $GesammtCPU) * 100;
- my $PercentCPUiowait = ($CPUiowait / $GesammtCPU) * 100;
- my $PercentCPUirq = ($CPUirq / $GesammtCPU) * 100;
- my $PercentCPUsoftirq = ($CPUsoftirq / $GesammtCPU) * 100;
-
- $map->{$pName."_percent"}=sprintf ("%.2f %.2f %.2f %.2f %.2f %.2f %.2f",$PercentCPUuser,$PercentCPUnice,$PercentCPUsystem,$PercentCPUidle,$PercentCPUiowait,$PercentCPUirq,$PercentCPUsoftirq);
- $map->{$pName."_text"}=sprintf ("user: %.2f %%, nice: %.2f %%, sys: %.2f %%, idle: %.2f %%, io: %.2f %%, irq: %.2f %%, sirq: %.2f %%",$PercentCPUuser,$PercentCPUnice,$PercentCPUsystem,$PercentCPUidle,$PercentCPUiowait,$PercentCPUirq,$PercentCPUsoftirq);
-
- $map = SYSMON_getComputeStat($hash, $map, $PercentCPUidle, $tName."_idle_stat");
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Werte fuer RAM und SWAP (Gesamt, Verwendet, Frei).
- #------------------------------------------------------------------------------
- sub SYSMON_getRamAndSwap($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'ramswap'}) {return $map;}
- #my @speicher = qx(free -m);
- #my @speicher = SYSMON_execute($hash, "LANG=en free");
- my $free_version = SYSMON_execute($hash, 'free -V');
- $free_version =~ s/\D//g;
- my @speicher = SYSMON_execute($hash, 'LANG=en ' . ($free_version > 339 ? 'free -w' : 'free'));
- if(!@speicher) {
- return $map;
- }
- shift @speicher;
- my ($fs_desc, $total, $used, $free, $shared, $buffers, $cached);
- if(defined ($speicher[0])) {
- ($fs_desc, $total, $used, $free, $shared, $buffers, $cached) = split(/\s+/, trim($speicher[0]));
- }
-
- shift @speicher;
- my ($fs_desc2, $total2, $used2, $free2, $shared2, $buffers2, $cached2);
-
- if(defined ($speicher[0])) {
- ($fs_desc2, $total2, $used2, $free2, $shared2, $buffers2, $cached2) = split(/\s+/, trim($speicher[0]))
- }
-
- if(defined($fs_desc2)) {
- if($fs_desc2 ne "Swap:") {
- shift @speicher;
- if(defined ($speicher[0])) {
- ($fs_desc2, $total2, $used2, $free2, $shared2, $buffers2, $cached2) = split(/\s+/, trim($speicher[0]));
- }
- }
- }
- my $ram;
- my $swap;
- #my $percentage_ram;
- #my $percentage_swap;
-
- my $used_clean;
-
- if(defined($total) && $total > 0) {
-
- $total = $total / 1024;
- $used = $used / 1024;
- $free = $free / 1024;
- $buffers = $buffers / 1024;
- if(defined($cached)) {
- $cached = $cached / 1024;
- } else {
- # Bei FritzBox wird dieser Wert nicht ausgegeben
- $cached = 0;
- }
- #$used_clean = $used - $buffers - $cached;
- #$ram = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total, $used_clean, ($used_clean / $total * 100), ($free + $buffers + $cached));
- #if ($total > 2048) {
- if ($free_version > 339) {
- $used_clean = $used;
- $ram = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total, $used_clean, ($used_clean / $total * 100), ($free));
- } else {
- $used_clean = $used - $buffers - $cached;
- $ram = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total, $used_clean, ($used_clean / $total * 100), ($free + $buffers + $cached));
- }
- }
- else
- {
- $ram = "n/a";
- }
- $map->{+RAM} = $ram;
-
- $map = SYSMON_getComputeStat($hash, $map, $used_clean, "ram_used_stat");
-
- # wenn kein swap definiert ist, ist die Groesse (total2) gleich Null. Dies wuerde eine Exception (division by zero) ausloesen
- if(defined($total2) && $total2 > 0 && defined($used2) && defined($free2)) {
- $total2 = $total2 / 1024;
- $used2 = $used2 / 1024;
- $free2 = $free2 / 1024;
-
- $swap = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total2, $used2, ($used2 / $total2 * 100), $free2);
- } else {
- $swap = "n/a"
- }
- $map->{+SWAP} = $swap;
- $map = SYSMON_getComputeStat($hash, $map, $used2, "swap_used_stat");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Prueft, ob das Host-System OSX ist (darvin).
- #------------------------------------------------------------------------------
- sub SYSMON_isOSX()
- {
- return $^O eq 'darwin';
- }
- #------------------------------------------------------------------------------
- # Prueft, ob das Host-System Linux ist (linux).
- #------------------------------------------------------------------------------
- sub SYSMON_isLinux()
- {
- return $^O eq 'linux';
- }
- #------------------------------------------------------------------------------
- # Liefert Werte fuer RAM und SWAP (Gesamt, Verwendet, Frei).
- #------------------------------------------------------------------------------
- sub SYSMON_getRamAndSwapOSX($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'ramswap'}) {return $map;}
-
- my $debug = 0; # Nur zum Testen!
- #my @speicher = qx(free -m);
- my @amemsize = SYSMON_execute($hash, "sysctl hw.memsize");
-
- if($debug) {
- @amemsize = ("hw.memsize: 8589934592");
- }
-
- if($amemsize[0]=~m/hw.memsize:\s+(.+)/) {
- my $total = $1;
-
- my @avmstat = SYSMON_execute($hash, "vm_stat");
- if($debug) {
- @avmstat = ('Mach Virtual Memory Statistics: (page size of 4096 bytes)',
- 'Pages free: 5268.',
- 'Pages active: 440314.',
- 'Pages inactive: 430905.',
- 'Pages speculative: 878.',
- 'Pages throttled: 0.',
- 'Pages wired down: 398445.',
- 'Pages purgeable: 69.',
- '"Translation faults": 508984629.',
- 'Pages copy-on-write: 5668036.',
- 'Pages zero filled: 347281743.',
- 'Pages reactivated: 114745855.',
- 'Pages purged: 13495647.',
- 'File-backed pages: 88747.',
- 'Anonymous pages: 783350.',
- 'Pages stored in compressor: 1760568.',
- 'Pages occupied by compressor: 820444.',
- 'Decompressions: 48558417.',
- 'Compressions: 63022425.',
- 'Pageins: 3754238.',
- 'Pageouts: 589840.',
- 'Swapins: 714378.',
- 'Swapouts: 1017813.');
- }
-
- #wired down, active, inactive
- my $wired_down=0;
- my $active=0;
- my $inactive=0;
- my $blockSize = 4096;
- foreach my $k (@avmstat) {
- if($k=~m/page\s+size\s+of\s+(\d+)\s+bytes/) {
- $blockSize = $1;
- }
- if($k=~m/Pages\s+wired\s+down:\s+(.+)\./) {
- $wired_down = $1;
- }
- if($k=~m/Pages\s+active:\s+(.+)\./) {
- $active = $1;
- }
- if($k=~m/Pages\s+inactive:\s+(.+)\./) {
- $inactive = $1;
- }
- }
-
- $wired_down = $wired_down * $blockSize / 1048576; # In Megabyte umrechnen
- $active = $active * $blockSize / 1048576;
- $inactive = $inactive * $blockSize / 1048576;
-
- my $used = $wired_down+$active+$inactive;
-
- $total = $total/1048576;
- my $free = $total-$used;
- my $ram = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total, $used , ($used / $total * 100), $free);
- #Log 3, "SYSMON >>>>>>>>>>>>>>>>>>>>>>>>> OSX: RAM: ".$ram;
- $map->{+RAM} = $ram;
- $map = SYSMON_getComputeStat($hash, $map, $used, "ram_used_stat");
-
- my @avm = SYSMON_execute($hash, "sysctl vm.swapusage");
- if($debug) {
- @avm=(
- #'vm.loadavg: { 2.45 2.19 3.34 }',
- 'vm.swapusage: total = 1024.00M used = 529.25M free = 494.75M (encrypted)',
- #'vm.cs_force_kill: 0',
- #'vm.cs_force_hard: 0',
- #'vm.cs_debug: 0',
- #'vm.cs_all_vnodes: 0',
- #'vm.cs_enforcement: 0',
- #'vm.cs_enforcement_panic: 0',
- #'vm.sigpup_disable: 0',
- #'vm.global_no_user_wire_amount: 67108864',
- #'vm.global_user_wire_limit: 8522825728',
- #'vm.user_wire_limit: 8522825728',
- #'vm.vm_copy_src_not_internal: 129',
- #'vm.vm_copy_src_not_symmetric: 14994',
- #'vm.vm_copy_src_large: 0',
- #'vm.vm_page_external_count: 355255',
- #'vm.vm_page_filecache_min: 104857',
- #'vm.compressor_mode: 4',
- #'vm.compressor_bytes_used: 2984467096',
- #'vm.compressor_swapout_target_age: 0',
- #'vm.compressor_eval_period_in_msecs: 250',
- #'vm.compressor_sample_min_in_msecs: 500',
- #'vm.compressor_sample_max_in_msecs: 10000',
- #'vm.compressor_thrashing_threshold_per_10msecs: 50',
- #'vm.compressor_thrashing_min_per_10msecs: 20',
- #'vm.compressor_minorcompact_threshold_divisor: 20',
- #'vm.compressor_majorcompact_threshold_divisor: 25',
- #'vm.compressor_unthrottle_threshold_divisor: 35',
- #'vm.compressor_catchup_threshold_divisor: 50',
- #'vm.cs_validation: 1',
- #'vm.cs_blob_count: 616',
- #'vm.cs_blob_size: 8053170',
- #'vm.cs_blob_count_peak: 693',
- #'vm.cs_blob_size_peak: 8389641',
- #'vm.cs_blob_size_max: 1675264',
- #'vm.vm_debug_events: 0',
- #'vm.allow_stack_exec: 0',
- #'vm.allow_data_exec: 1',
- #'vm.shared_region_unnest_logging: 1',
- #'vm.shared_region_trace_level: 1',
- #'vm.shared_region_version: 3',
- #'vm.shared_region_persistence: 0',
- #'vm.vm_page_free_target: 2000',
- #'vm.memory_pressure: 0',
- #'vm.page_free_wanted: 86',
- #'vm.page_purgeable_count: 1055',
- #'vm.page_purgeable_wired_count: 0',
- #'vm.madvise_free_debug: 0',
- #'vm.page_reusable_count: 39048',
- #'vm.reusable_success: 11350536',
- #'vm.reusable_failure: 1060241',
- #'vm.reusable_shared: 248771',
- #'vm.all_reusable_calls: 290574',
- #'vm.partial_reusable_calls: 11142306',
- #'vm.reuse_success: 9593371',
- #'vm.reuse_failure: 5124',
- #'vm.all_reuse_calls: 257820',
- #'vm.partial_reuse_calls: 9684238',
- #'vm.can_reuse_success: 6171792',
- #'vm.can_reuse_failure: 79183',
- #'vm.reusable_reclaimed: 0',
- #'vm.page_free_count: 1914',
- #'vm.page_speculative_count: 810',
- #'vm.page_cleaned_count: 0',
- #'vm.pageout_inactive_dirty_internal: 63170734',
- #'vm.pageout_inactive_dirty_external: 465495',
- #'vm.pageout_inactive_clean: 18967682',
- #'vm.pageout_speculative_clean: 32929182',
- #'vm.pageout_inactive_used: 115155398',
- #'vm.pageout_freed_from_inactive_clean: 18423099',
- #'vm.pageout_freed_from_speculative: 32929182',
- #'vm.pageout_freed_from_cleaned: 568334',
- #'vm.pageout_enqueued_cleaned: 1010912',
- #'vm.pageout_enqueued_cleaned_from_inactive_clean: 0',
- #'vm.pageout_enqueued_cleaned_from_inactive_dirty: 1011010',
- #'vm.pageout_cleaned: 568334',
- #'vm.pageout_cleaned_reactivated: 407922',
- #'vm.pageout_cleaned_reference_reactivated: 4',
- #'vm.pageout_cleaned_volatile_reactivated: 0',
- #'vm.pageout_cleaned_fault_reactivated: 557',
- #'vm.pageout_cleaned_commit_reactivated: 407361',
- #'vm.pageout_cleaned_busy: 33',
- #'vm.pageout_cleaned_nolock: 12931'
- );
- }
-
- #vm.swapusage: total = 1024.00M used = 529.25M free = 494.75M (encrypted)
- if($avm[0]=~m/vm.swapusage:\s+total\s+=\s+(\S*)\s+used\s+=\s+(\S*)\s+free\s+=\s+(\S*)\s+(.*)/) {
- my $total2 = SYSMON_fmtStorageAmount_($1);
- my $used2 = SYSMON_fmtStorageAmount_($2);
- my $free2 = SYSMON_fmtStorageAmount_($3);
- my $swap = sprintf("Total: %.2f MB, Used: %.2f MB, %.2f %%, Free: %.2f MB", $total2, $used2, ($used2 / $total2 * 100), $free2);
- $map->{+SWAP} = $swap;
- $map = SYSMON_getComputeStat($hash, $map, $used2, "swap_used_stat");
- #Log 3, "SYSMON >>>>>>>>>>>>>>>>>>>>>>>>> OSX: SWAP: ".$swap;
- }
- }
-
- return $map;
- }
- sub SYSMON_fmtStorageAmount_($) {
- my ($t) = @_;
- if($t=~m/([\d|\.]+)(.*)/) {
- my $r=$1;
- my $m=$2;
- if($m) {
- # Modifier testen
- if($m eq 'M') {
- # Megabyte ist OK,so lassen
- return $r;
- }
- if($m eq 'G') {
- # Gigabyte: in MB umwandeln
- $r=$r*1024;
- }
- # K, oder P nehmen ich nicht mehr bzw. noch nicht an ;)
- return $r;
- }
- }
- return $t;
- }
- #------------------------------------------------------------------------------
- # Liefert Fuellstand fuer das angegebene Dateisystem (z.B. '/dev/root', '/dev/sda1' (USB stick)).
- # Eingabeparameter: HASH; MAP; FS-Bezeichnung
- #------------------------------------------------------------------------------
- sub SYSMON_getFileSystemInfo ($$$) {
- my ($hash, $map, $fs) = @_;
-
- if($hash->{helper}->{excludes}{'filesystem'}) {return $map;}
-
- SYSMON_Log($hash, 5, "get $fs");
-
- # Neue Syntax: benannte Filesystems: <name>:<definition>
- my($fName, $fDef, $fComment) = split(/:/, $fs);
- if(defined $fDef) {
- $fs = $fDef;
- }
- #my $disk = "df ".$fs." -m 2>&1"; # in case of failure get string from stderr
- my $disk = "df ".$fs." -m 2>/dev/null";
-
- SYSMON_Log($hash, 5, "exec $disk");
- #my @filesystems = qx($disk);
- my @filesystems = SYSMON_execute($hash, $disk);
-
- SYSMON_Log($hash, 5, "recieved ".scalar(scalar(@filesystems))." lines");
-
- # - DEBUG -
- #if($fs eq "/test") {
- # @filesystems=(
- # "Filesystem 1M-blocks Used Available Use% Mounted on",
- # "/dev/mapper/n40l-root",
- # " 226741 22032 193192 11% /"
- # );
- # $fs = "/";
- #}
- #- DEBUG -
-
-
- #if(!defined @filesystems) { return $map; } # Ausgabe leer
- #if(scalar(@filesystems) == 0) { return $map; } # Array leer
- if(defined($filesystems[0])) {
- SYSMON_Log($hash, 5, "recieved line0 $filesystems[0]");
- } else {
- SYSMON_Log($hash, 5, "recieved empty line");
- }
- shift @filesystems;
-
- # Falls kein Eintrag gefunden (z.B: kein Medium im Laufwerk), mit Nullen fuellen (damit die Plots richtig funktionieren).
- if(defined $fDef) {
- $map->{$fName} = "Total: 0 MB, Used: 0 MB, 0 %, Available: 0 MB at ".$fs." (not available)";
- } else {
- $map->{+FS_PREFIX.$fs} = "Total: 0 MB, Used: 0 MB, 0 %, Available: 0 MB at ".$fs." (not available)";
- }
-
- #return $map unless defined(@filesystems);
- return $map unless int(@filesystems)>0;
- #if(!defined $filesystems[0]) { return $map; } # Ausgabe leer
-
- SYSMON_Log($hash, 5, "analyse line $filesystems[0] for $fs");
-
- #if (!($filesystems[0]=~ /$fs\s*$/)){ shift @filesystems; }
- if (!($filesystems[0]=~ /$fs$/)){
- shift @filesystems;
- if(int(@filesystems)>0) {
- SYSMON_Log($hash, 5, "analyse line $filesystems[0] for $fs");
- }
- } else {
- SYSMON_Log($hash, 5, "pattern ($fs) found");
- }
- #if (index($filesystems[0], $fs) < 0) { shift @filesystems; } # Wenn die Bezeichnung so lang ist, dass die Zeile umgebrochen wird...
- #if (index($filesystems[0], $fs) >= 0) # check if filesystem available -> gives failure on console
- if (int(@filesystems)>0 && $filesystems[0]=~ /$fs$/)
- {
- SYSMON_Log($hash, 5, "use line $filesystems[0]");
-
- my ($fs_desc, $total, $used, $available, $percentage_used, $mnt_point) = split(/\s+/, $filesystems[0]);
- $percentage_used =~ /^(.+)%$/;
- $percentage_used = $1;
- my $out_txt = "Total: ".$total." MB, Used: ".$used." MB, ".$percentage_used." %, Available: ".$available." MB at ".$mnt_point;
- if(defined $fDef) {
- $map->{$fName} = $out_txt;
- } else {
- $map->{+FS_PREFIX.$mnt_point} = $out_txt;
- }
- }
- # else {
- # if(defined $fDef) {
- # $map->{$fName} = "not available";
- # } else {
- # $map->{+FS_PREFIX.$fs} = "not available";
- # }
- #}
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Netztwerkinformationen
- # Parameter: HASH; MAP; DEVICE (eth0 or wlan0)
- #------------------------------------------------------------------------------
- sub SYSMON_getNetworkInfo ($$$) {
- my ($hash, $map, $device) = @_;
-
- if($hash->{helper}->{excludes}{'network'}) {return $map;}
- return $map unless (-e "/sbin/ifconfig");
-
- SYSMON_Log($hash, 5, "get $device");
- my($nName, $nDef) = split(/:/, $device);
- if(!defined $nDef) {
- $nDef = $nName;
- }
- $device = $nDef;
- # in case of network not present get failure from stderr (2>&1)
- my $cmd="/sbin/ifconfig ".$device." 2>&1";
- #my @dataThroughput = qx($cmd);
- my @dataThroughput = SYSMON_execute($hash, $cmd);
- SYSMON_Log ($hash, 5, "SYSMON_getNetworkInfo>>>>>>>>>>>>>>>>".Dumper(@dataThroughput));
-
- #--- DEBUG ---
- if($device eq "_test1") {
- @dataThroughput = (
- "enp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1492",
- " inet 192.168.2.7 netmask 255.255.255.0 broadcast 192.168.2.255",
- " ether 00:21:85:5a:0d:e0 txqueuelen 1000 (Ethernet)",
- " RX packets 1553313 bytes 651891540 (621.6 MiB)",
- " RX errors 0 dropped 0 overruns 0 frame 0",
- " TX packets 1915387 bytes 587386206 (560.1 MiB)",
- " TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0");
- }
-
- if($device eq "_test2") {
- @dataThroughput = (
- "eth0 Link encap:Ethernet Hardware Adresse b8:27:eb:47:a9:8d",
- " inet Adresse:192.168.2.118 Bcast:192.168.2.255 Maske:255.255.255.0",
- " inet6-Adresse: 2003:46:b6b:3100:ba27:ebff:fe47:a98d/64 Gültigkeitsbereich:Global",
- " inet6-Adresse: fe80::ba27:ebff:fe47:a98d/64 Gültigkeitsbereich:Verbindung",
- " UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1",
- " RX packets:1224709 errors:0 dropped:0 overruns:0 frame:0",
- " TX packets:1156620 errors:0 dropped:0 overruns:0 carrier:0",
- " Kollisionen:0 Sendewarteschlangenlänge:1000",
- " RX bytes:180806073 (172.4 MiB) TX bytes:108919337 (103.8 MiB)");
- }
- #--- DEBUG ---
- # check if network available
- if (defined($dataThroughput[0]) && index($dataThroughput[0], 'Fehler') < 0 && index($dataThroughput[0], 'error') < 0)
- {
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>> OK >>>".$dataThroughput[0];
- my $dataThroughput = undef;
-
- # Suche nach der Daten in Form:
- # eth0 Link encap:Ethernet Hardware Adresse b8:27:eb:a5:e0:85
- # inet Adresse:192.168.0.10 Bcast:192.168.0.255 Maske:255.255.255.0
- # UP BROADCAST RUNNING MULTICAST MTU:1500 Metrik:1
- # RX packets:339826 errors:0 dropped:45 overruns:0 frame:0
- # TX packets:533293 errors:0 dropped:0 overruns:0 carrier:0
- # Kollisionen:0 Sendewarteschlangenlaenge:1000
- # RX bytes:25517384 (24.3 MiB) TX bytes:683970999 (652.2 MiB)
-
- my $ip = undef; my $ip6 = undef;
- foreach (@dataThroughput) {
- if($_=~ m/inet\s+(Adresse:)*(\S*)/) {
- $ip=$2;
- }
- if(!$ip && $_=~ m/inet\s+(addr:)*(\S*)/) {
- $ip=$2;
- SYSMON_Log ($hash, 3, "SYSMON_getNetworkInfo:ip: ".$ip);
- }
-
- if($_=~ m/inet6-(Adresse:)*\s*(\S*)\s+G.ltigkeitsbereich:Verbindung/) {
- $ip6=$2;
- }
- if(!$ip && $_=~ m/inet6\s+(addr:)*\s*(\S*)\s+Scope:Link/) {
- $ip6=$2;
- }
- if(!$ip && $_=~ m/inet6\s+(addr:)*\s*(\S*)/) {
- $ip6=$2;
- }
- if(index($_, 'RX bytes') >= 0) {
- $dataThroughput = $_;
- last;
- }
- }
-
- if(defined $ip) {
- $ip =~ s/addr://;
- $map->{$nName.IP_SUFFIX} = $ip;
- }
-
- if(defined $ip6) {
- $ip6 =~ s/addr://;
- $map->{$nName.IP6_SUFFIX} = $ip6;
- }
- my $rxRaw = -1;
- my $txRaw = -1;
- # if(-e "/sys/class/net/$nName/statistics/rx_bytes" && -e "/sys/class/net/$nName/statistics/tx_bytes") {
- if(SYSMON_isNetStatClass($hash, $nName)) {
- $rxRaw = SYSMON_execute($hash, "cat /sys/class/net/$nName/statistics/rx_bytes");
- $rxRaw = -1 unless (defined($rxRaw) && looks_like_number($rxRaw));
- $txRaw = SYSMON_execute($hash, "cat /sys/class/net/$nName/statistics/tx_bytes");
- $txRaw = -1 unless (defined($txRaw) && looks_like_number($txRaw));
- }
- if($rxRaw<0||$txRaw<0) {
- if(defined $dataThroughput) {
- # remove RX bytes or TX bytes from string
- $dataThroughput =~ s/RX bytes://;
- $dataThroughput =~ s/TX bytes://;
- $dataThroughput = trim($dataThroughput);
- @dataThroughput = split(/ /, $dataThroughput); # return of split is array
- $rxRaw = $dataThroughput[0] if(defined $dataThroughput[0]);
- $txRaw = $dataThroughput[4] if(defined $dataThroughput[4]);
- } else {
- #
- # an manchen Systemen kann die Ausgabe leider auch anders aussehen:
- # enp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1492
- # inet 192.168.2.7 netmask 255.255.255.0 broadcast 192.168.2.255
- # ether 00:21:85:5a:0d:e0 txqueuelen 1000 (Ethernet)
- # RX packets 1553313 bytes 651891540 (621.6 MiB)
- # RX errors 0 dropped 0 overruns 0 frame 0
- # TX packets 1915387 bytes 587386206 (560.1 MiB)
- # TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- #
- my $d;
- foreach $d (@dataThroughput) {
- if($d =~ m/RX\s.*\sbytes\s(\d*)\s/) {
- $rxRaw = $1;
- }
- if($d =~ m/TX\s.*\sbytes\s(\d*)\s/) {
- $txRaw = $1;
- }
- }
- }
- }
-
- if($rxRaw<0) {
- # Daten nicht gefunden / Format unbekannt
- $map->{$nName} = "unexpected format";
- $map->{$nName.DIFF_SUFFIX} = "unexpected format";
- } else {
- $map->{$nName."_rx"} = $rxRaw;
- $map->{$nName."_tx"} = $txRaw;
-
- $rxRaw = $rxRaw / 1048576; # Bytes in MB
- $txRaw = $txRaw / 1048576;
-
- my $rx = sprintf ("%.2f", $rxRaw);
- my $tx = sprintf ("%.2f", $txRaw);
- my $totalRxTx = $rx + $tx;
- my $out_txt = "RX: ".$rx." MB, TX: ".$tx." MB, Total: ".$totalRxTx." MB";
- $map->{$nName} = $out_txt;
- my $lastVal = ReadingsVal($hash->{NAME},$nName,"RX: 0 MB, TX: 0 MB, Total: 0 MB");
- my ($d0, $o_rx, $d1, $d2, $o_tx, $d3, $d4, $o_tt, $d5) = split(/\s+/, trim($lastVal));
- if(defined($o_tx) && defined($o_tt)) {
- my $d_rx = $rx-$o_rx;
- if($d_rx<0) {$d_rx=0;}
- my $d_tx = $tx-$o_tx;
- if($d_tx<0) {$d_tx=0;}
- my $d_tt = $totalRxTx-$o_tt;
- if($d_tt<0) {$d_tt=0;}
- my $out_txt_diff = "RX: ".sprintf ("%.2f", $d_rx)." MB, TX: ".sprintf ("%.2f", $d_tx)." MB, Total: ".sprintf ("%.2f", $d_tt)." MB";
- $map->{$nName.DIFF_SUFFIX} = $out_txt_diff;
- }
-
- my $speed;
- #if ($nName eq "wlan0") {
- if($nName=~m/wlan/) {
- #my @iwData = SYSMON_execute($hash, "/sbin/iwconfig $nName 2>/dev/null");
- my @iwData = SYSMON_execute($hash, "/sbin/iwconfig $nDef 2>/dev/null");
- foreach (@iwData) {
- next unless ($_);
- if($_=~ m/Bit\sRate+(=|:)*(\S*)/) {
- $speed=$2;
- }
- }
- }
- elsif (1 eq SYSMON_execute($hash, "[ -f /sys/class/net/$nName/speed ] && echo 1 || echo 0")) {
- $speed = SYSMON_execute($hash, "cat /sys/class/net/$nName/speed 2>/dev/null");
- }
- else {
- $speed = "not available";
- }
- if(defined($speed)) {
- $map->{$nName.SPEED_SUFFIX} = $speed;
- }
- }
- } else {
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>> NOK ";
- #Log 3, "SYSMON>>>>>>>>>>>>>>>>> >>> ".$nName;
- $map->{$nName} = "not available";
- $map->{$nName.DIFF_SUFFIX} = "not available";
- }
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Informationen, ob WLAN an oder aus ist (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBWLANState($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'network'}) {return $map;}
-
- #SYSMON_Log($hash, 5, "");
-
- $map->{+FB_WLAN_STATE}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r wlan settings/ap_enabled",1);
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Informationen, ob WLAN-Gastzugang an oder aus ist (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBWLANGuestState($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'network'}) {return $map;}
-
- #SYSMON_Log($hash, 5, "");
-
- $map->{+FB_WLAN_GUEST_STATE}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r wlan settings/guest_ap_enabled",1);
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert IP Adresse im Internet (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBInetIP($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'network'}) {return $map;}
-
- $map->{+FB_INET_IP}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r dslstatistic status/ifacestat0/ipaddr");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Status Internet-Verbindung (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBInetConnectionState($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'network'}) {return $map;}
-
- $map->{+FB_INET_STATE}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r dslstatistic status/ifacestat0/connection_status");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Status Klingelsperre (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBNightTimeControl($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbnightctrl'}) {return $map;}
-
- $map->{+FB_N_TIME_CTRL}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r box settings/night_time_control_enabled",1);
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Anzahl der nicht abgehoerten Nachrichten auf dem Anrufbeantworter (nur FritzBox)
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBNumNewMessages($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbnewmessages'}) {return $map;}
-
- $map->{+FB_NUM_NEW_MESSAGES}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r tam status/NumNewMessages");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert DECT-Temperatur einer FritzBox.
- # Parameter: HASH; MAP
- #------------------------------------------------------------------------------
- sub SYSMON_getFBDECTTemp($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdecttemp'}) {return $map;}
-
- $map->{+FB_DECT_TEMP}=SYSMON_acquireInfo_intern($hash, "ctlmgr_ctl r dect status/Temperature");
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Liefert Liste an der FritzBox bekannter Devices.
- # Parameter: HASH
- # Return Hash mit Devices
- #------------------------------------------------------------------------------
- sub SYSMON_getFBLanDeviceList($) {
- my ($hash) = @_;
-
- if(!SYSMON_isFB($hash)) {
- return undef;
- }
-
- my $map;
-
- my $name = $hash->{NAME};
- # ---
- #TODO: SSH
- my $msg = undef;
- my $openedTelnet = 0;
- my $telnet = $hash->{".telnet"};
- #$telnet = undef;
- my $mode = $hash->{MODE};
- # Wenn remote: open connection
- if ($mode eq 'telnet') {
- unless (defined $telnet) {
- SYSMON_Log($hash, 5, "$name: Open single telnet connection");
- $msg = SYSMON_Open_Connection($hash);
- $hash->{helper}{error_msg}=$msg;
- if (!$msg) {
- $openedTelnet = 1;
- $hash->{helper}{error_msg}=undef;
- }
- }
- }
- # ---
- my $count = SYSMON_execute($hash, "ctlmgr_ctl r landevice settings/landevice/count");
- if(defined($count)) {
- for (my $i=0;$i<$count;$i++) {
- #landevice0/...
- # ip=192.168.178.12, mac=00:1F:3F:MM:AA:CC, name=PC-192-168-178-12, manu_name=0,
- # dhcp=0, static_dhcp=0, wlan=0, ethernet=1, active=1, online=0, speed=100,
- # deleteable=2, wakeup=0, source=4096, neighbour_name=, is_double_neighbour_name=0
- # ipv6addrs=, ipv6_ifid=
- my $dev_name = SYSMON_execute($hash, "ctlmgr_ctl r landevice settings/landevice".$i."/name");
- my $dev_ip = SYSMON_execute($hash, "ctlmgr_ctl r landevice settings/landevice".$i."/ip");
- my $dev_mac = SYSMON_execute($hash, "ctlmgr_ctl r landevice settings/landevice".$i."/mac");
- my $dev_active = SYSMON_execute($hash, "ctlmgr_ctl r landevice settings/landevice".$i."/active");
-
- $map->{$dev_name}{id} = $i;
- $map->{$dev_name}{name} = $dev_name;
- $map->{$dev_name}{ip} = $dev_ip;
- $map->{$dev_name}{mac} = $dev_mac;
- $map->{$dev_name}{active} = $dev_active;
- }
- }
-
- # ---
- # Wenn remote: close connection
- if ($mode eq 'telnet') {
- if($openedTelnet) {
- SYSMON_Log($hash, 5, "$name: Close shared telnet connection");
- SYSMON_Close_Connection( $hash );
- }
- }
- # ---
-
- return $map;
- }
- # TODO: FritzBox-Infos: Dateien /var/env oder /proc/sys/urlader/environment.
- #------------------------------------------------------------------------------
- # Liefert Informationen zu verschiedenen Eigenschaften durch Aufruf von entsprechenden Befehlen
- # Parameter: HASH; cmd; Art (Interpretieren als: 1=on/off)
- #------------------------------------------------------------------------------
- sub SYSMON_acquireInfo_intern($$;$)
- {
- my ($hash, $cmd, $art) = @_;
-
- SYSMON_Log($hash, 5, "cmd: ".$cmd);
-
- my $str = SYSMON_execute($hash, $cmd);
- if(defined($str)) {
- $str = trim($str);
- }
- my $ret;
-
- if(!defined($art)) { $art= 0; }
- $ret = $str;
- no warnings;
- if($art == 1) {
- if($str+0 == 1) {
- $ret="on";
- } else {
- if($str+0 == 0) {
- $ret="off";
- } else {
- $ret="unknown";
- }
- }
- }
- use warnings;
- return $ret;
- }
- sub SYSMON_FBVersionInfo($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbversion'}) {return $map;}
-
- my @ar = SYSMON_execute($hash, "/etc/version --version --date");
- my $data = $ar[0];
-
- my($v, $d, $t) = split(/\s+/, $data);
-
- my $version = "";
- if(defined($v)) { $version = $v; }
- if(defined($d)) { $version.= " ".$d; }
- if(defined($t)) { $version.= " ".$t; }
-
- #if(defined($data[0])) {
- # #Version
- # $version = $data[0];
- #}
- #if(defined($data[1])) {
- # #Date
- # $version = $version." ".$data[1];
- #}
-
- if($version ne "") {
- $map->{+FB_FW_VERSION}=$version;
- }
-
- return $map;
- }
- #DSL-Downstream und DSL-Upstream abfragen
- sub SYSMON_getFBStreamRate($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdsl'}) {return $map;}
-
- my $ds_rate = SYSMON_execute($hash, "ctlmgr_ctl r sar status/dsl_ds_rate");
- unless($ds_rate) {
- return SYSMON_getFBStreamRate2($hash, $map);
- }
- my $us_rate = SYSMON_execute($hash, "ctlmgr_ctl r sar status/dsl_us_rate");
-
- if($ds_rate ne "" && $us_rate ne "") {
- $map->{+FB_DSL_RATE}="down: ".int($ds_rate)." kBit/s, up: ".int($us_rate)." kBit/s";
- }
-
- return $map;
- }
- # DSL-Geschwindigkeit mit neuer FritzOS (6.23)
- sub SYSMON_getFBStreamRate2($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdsl'}) {return $map;}
-
- my $ds_rate = SYSMON_execute($hash, "ctlmgr_ctl r dslstatglobal status/in");
- my $us_rate = SYSMON_execute($hash, "ctlmgr_ctl r dslstatglobal status/out");
-
- if(defined($ds_rate) && defined($us_rate) && $ds_rate ne "" && $us_rate ne "") {
- $ds_rate = $ds_rate/1000;
- $us_rate = $us_rate/1000;
- $map->{+FB_DSL_RATE}="down: ".int($ds_rate)." kBit/s, up: ".int($us_rate)." kBit/s";
- }
-
- return $map;
- }
- # Ausrechnet aus der Zahl der Sekunden Anzeige in Tagen:Stunden:Minuten:Sekunden.
- sub SYSMON_sec2Dauer($){
- my ($t) = @_;
- my $d = int($t/86400);
- my $r = $t-($d*86400);
- my $h = int($r/3600);
- $r = $r - ($h*3600);
- my $m = int($r/60);
- my $s = $r - $m*60;
- return sprintf("%02d Tage %02d Std. %02d Min. %02d Sec.",$d,$h,$m,$s);
- }
- #Sync-Zeit mit Vermittlungsstelle abfragen
- sub SYSMON_getFBSyncTime($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdsl'}) {return $map;}
-
- my $data = SYSMON_execute($hash, "ctlmgr_ctl r sar status/modem_ShowtimeSecs");
- unless($data) {
- return SYSMON_getFBSyncTime2($hash, $map);
- }
-
- if($data ne "") {
- my $idata = int($data);
- $map->{+FB_DSL_SYNCTIME}=SYSMON_sec2Dauer($idata);
- }
-
- return $map;
- }
- #Sync-Zeit mit Vermittlungsstelle abfragen mit neuer FritzOS (6.23)
- sub SYSMON_getFBSyncTime2($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdsl'}) {return $map;}
-
- my $data = SYSMON_execute($hash, "ctlmgr_ctl r dslstatistic status/ifacestat0/connect_time");
-
- if(defined($data) && $data ne "") {
- $map->{+FB_DSL_SYNCTIME}=$data;
- }
-
- return $map;
- }
- #Uebertragungsfehler abfragen (nicht behebbar und behebbar)
- sub SYSMON_getFBCRCFEC($$) {
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'fbdsl'}) {return $map;}
-
- my $ds_crc = SYSMON_execute($hash, "ctlmgr_ctl r sar status/ds_crc_per15min");
- my $us_crc = SYSMON_execute($hash, "ctlmgr_ctl r sar status/us_crc_per15min");
-
- my $ds_fec = SYSMON_execute($hash, "ctlmgr_ctl r sar status/ds_fec_per15min");
- my $us_fec = SYSMON_execute($hash, "ctlmgr_ctl r sar status/us_fec_per15min");
-
- if(defined($ds_crc) && $ds_crc ne "") {
- # FB_DSL_CRC_15
- $map->{+FB_DSL_CRC_15}="down: ".int($ds_crc)." up: ".int($us_crc);
- }
- if(defined($ds_fec) && $ds_fec ne "") {
- # FB_DSL_FEC_15
- $map->{+FB_DSL_FEC_15}="down: ".int($ds_fec)." up: ".int($us_fec);
- }
-
- return $map;
- }
- #------------------------------------------------------------------------------
- # Systemparameter als HTML-Tabelle ausgeben
- # Parameter: Name des SYSMON-Geraetes (muss existieren, kann auch anderer Modul genutzt werden), dessen Daten zur Anzeige gebracht werden sollen.
- # (optional) Liste der anzuzeigenden Werte (ReadingName[:Comment:[Postfix[:FormatString]]],...)
- # Beispiel: define sysv weblink htmlCode {SYSMON_ShowValuesHTML('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C', 'cpu_freq:CPU Frequenz: MHz'))}
- #------------------------------------------------------------------------------
- sub SYSMON_ShowValuesHTML ($;@)
- {
- my ($name, @data) = @_;
- return SYSMON_ShowValuesFmt($name, undef, 1, @data);
- }
- #------------------------------------------------------------------------------
- # Systemparameter als HTML-Tabelle ausgeben. Zusaetzlich wird eine Ueberschrift ausgegeben.
- # Parameter: Name des SYSMON-Geraetes (muss existieren, kann auch anderer Modul genutzt werden), dessen Daten zur Anzeige gebracht werden sollen.
- # Title: Ueberschrift (Text)
- # (optional) Liste der anzuzeigenden Werte (ReadingName[:Comment:[Postfix[:FormatString]]],...)
- # Beispiel: define sysv weblink htmlCode {SYSMON_ShowValuesHTML('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C', 'cpu_freq:CPU Frequenz: MHz'))}
- #------------------------------------------------------------------------------
- sub SYSMON_ShowValuesHTMLTitled ($;$@)
- {
- my ($name, $title, @data) = @_;
- $title = $attr{$name}{'alias'} unless $title;
- $title = $name unless $title;
- return SYSMON_ShowValuesFmt($name, $title, 1, @data);
- }
- #------------------------------------------------------------------------------
- # Systemparameter im Textformat ausgeben
- # Parameter: Name des SYSMON-Geraetes (muss existieren, kann auch anderer Modul genutzt werden), dessen Daten zur Anzeige gebracht werden sollen.
- # (optional) Liste der anzuzeigenden Werte (ReadingName[:Comment:[Postfix[:FormatString]]],...)
- # Beispiel: define sysv weblink htmlCode {SYSMON_ShowValuesText('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C', 'cpu_freq:CPU Frequenz: MHz'))}
- #------------------------------------------------------------------------------
- sub SYSMON_ShowValuesText ($;@)
- {
- my ($name, @data) = @_;
- return SYSMON_ShowValuesFmt($name, undef, 0, @data);
- }
- #------------------------------------------------------------------------------
- # Systemparameter im Textformat ausgeben
- # Parameter: Name des SYSMON-Geraetes (muss existieren, kann auch anderer Modul genutzt werden), dessen Daten zur Anzeige gebracht werden sollen.
- # Title: Ueberschrift (Text)
- # (optional) Liste der anzuzeigenden Werte (ReadingName[:Comment:[Postfix[:FormatString]]],...)
- # Beispiel: define sysv weblink htmlCode {SYSMON_ShowValuesText('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C', 'cpu_freq:CPU Frequenz: MHz'))}
- #------------------------------------------------------------------------------
- sub SYSMON_ShowValuesTextTitled ($;$@)
- {
- my ($name, $title, @data) = @_;
- $title = $attr{$name}{'alias'} unless $title;
- $title = $name unless $title;
- return SYSMON_ShowValuesFmt($name, $title, 0, @data);
- }
- #------------------------------------------------------------------------------
- # Systemparameter formatiert ausgeben
- # Parameter:
- # Name des SYSMON-Geraetes (muss existieren), dessen Daten zur Anzeige gebracht werden sollen.
- # Title: Ueberschrift
- # Format: 0 = Text, 1 = HTML
- # (optional) Liste der anzuzeigenden Werte (ReadingName[:Comment:[Postfix[:FormatString]]],...)
- #------------------------------------------------------------------------------
- sub SYSMON_ShowValuesFmt ($$$;@)
- {
- my ($name, $title, $format, @data) = @_;
-
- if($format != 0 && $format != 1) {
- return "unknown output format\r\n";
- }
-
- my $hash = $main::defs{$name};
-
- # nur, wenn es sich um eine SYSMON Instanz handelt
- if($hash->{TYPE} eq 'SYSMON') {
- SYSMON_updateCurrentReadingsMap($hash);
- }
- #Log 3, "SYSMON $>name, @data<";
- my @dataDescription = @data;
- if(scalar(@data)<=0) {
- # Array mit anzuzeigenden Parametern (Prefix, Name (in Map), Postfix)
- my $deg = "°";
- if($format == 1) {
- $deg = "°";
- }
- # bei der Benutzung mit CloneDummies ist $cur_readings_map nicht unbedingt definiert
- @dataDescription = (DATE,
- #CPU_TEMP.":".$hash->{helper}{cur_readings_map}->{+CPU_TEMP}.": ".$deg."C",
- CPU_TEMP.":"."CPU temperature".": ".$deg."C".":%.1f",
- #CPU_FREQ.":".$hash->{helper}{cur_readings_map}->{+CPU_FREQ}.": "."MHz",
- CPU_FREQ.":"."CPU frequency".": "."MHz",
- CPU_MODEL_NAME, CPU_BOGOMIPS,
- UPTIME_TEXT, FHEMUPTIME_TEXT, LOADAVG, RAM, SWAP,
- "power_ac_text", "power_usb_text", "power_battery_text");
- # network-interfaces
- my $networks = AttrVal($name, "network-interfaces", undef);
- if(defined $networks) {
- my @networks_list = split(/,\s*/, trim($networks));
- foreach (@networks_list) {
- my($nName, $nDef, $nComment) = split(/:/, $_);
- push(@dataDescription, $nName);
- }
- }
-
- # named filesystems
- my $filesystems = AttrVal($name, "filesystems", undef);
- if(defined $filesystems) {
- my @filesystem_list = split(/,\s*/, trim($filesystems));
- foreach (@filesystem_list) {
- my($fName, $fDef, $fComment) = split(/:/, $_);
- push(@dataDescription, $fName);
- }
- }
- # User defined
- my $userdefined = AttrVal($name, "user-defined", undef);
- if(defined $userdefined) {
- my @userdefined_list = split(/,\s*/, trim($userdefined));
- foreach (@userdefined_list) {
- # <readingName>:<Interval_Minutes>:<Comment>:<Cmd>
- my($uName, $uInterval, $uComment, $uCmd) = split(/:/, $_);
- push(@dataDescription, $uName);
- }
- }
- }
-
- #TODO: UserDefinedFn?
-
- my $map;
- if($hash->{TYPE} eq 'SYSMON') {
- $map = SYSMON_obtainParameters($hash, 1);
- } else {
- # Wenn nicht SYSMON, dann versuchen, die Daten aus den Readings auszulesen
- #$map = SYSMON_obtainReadings($hash);
- foreach my $rname (keys %{$hash->{READINGS}}) {
- my $rval=$hash->{READINGS}->{$rname}->{VAL};
- $map->{$rname}=$rval;
- }
- }
- my $div_class="sysmon";
- my $htmlcode;
- if($format == 1) {
- $htmlcode = "<div class='".$div_class."'><table>";
- } else {
- if($format == 0) {
- $htmlcode = "";
- }
- }
-
- if(defined $title) {
- if($format == 1) {
- $htmlcode .= "<tr><td valign='top' colspan='2'>".$title."</td></tr>";
- } else {
- if($format == 0) {
- $htmlcode .= sprintf("%s\r\n", $title);
- }
- }
- }
-
- # oben definierte Werte anzeigen
- foreach (@dataDescription) {
- my($rName, $rComment, $rPostfix, $fmtStr) = split(/:/, $_);
- if(defined $rName) {
- if(!defined $rComment) {
- $rComment = $hash->{helper}{cur_readings_map}->{$rName};
- }
- my $rVal = $map->{$rName};
- if(!defined $rVal) {
- # ggf. userReadings verarbeiten
- $rVal = ReadingsVal($name,$rName,undef);
- }
- if($rName eq DATE) {
- # Datum anzeigen
- $rVal = strftime("%d.%m.%Y %H:%M:%S", localtime());
- }
- if(!defined $rPostfix) { $rPostfix = ""; }
- if(defined $rVal) {
- if(defined($fmtStr)) {
- $rVal = sprintf($fmtStr,$rVal);
- }
- if($format == 1) {
- $htmlcode .= "<tr><td valign='top'>".$rComment.": </td><td>".$rVal.$rPostfix."</td></tr>";
- } else {
- if($format == 0) {
- $htmlcode .= sprintf("%-24s: %s%s\r\n", $rComment, $rVal,$rPostfix);
- }
- }
- }
- }
- }
-
- # nur Default (also alles anzeigen)
- if(scalar(@data)<=0) {
- # File systems
- foreach my $aName (sort keys %{$map}) {
- if(defined ($aName) && index($aName, FS_PREFIX) == 0) {
- $aName =~ /^~ (.+)/;
- if($format == 1) {
- $htmlcode .= "<tr><td valign='top'>File System: ".$1." </td><td>".$map->{$aName}."</td></tr>";
- } else {
- if($format == 0) {
- $htmlcode .= sprintf("%-24s: %s\r\n", "File System: ".$1,$map->{$aName});
- }
- }
- }
- }
- }
- if($format == 1) {
- $htmlcode .= "</table></div><br>";
- } else {
- if($format == 0) {
- $htmlcode .= "";
- }
- }
- return $htmlcode;
- }
- #sub SYSMON_first($) {
- # my (@d) = @_;
- # return @d[0];
- #
- # #my ($d) = @_;
- # #
- # #return undef unless defined $d;
- #
- # ##return ref ($d)." - ".ref(\$d);
- # #if (ref $d eq "ARRAY") {
- # # return @{$d}[0];
- # #} else {
- # # return $d;
- # #}
- #}
- #
- #sub SYSMON_last($) {
- # my (@d) = @_;
- #
- # return undef unless defined @d;
- #
- # return @d[-1];
- #
- # #return ref ($d)." - ".ref(\$d);
- # #if (ref $d eq "ARRAY") {
- # # return @{$d}[-1];
- # #} else {
- # # return $d;
- # #}
- #}
- #my $proc_fs = undef;
- sub
- SYSMON_isProcFS($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{proc_fs}) {
- $hash->{helper}{proc_fs} = int(SYSMON_execute($hash, "[ -d /proc/ ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{proc_fs};
- }
- #my $sys_cpu_temp_rpi = undef;
- sub
- SYSMON_isCPUTempRPi($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_cpu_temp_rpi}) {
- $hash->{helper}{sys_cpu_temp_rpi} = int(SYSMON_execute($hash, "[ -f /sys/class/thermal/thermal_zone0/temp ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_cpu_temp_rpi};
- }
- #my $sys_cpu_temp_bbb = undef;
- sub
- SYSMON_isCPUTempBBB($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_cpu_temp_bbb}) {
- $hash->{helper}{sys_cpu_temp_bbb} = int(SYSMON_execute($hash, "[ -f /sys/class/hwmon/hwmon0/device/temp1_input ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_cpu_temp_bbb};
- }
- #my $sys_cpu_freq_rpi_bbb = undef;
- sub
- SYSMON_isCPUFreqRPiBBB($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_cpu_freq_rpi_bbb}) {
- #$hash->{helper}{sys_cpu_freq_rpi_bbb} = int(SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq ] && echo 1 || echo 0"));
- # Diese abenteuerliche Konstruktion ist noetig, weil bei zu langen Zeilen ueber Telnet der Rest der Zeile als erstes Element kommt
- my @t = SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq ] && echo 1 || echo 0");
- if(@t) {
- $hash->{helper}{sys_cpu_freq_rpi_bbb} = int($t[-1]);
- }
- }
- return $hash->{helper}{sys_cpu_freq_rpi_bbb};
- }
- # DUMMY
- sub SYSMON_isCPUTempFB($) {
- my ($hash) = @_;
- return SYSMON_isFB($hash);
- }
- sub
- SYSMON_isCPUTemp_X($$) {
- my ($hash, $cpuNum) = @_;
-
- if(!defined $hash->{helper}{"sys_cpu".$cpuNum."_temp"}) {
- #/sys/class/hwmon/hwmon0/device/hwmon/hwmon0/temp2_input
- #$hash->{helper}{"sys_cpu".$cpuNum."_temp"} = int(SYSMON_execute($hash, "[ -f /sys/class/hwmon/hwmon0/device/hwmon/hwmon0/temp".$cpuNum."_input ] && echo 1 || echo 0"));
- # s. o.
- my @t = SYSMON_execute($hash, "[ -f /sys/class/hwmon/hwmon0/device/hwmon/hwmon0/temp".($cpuNum+1)."_input ] && echo 1 || echo 0");
- if(@t) {
- $hash->{helper}{"sys_cpu".$cpuNum."_temp"} = int($t[-1]);
- }
- }
- return $hash->{helper}{"sys_cpu".$cpuNum."_temp"};
- }
- sub
- SYSMON_isCPUXFreq($$) {
- my ($hash, $cpuNum) = @_;
- if(!defined $hash->{helper}{"sys_cpu".$cpuNum."_freq"}) {
- #$hash->{helper}{"sys_cpu".$cpuNum."_freq"} = int(SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq ] && echo 1 || echo 0"));
- # s. o.
- my @t = SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/cpu".$cpuNum."/cpufreq/scaling_cur_freq ] && echo 1 || echo 0");
- if(@t) {
- $hash->{helper}{"sys_cpu".$cpuNum."_freq"} = int($t[-1]);
- }
- }
- return $hash->{helper}{"sys_cpu".$cpuNum."_freq"};
- }
- #my $sys_fb = undef;
- sub
- SYSMON_isFB($) {
- my ($hash) = @_;
- if(!defined ($hash->{helper}{sys_fb})) {
- $hash->{helper}{sys_fb} = int(SYSMON_execute($hash, "[ -f /usr/bin/ctlmgr_ctl ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_fb};
- }
- #-Power-------
- #my $sys_power_ac = undef;
- sub
- SYSMON_isSysPowerAc($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_power_ac}) {
- $hash->{helper}{sys_power_ac} = int(SYSMON_execute($hash, "[ -f /sys/class/power_supply/ac/online ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_power_ac};
- }
- #my $sys_power_usb = undef;
- sub
- SYSMON_isSysPowerUsb($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_power_usb}) {
- $hash->{helper}{sys_power_usb} = int(SYSMON_execute($hash, "[ -f /sys/class/power_supply/usb/online ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_power_usb};
- }
- #my $sys_power_bat = undef;
- sub
- SYSMON_isSysPowerBat($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_power_bat}) {
- $hash->{helper}{sys_power_bat} = int(SYSMON_execute($hash, "[ -f /sys/class/power_supply/battery/online ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_power_bat};
- }
- #my $sys_cpu_num = undef;
- sub
- SYSMON_isSysCpuNum($) {
- my ($hash) = @_;
- if(!defined $hash->{helper}{sys_cpu_num}) {
- $hash->{helper}{sys_cpu_num} = int(SYSMON_execute($hash, "[ -f /sys/devices/system/cpu/kernel_max ] && echo 1 || echo 0"));
- }
- return $hash->{helper}{sys_cpu_num};
- }
- sub
- SYSMON_isNetStatClass($$) {
- my ($hash, $nName) = @_;
- if(!defined $hash->{helper}{'net_'.$nName.'_stat_class'}) {
- $hash->{helper}{'net_'.$nName.'_stat_class'} = int(SYSMON_execute($hash, "[ -f /sys/class/net/$nName/statistics/rx_bytes ] && echo 1 || echo 0"));
- # /sys/class/net/$nName/statistics/tx_bytes
- }
- return $hash->{helper}{'net_'.$nName.'_stat_class'};
- }
- sub SYSMON_PowerAcInfo($$) {
- #online, present, current_now (/1000 =>mA), voltage_now (/1000000 => V)
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'powerinfo'}) {return $map;}
-
- my $type="ac";
- my $base = "cat /sys/class/power_supply/".$type."/";
-
- my $d_online_t = SYSMON_execute($hash, $base."online");
- if($d_online_t) {
- my $d_online = trim($d_online_t);
- my $d_present = trim(SYSMON_execute($hash, $base."present 2>/dev/null"));
- my $d_current = SYSMON_execute($hash, $base."current_now 2>/dev/null");
- if(defined $d_current) {$d_current/=1000;} else {return $map;}
- my $d_voltage = SYSMON_execute($hash, $base."voltage_now 2>/dev/null");
- if(defined $d_voltage) {$d_voltage/=1000000;} else {return $map;}
-
- #$map->{"power_".$type."_online"}=$d_online;
- #$map->{"power_".$type."_present"}=$d_present;
- #$map->{"power_".$type."_current"}=$d_current;
- #$map->{"power_".$type."_voltage"}=$d_voltage;
- $map->{"power_".$type."_stat"}="$d_online $d_present $d_voltage $d_current";
- $map->{"power_".$type."_text"}=$type.": ".(($d_present eq "1") ? "present" : "absent")." / ".($d_online eq "1" ? "online" : "offline").", voltage: ".$d_voltage." V, current: ".$d_current." mA, ".(int(($d_voltage*$d_current/100+0.5))/10)." W";
- }
- return $map;
- }
- sub SYSMON_PowerUsbInfo($$) {
- #online, present, current_now (/1000 =>mA), voltage_now (/1000000 => V)
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'powerinfo'}) {return $map;}
-
- my $type="usb";
- my $base = "cat /sys/class/power_supply/".$type."/";
-
- my $d_online = trim(SYSMON_execute($hash, $base."online"));
- my $d_present = trim(SYSMON_execute($hash, $base."present 2>/dev/null"));
- my $d_current = SYSMON_execute($hash, $base."current_now 2>/dev/null");
- if(defined $d_current) {$d_current/=1000;} else {return $map;}
- my $d_voltage = SYSMON_execute($hash, $base."voltage_now 2>/dev/null");
- if(defined $d_voltage) {$d_voltage/=1000000;} else {return $map;}
-
- #$map->{"power_".$type."_online"}=$d_online;
- #$map->{"power_".$type."_present"}=$d_present;
- #$map->{"power_".$type."_current"}=$d_current;
- #$map->{"power_".$type."_voltage"}=$d_voltage;
- $map->{"power_".$type."_stat"}="$d_online $d_present $d_voltage $d_current";
- $map->{"power_".$type."_text"}=$type.": ".(($d_present eq "1") ? "present" : "absent")." / ".($d_online eq "1" ? "online" : "offline").", voltage: ".$d_voltage." V, current: ".$d_current." mA, ".(int(($d_voltage*$d_current/100+0.5))/10)." W";
-
- return $map;
- }
- sub SYSMON_PowerBatInfo($$) {
- #online, present, current_now (/1000 =>mA), voltage_now (/1000000 => V)
- my ($hash, $map) = @_;
-
- if($hash->{helper}->{excludes}{'powerinfo'}) {return $map;}
-
- my $type="battery";
- my $base = "cat /sys/class/power_supply/".$type."/";
-
- my $d_online = trim(SYSMON_execute($hash, $base."online"));
- my $d_present = trim(SYSMON_execute($hash, $base."present 2>/dev/null"));
- my $d_current = SYSMON_execute($hash, $base."current_now 2>/dev/null");
- if(defined $d_current) {$d_current/=1000;} else {return $map;}
- my $d_voltage = SYSMON_execute($hash, $base."voltage_now 2>/dev/null");
- if(defined $d_voltage) {$d_voltage/=1000000;} else {return $map;}
-
- my $d_capacity = trim(SYSMON_execute($hash, $base."capacity 2>/dev/null"));
- if($d_present ne "1") {
- $d_capacity = "0";
- }
- #$map->{"power_".$type."_online"}=$d_online;
- #$map->{"power_".$type."_present"}=$d_present;
- #$map->{"power_".$type."_current"}=$d_current;
- #$map->{"power_".$type."_voltage"}=$d_voltage;
- $map->{"power_".$type."_stat"}="$d_online $d_present $d_voltage $d_current $d_capacity";
- $map->{"power_".$type."_text"}=$type.": ".(($d_present eq "1") ? "present" : "absent")." / ".($d_online eq "1" ? "online" : "offline").", voltage: ".$d_voltage." V, current: ".$d_current." mA, ".(int(($d_voltage*$d_current/100+0.5))/10)." W, "."capacity: ".$d_capacity." %";
-
- if($d_present eq "1") {
- # Zusaetzlich: technology, capacity, status, health, temp (/10 => °C)
- my $d_technology = trim(SYSMON_execute($hash, $base."technology 2>/dev/null"));
- my $d_status = trim(SYSMON_execute($hash, $base."status 2>/dev/null"));
- my $d_health = trim(SYSMON_execute($hash, $base."health 2>/dev/null"));
- my $d_energy_full_design = trim(SYSMON_execute($hash, $base."energy_full_design 2>/dev/null"));
-
- $map->{"power_".$type."_info"}=$type." info: ".$d_technology." , capacity: ".$d_capacity." %, status: ".$d_status." , health: ".$d_health." , total capacity: ".$d_energy_full_design." mAh";
-
- # ggf. noch irgendwann: model_name, voltage_max_design, voltage_min_design
- } else {
- $map->{"power_".$type."_info"}=$type." info: n/a , capacity: n/a %, status: n/a , health: n/a , total capacity: n/a mAh";
- }
-
- return $map;
- }
- #-------------
- sub SYSMON_execute($$)
- {
- my ($hash, $cmd) = @_;
- return SYSMON_Exec($hash, $cmd);
- #return qx($cmd);
- }
- #------------------------------------------------------------------------------
- # checks and stores password used for remote connection
- sub SYSMON_storePassword($$)
- {
- my ($hash, $password) = @_;
-
- my $index = $hash->{TYPE}."_".$hash->{NAME}."_passwd";
- my $key = getUniqueId().$index;
-
- my $enc_pwd = "";
-
- if(eval "use Digest::MD5;1")
- {
- $key = Digest::MD5::md5_hex(unpack "H*", $key);
- $key .= Digest::MD5::md5_hex($key);
- }
-
- for my $char (split //, $password)
- {
- my $encode=chop($key);
- $enc_pwd.=sprintf("%.2x",ord($char)^ord($encode));
- $key=$encode.$key;
- }
-
- my $err = setKeyValue($index, $enc_pwd);
- $hash->{helper}{error_msg}=$err;
- return "error while saving the password - $err" if(defined($err));
-
- return "password successfully saved";
- }
- # read password
- sub SYSMON_readPassword($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $index = $hash->{TYPE}."_".$hash->{NAME}."_passwd";
- my $key = getUniqueId().$index;
- my ($password, $err);
- SYSMON_Log($hash, 5, "Read password from file");
- ($err, $password) = getKeyValue($index);
- if(defined($err))
- {
- SYSMON_Log($hash, 3, "unable to read password from file: $err");
- return undef;
- }
- if(defined($password))
- {
- if(eval "use Digest::MD5;1")
- {
- $key = Digest::MD5::md5_hex(unpack "H*", $key);
- $key .= Digest::MD5::md5_hex($key);
- }
- my $dec_pwd = '';
-
- for my $char (map { pack('C', hex($_)) } ($password =~ /(..)/g))
- {
- my $decode=chop($key);
- $dec_pwd.=chr(ord($char)^ord($decode));
- $key=$decode.$key;
- }
-
- return $dec_pwd;
- }
- else
- {
- SYSMON_Log($hash, 5, "No password in file");
- return undef;
- }
- }
- # Opens a Telnet Connection to an external Machine
- ############################################
- sub SYSMON_Open_Connection($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $msg;
-
- my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- if ($mode eq 'local') {
- return undef;
- }
- if($missingModulRemote) {
- $msg="Error: Perl modul ".$missingModulRemote."is missing on this system. Please install before using this modul.";
- SYSMON_Log($hash, 3, $msg);
- return $msg;
- }
- my $host = $hash->{HOST};#AttrVal( $name, "remote_host", undef );
-
- if(!defined $host) {
- $msg="Error: no remote host provided";
- SYSMON_Log($hash, 3, $msg);
- return $msg unless defined $host;
- }
- my $port = $hash->{PORT};#AttrVal( $name, "remote_port", 23 );
- my $pwd = SYSMON_readPassword($hash);#AttrVal( $name, "remote_password", undef );
- my $user = $hash->{USER};#AttrVal( $name, "remote_user", "" );
- $user="" unless defined($user);
- #test
- #$pwd="dummy";
- #test
- my $before;
- my $match;
-
- #if(!defined($pwd)) {
- # my $pwdFile = AttrVal( $name, "pwdFile", undef);
- # if(defined($pwdFile)) {
- # SYSMON_Log($hash, 5, "Open password file '$pwdFile' to extract password");
- # if (open(IN, "<" . $pwdFile)) {
- # $pwd = <IN>;
- # close(IN);
- # SYSMON_Log($hash, 5, "Close password file");
- # } else {
- # $msg = "Error: Cannot open password file '$pwdFile': $!";
- # SYSMON_Log($hash, 2, $msg);
- # return $msg;
- # }
- # }
- #}
-
- if(!defined($pwd)) {
- $msg="Error: no password provided";
- SYSMON_Log($hash, 3, $msg);
- return $msg unless defined $pwd;
- }
-
- SYSMON_Log($hash, 5, "Open Telnet connection to $host:$port");
- my $timeout = AttrVal( $name, "telnet-time-out", "10");
- my $t_prompt=AttrVal($name,'telnet-prompt-regx','(#|\$)\s*$');
- #my $telnet = new Net::Telnet ( Host=>$host, Port => $port, Timeout=>$timeout, Errmode=>'return', Prompt=>'/(#|\$) $/');
- my $telnet = new Net::Telnet ( Host=>$host, Port => $port, Timeout=>$timeout, Errmode=>'return', Prompt=>'/'.$t_prompt.'/');
- if (!$telnet) {
- $msg = "Could not open telnet connection to $host:$port";
- SYSMON_Log($hash, 2, $msg);
- $telnet = undef;
- $hash->{".telnet"}=$telnet;
- return $msg;
- }
- $hash->{".telnet"}=$telnet;
- SYSMON_Log($hash, 5, "Wait for user or password prompt.");
- unless ( ($before,$match) = $telnet->waitfor('/(user|login|password): $/i') )
- {
- $msg = "Telnet error while waiting for user or password prompt: ".$telnet->errmsg;
- SYSMON_Log($hash, 2, $msg);
- $telnet->close;
- $telnet = undef;
- return $msg;
- }
- if ( $match =~ /(user|login): / && $user eq "")
- {
- $msg = "Telnet login requires user name but attribute 'telnetUser' not defined";
- SYSMON_Log($hash, 2, $msg);
- $telnet->close;
- $telnet = undef;
- return $msg;
- }
- elsif ( $match =~ /(user|login): /)
- {
- SYSMON_Log($hash, 5, "Entering user name");
- $telnet->print( $user );
- SYSMON_Log($hash, 5, "Wait for password prompt");
- unless ($telnet->waitfor( '/password: $/i' ))
- {
- $msg = "Telnet error while waiting for password prompt: ".$telnet->errmsg;
- SYSMON_Log($hash, 2, $msg);
- $telnet->close;
- $telnet = undef;
- return $msg;
- }
- }
- elsif ( $match eq "password: " && $user ne "")
- {
- SYSMON_Log($hash, 3, "remote user was defined but telnet login did not prompt for user name.");
- }
- SYSMON_Log($hash, 5, "Entering password");
- $telnet->print( $pwd );
- SYSMON_Log($hash, 5, "Wait for command prompt");
- my $tlogin_prompt=AttrVal($name,'telnet-login-prompt-regx','(#|\$|>)\s*$|Login failed.');
- #unless ( ($before,$match) = $telnet->waitfor( '/# $|Login failed./i' ))
- unless ( ($before,$match) = $telnet->waitfor( '/'.$tlogin_prompt.'/i' ))
- {
- $msg = "Telnet error while waiting for command prompt: ".$telnet->errmsg;
- SYSMON_Log($hash, 2, $msg);
- $telnet->close;
- $telnet = undef;
- return $msg;
- }
- elsif ( $match eq "Login failed.")
- {
- $msg = "Telnet error: Login failed. Wrong password.";
- SYSMON_Log($hash, 2, $msg);
- $telnet->close;
- $telnet = undef;
- return $msg;
- }
- #SYSMON_Log($hash, 2, "Prompt: ".Dumper($before)." > ".$match);
-
- # Promptzeile erkenen
- if(!($hash->{helper}{recognized_prompt})) {
- my @prompt = SYSMON_Exec_Remote($hash, '');
- if(scalar(@prompt) == 1) {
- $hash->{helper}{recognized_prompt}=$prompt[0];
- }
- }
- #SYSMON_Log($hash, 2, "Prompt: '".Dumper(@retVal)."'");
-
- return undef;
- } # end SYSMON_Open_Connection
-
- # Closes a Telnet Connection to an external Machine
- ############################################
- sub SYSMON_Close_Connection($)
- {
- my ($hash) = @_;
-
- my $name = $hash->{NAME};
- my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- if (!defined($mode) || $mode eq 'local') {
- return undef;
- }
-
- my $telnet = $hash->{".telnet"};
- if (defined $telnet)
- {
- SYSMON_Log ($hash, 5, "Close Telnet connection");
- $telnet->close;
- $telnet = undef;
- $hash->{".telnet"}=$telnet;
- }
- else
- {
- SYSMON_Log($hash, 1, "Cannot close an undefined Telnet connection");
- }
- } # end SYSMON_Close_Connection
- # Executed the command on the remote Shell
- ############################################
- sub SYSMON_Exec($$;$)
- {
- my ($hash, $cmd,$is_arr) = @_;
- my $openedTelnet = 0;
- my $telnet = $hash->{".telnet"};
-
- my $name = $hash->{NAME};
- my $mode = $hash->{MODE};#AttrVal( $name, 'mode', 'local');
- if ($mode eq 'telnet') {
- unless (defined $telnet)
- {
- SYSMON_Log($hash, 5, "$name: Open single telnet connection");
- my $msg = SYSMON_Open_Connection($hash);
- $hash->{helper}{error_msg}=$msg;
- if ($msg) {
- return undef;
- }
- $openedTelnet = 1;
- $hash->{helper}{error_msg}=undef;
- }
- my @retVal = SYSMON_Exec_Remote($hash, $cmd);
-
- if($openedTelnet) {
- SYSMON_Log($hash, 5, "$name: Close single telnet connection");
- SYSMON_Close_Connection( $hash );
- }
- #Prompt-Zeile entfernen, falls vorhanden
- my $recognized_prompt = $hash->{helper}{recognized_prompt};
- if(defined($recognized_prompt)) {
- if(scalar(@retVal)>=1) {
- if($retVal[-1] eq $recognized_prompt) {
- SYSMON_Log ($hash, 5, "remove prompt: ".$retVal[-1]."'");
- splice @retVal, -1, 1;# $retVal[-1];
- }
- }
- }
-
- # Arrays als solche zurueckgeben
- #if($is_arr && scalar(@retVal)>1) {
- if(scalar(@retVal)>1) {
- SYSMON_Log ($hash, 5, "Result A: '".Dumper(@retVal)."'");
- return @retVal;
- }
- # Einzeiler als normale Scalars
- my $line = $retVal[0];
- if(defined($line)) {
- chomp $line;
- SYSMON_Log ($hash, 5, "Result L: '$line'");
- } else {
- SYSMON_Log ($hash, 5, "Result undef");
- }
- return $line;
- #return $retVal;
- } else {
- if ($mode eq 'ssh') {
- return SYSMON_Exec_Ssh($hash, $cmd);
- } else {
- return SYSMON_Exec_Local($hash, $cmd);
- }
- }
- }
- sub MYTEST() {
- my @output=(
- '',
- '[~] ',
- '',
- '[~] # ',
- '',
- '',
- '',
- ' Interrupt:16 Memory:c0100000-c0120000 ',
- '',
- ' RX bytes:483322579219 (450.1 GiB) TX bytes:3757348645531 (3.4 TiB)',
- '',
- ' collisions:0 txqueuelen:1000 ',
- '',
- ' TX packets:3656315540 errors:0 dropped:0 overruns:0 carrier:0',
- '',
- ' RX packets:2817622543 errors:8 dropped:265294 overruns:0 frame:8',
- '',
- ' UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1',
- '',
- ' inet addr:192.168.178.80 Bcast:192.168.178.255 Mask:255.255.255.0',
- '',
- 'eth0 Link encap:Ethernet HWaddr 00:08:9B:D3:8D:9E'
- );
- @output = reverse(@output);
- for (my $i=0;$i<scalar(@output);$i++) {
- if($output[$i]=~ /^\[~\]/) {undef ($output[$i]);}
- }
- @output = grep{ defined($_) && trim($_) ne '' }@output;
- return Dumper(@output);
- }
- # Executed the command via Telnet
- sub ############################################
- SYSMON_Exec_Remote($$)
- {
- my ($hash, $cmd) = @_;
- my @output;
- my $result;
- my $telnet = $hash->{".telnet"};
- SYSMON_Log($hash, 5, "Execute '".$cmd."'");
- @output=$telnet->cmd($cmd);
- #SYSMON_Log($hash, 5, "Result '".Dumper(@output)."'"); # TODO: remove
- # Sonderlocke fuer QNAP: letzten Zeilen mit "[~] " am Anfang entfernen
- #while((scalar(@output)>0) && ($output[-1]=~ /^\[~\]/)) {
- # SYSMON_Log ($hash, 5, "Remove line: '".$output[-1]."'");
- # splice @output, -1, 1;
- #}
- for (my $i=0;$i<scalar(@output);$i++) {
- #SYSMON_Log($hash, 5, "Result >>> Line >>> '".$output[$i]."'"); # TODO: remove
- if($output[$i]=~ /^\[~\]/) {undef ($output[$i]);}
- }
- #SYSMON_Log($hash, 5, "Result >>> vgrep >>>'".Dumper(@output)."'"); # TODO: remove
- @output = grep{ defined($_) && trim($_) ne '' }@output;
- #SYSMON_Log($hash, 5, "Result >>> ngrep >>>'".Dumper(@output)."'"); # TODO: remove
-
- return @output;
- ## Arrays als solche zurueckgeben
- #if(scalar(@output)>1) {
- # SYSMON_Log ($hash, 5, "Result '".Dumper(@output)."'");
- # return @output;
- #}
- ## Einzeiler als normale Scalars
- #my $line = @output[0];
- #chomp $line;
- #SYSMON_Log ($hash, 5, "Result '$line'");
- #return $line;
-
- #$result = $output[0];
- ##chomp $result;
- #my $log = join " ", @output;
- #chomp $log;
- #SYSMON_Log($hash, 5, "Result '$log'");
- #return $result;
- }
- # Executed the command on the remote Shell
- sub ############################################
- SYSMON_Exec_Local($$)
- {
- my ($hash, $cmd) = @_;
-
- SYSMON_Log($hash, 5, "Execute '".$cmd."'");
- #return qx($cmd);
- my @result = qx($cmd);
- # Arrays als solche zurueckgeben
- if(scalar(@result)>1) {
- SYSMON_Log ($hash, 5, "Result '".Dumper(@result)."'");
- return @result;
- }
- # Einzeiler als normale Scalars
- my $line = $result[0];
-
- if(defined($line)) {
- chomp $line;
- SYSMON_Log ($hash, 5, "Result '$line'");
- } else {
- SYSMON_Log ($hash, 5, "Result undef");
- }
- return $line;
-
- #chomp $result;
- #SYSMON_Log ($hash, 5, "Result '$result'");
- #return $result;
- }
- # Executed the command on the remote SSH Shell
- sub ############################################
- SYSMON_Exec_Ssh($$)
- {
- my ($hash, $cmd) = @_;
-
- my $msg;
- my $host = $hash->{HOST};#AttrVal( $name, "remote_host", undef );
- if(!defined $host) {
- $msg="Error: no remote host provided";
- SYSMON_Log($hash, 3, $msg);
- return $msg unless defined $host;
- }
- my $pwd = SYSMON_readPassword($hash);#AttrVal( $name, "remote_password", undef );
- my $t_sshpass = '';
- if(defined($pwd)) {
- #$msg="Error: no passwort provided";
- #SYSMON_Log($hash, 3, $msg);
- #return $msg unless defined $pwd;
- $t_sshpass = 'echo '.$pwd.' | sshpass ';
- #$t_sshpass = 'sshpass -p '.$pwd.' ';
- }
- my $user = $hash->{USER};#AttrVal( $name, "remote_user", "" );
- my $port = $hash->{PORT};#AttrVal( $name, "remote_port", "22" );
-
- SYSMON_Log($hash, 5, "Execute '".$cmd."' by SSH");
- my $p_tmp = '';
- if(!defined($port)) {
- $p_tmp = ' -p '.$port.' ';
- }
-
- my $call = "ssh ".$p_tmp.$user."\@".$host." ".$cmd;
- SYSMON_Log ($hash, 5, "Call: '".$call."'");
- $call = $t_sshpass.$call;
-
- # $call = $call.' 2>/dev/null';
-
- my @result = qx($call);
- # Arrays als solche zurueckgeben
- if(scalar(@result)>1) {
- SYSMON_Log ($hash, 5, "Result '".Dumper(@result)."'");
- return @result;
- }
- # Einzeiler als normale Scalars
- my $line = $result[0];
-
- if(defined($line)) {
- chomp $line;
- SYSMON_Log ($hash, 5, "Result '$line'");
- } else {
- SYSMON_Log ($hash, 5, "Result undef");
- }
- return $line;
-
- #chomp $result;
- #SYSMON_Log ($hash, 5, "Result '$result'");
- #return $result;
- }
- #------------------------------------------------------------------------------
- #------------------------------------------------------------------------------
- # Uebersetzt Sekunden (Dauer) in Tage/Stunden/Minuten/Sekunden
- #------------------------------------------------------------------------------
- sub SYSMON_decode_time_diff($)
- {
- my $s = shift;
- my $d = int($s/86400);
- $s -= $d*86400;
- my $h = int($s/3600);
- $s -= $h*3600;
- my $m = int($s/60);
- #$s -= $m*60;
- #return ($d,$h,$m,$s);
- return ($d,$h,$m);
- }
- #------------------------------------------------------------------------------
- # Logging: Funkrionsaufrufe
- # Parameter: HASH, Funktionsname, Message
- #------------------------------------------------------------------------------
- #sub logF($$$)
- #{
- # my ($hash, $fname, $msg) = @_;
- # #Log 5, "SYSMON $fname (".$hash->{NAME}."): $msg";
- # Log 5, "SYSMON $fname $msg";
- #}
- sub SYSMON_Log($$$) {
- my ( $hash, $loglevel, $text ) = @_;
- my $xline = ( caller(0) )[2];
-
- my $xsubroutine = ( caller(1) )[3];
- my $sub = ( split( ':', $xsubroutine ) )[2];
- $sub =~ s/SYSMON_//;
- my $instName = ( ref($hash) eq "HASH" ) ? $hash->{NAME} : $hash;
- $instName="" unless $instName;
- Log3 $hash, $loglevel, "SYSMON $instName: $sub.$xline " . $text;
- }
- # -----------------------------------------------------------------------------
- 1;
- =pod
- =item device
- =item summary provides some statistics about the system
- =item summary_DE liefert einige Statistiken ueber das Host-System
- =begin html
- <!-- ================================ -->
- <a name="SYSMON"></a>
- <h3>SYSMON</h3>
- (en | <a href="commandref_DE.html#SYSMON">de</a>)
- <ul>
- This module provides statistics about the system running FHEM server. Furthermore, remote systems can be accessed (Telnet). Only Linux-based systems are supported.
- Some informations are hardware specific and are not available on every platform.
- So far, this module has been tested on the following systems:
- Raspberry Pi (Debian Wheezy), BeagleBone Black, FritzBox 7390, WR703N under OpenWrt, CubieTruck and some others.
- <br><br>
- For more information on a FritzBox check other moduls: <a href="#FRITZBOX">FRITZBOX</a> and <a href="#FB_CALLMONITOR">FB_CALLMONITOR</a>.
- <br>
- <i>The modul uses the Perl modul 'Net::Telnet' for remote access. Please make sure that this module is installed.</i>
- <br><br>
- <b>Define</b>
- <br><br>
- <code>define <name> SYSMON [MODE[:[USER@]HOST][:PORT]] [<M1>[ <M2>[ <M3>[ <M4>]]]]</code><br>
- <br>
- This statement creates a new SYSMON instance. The parameters M1 to M4 define the refresh interval for various Readings (statistics). The parameters are to be understood as multipliers for the time defined by INTERVAL_BASE. Because this time is fixed at 60 seconds, the Mx-parameter can be considered as time intervals in minutes.<br>
- If one (or more) of the multiplier is set to zero, the corresponding readings is deactivated.
- <br>
- <br>
- The parameters are responsible for updating the readings according to the following scheme:
- <ul>
- <li>M1: (Default: 1)<br>
- cpu_freq, cpu_temp, cpu_temp_avg, loadavg, stat_cpu, stat_cpu_diff, stat_cpu_percent, stat_cpu_text, power readings<br><br>
- </li>
- <li>M2: (Default: M1)<br>
- ram, swap<br>
- </li>
- <li>M3: (Default: M1)<br>
- eth0, eth0_diff, wlan0, wlan0_diff<br><br>
- </li>
- <li>M4: (Default: 10*M1)<br>
- Filesystem informations<br><br>
- </li>
- <li>The following parameters are always updated with the base interval (regardless of the Mx-parameter):<br>
- fhemuptime, fhemuptime_text, idletime, idletime_text, uptime, uptime_text, starttime, starttime_text<br><br>
- </li>
- </ul>
- To query a remote system at least the address (HOST) must be specified. Accompanied by the port and / or user name, if necessary. The password (if needed) has to be defined once with the command 'set password <password>'. For MODE parameter are 'telnet', 'ssh' and 'local' only allowed. 'local' does not require any other parameters and can also be omitted.
- <br>
- For SSH login with password, 'sshpass' must be installed (note: not recommended! Use public key authentication instead).
- For SSH login to work, a manual SSH connection to the remote machine from the FHEM-Acount may need to be done once
- (under whose rights FHEM runs) the fingerprint must be confirmed.
- <br>
- <br>
- <b>Readings:</b>
- <br><br>
- <ul>
- <li>cpu_core_count<br>
- CPU core count
- </li>
- <li>cpu_model_name<br>
- CPU model name
- </li>
- <li>cpu_bogomips<br>
- CPU Speed: BogoMIPS
- </li>
- <li>cpu_freq (and cpu1_freq for dual core systems)<br>
- CPU frequency
- </li>
- <br>
- <li>cpu_temp<br>
- CPU temperature
- </li>
- <br>
- <li>cpu_temp_avg<br>
- Average of the CPU temperature, formed over the last 4 values.
- </li>
- <br>
- <li>fhemuptime<br>
- Time (in seconds) since the start of FHEM server.
- </li>
- <br>
- <li>fhemuptime_text<br>
- Time since the start of the FHEM server: human-readable output (text representation).
- </li>
- <br>
- <li>fhemstarttime<br>
- Start time (in seconds since 1.1.1970 1:00:00) of FHEM server.
- </li>
- <br>
- <li>fhemstarttime_text<br>
- Start time of the FHEM server: human-readable output (text representation).
- </li>
- <br>
- <li>idletime<br>
- Time spent by the system since the start in the idle mode (period of inactivity).
- </li>
- <br>
- <li>idletime_text<br>
- The inactivity time of the system since system start in human readable form.
- </li>
- <br>
- <li>loadavg<br>
- System load (load average): 1 minute, 5 minutes and 15 minutes.
- </li>
- <br>
- <li>ram<br>
- memory usage.
- </li>
- <br>
- <li>swap<br>
- swap usage.
- </li>
- <br>
- <li>uptime<br>
- System uptime.
- </li>
- <br>
- <li>uptime_text<br>
- System uptime (human readable).
- </li>
- <br>
- <li>starttime<br>
- System starttime.
- </li>
- <br>
- <li>starttime_text<br>
- System starttime (human readable).
- </li>
- <br>
- <li>Network statistics<br>
- Statistics for the specified network interface about the data volumes transferred and the difference since the previous measurement.
- <br>
- Examples:<br>
- Amount of the transmitted data via interface eth0.<br>
- <code>eth0: RX: 940.58 MB, TX: 736.19 MB, Total: 1676.77 MB</code><br>
- Change of the amount of the transferred data in relation to the previous call (for eth0).<br>
- <code>eth0_diff: RX: 0.66 MB, TX: 0.06 MB, Total: 0.72 MB</code><br>
- IP and IP v6 adresses
- <code>eth0_ip 192.168.0.15</code><br>
- <code>eth0_ip6 fe85::49:4ff:fe85:f885/64</code><br>
- </li>
- <br>
- <li>Network Speed (if avialable)<br>
- speed of the network connection.
- <br>
- Examples:<br>
- <code>eth0_speed 100</code><br>
- </li>
- <br>
- <li>File system information<br>
- Usage of the desired file systems.<br>
- Example:<br>
- <code>fs_root: Total: 7340 MB, Used: 3573 MB, 52 %, Available: 3425 MB at /</code>
- </li>
- <br>
- <li>CPU utilization<br>
- Information about the utilization of CPUs.<br>
- Example:<br>
- <code>stat_cpu: 10145283 0 2187286 90586051 542691 69393 400342</code><br>
- <code>stat_cpu_diff: 2151 0 1239 2522 10 3 761</code><br>
- <code>stat_cpu_percent: 4.82 0.00 1.81 93.11 0.05 0.00 0.20</code><br>
- <code>stat_cpu_text: user: 32.17 %, nice: 0.00 %, sys: 18.53 %, idle: 37.72 %, io: 0.15 %, irq: 0.04 %, sirq: 11.38 %</code>
- </li>
- <br>
- <li>user defined<br>
- These readings provide output of commands, which are passed to the operating system or delivered by user defined functions.
- </li>
- <br>
- <b>FritzBox specific Readings</b>
- <li>wlan_state<br>
- WLAN state: on/off
- </li>
- <br>
- <li>wlan_guest_state<br>
- GuestWLAN state: on/off
- </li>
- <br>
- <li>internet_ip<br>
- current IP-Adresse
- </li>
- <br>
- <li>internet_state<br>
- state of the Internet connection: connected/disconnected
- </li>
- <br>
- <li>night_time_ctrl<br>
- state night time control (do not disturb): on/off
- </li>
- <br>
- <li>num_new_messages<br>
- Number of new Voice Mail messages
- </li>
- <br>
- <li>fw_version_info<br>
- Information on the installed firmware version: <VersionNum> <creation date> <time>
- </li>
- <br>
- <b>DSL Informations (FritzBox)</b>
- <li>dsl_rate<br>
- Information about the down und up stream rate
- </li>
- <br>
- <li>dsl_synctime<br>
- sync time with DSLAM
- </li>
- <br>
- <li>dsl_crc_15<br>
- number of uncorrectable errors (CRC) for the last 15 minutes
- </li>
- <br>
- <li>dsl_fec_15<br>
- number of correctable errors (FEC) for the last 15 minutes
- </li>
- <br>
- <b>Power Supply Readings</b>
- <li>power_ac_stat<br>
- status information to the AC socket: online (0|1), present (0|1), voltage, current<br>
- Example:<br>
- <code>power_ac_stat: 1 1 4.807 264</code><br>
- </li>
- <br>
- <li>power_ac_text<br>
- human readable status information to the AC socket<br>
- Example:<br>
- <code>power_ac_text ac: present / online, voltage: 4.807 V, current: 264 mA</code><br>
- </li>
- <br>
- <li>power_usb_stat<br>
- status information to the USB socket
- </li>
- <br>
- <li>power_usb_text<br>
- human readable status information to the USB socket
- </li>
- <br>
- <li>power_battery_stat<br>
- status information to the battery (if installed): online (0|1), present (0|1), voltage, current, actual capacity<br>
- Example:<br>
- <code>power_battery_stat: 1 1 4.807 264 100</code><br>
- </li>
- <br>
- <li>power_battery_text<br>
- human readable status information to the battery (if installed)
- </li>
- <br>
- <li>power_battery_info<br>
- human readable additional information to the battery (if installed): technology, capacity, status, health, total capacity<br>
- Example:<br>
- <code>power_battery_info: battery info: Li-Ion , capacity: 100 %, status: Full , health: Good , total capacity: 2100 mAh</code><br>
- The capacity must be defined in script.bin (e.g. ct-hdmi.bin). Parameter name pmu_battery_cap. Convert with bin2fex (bin2fex -> script.fex -> edit -> fex2bin -> script.bin).<br>
- </li>
- <br>
- <li>cpuX_freq_stat<br>
- Frequency statistics for CPU X: minimum, maximum and average values<br>
- Example:<br>
- <code>cpu0_freq_stat: 100 1000 900</code><br>
- </li>
- <br>
- <li>cpuX_idle_stat<br>
- Idle statistik for CPU X: minimum, maximum and average values<br>
- Example:<br>
- <code>cpu0_freq_stat: 23.76 94.74 90.75</code><br>
- </li>
- <br>
- <li>cpu[X]_temp_stat<br>
- Temperature statistik for CPU: minimum, maximum and average values<br>
- Example:<br>
- <code>cpu_temp_stat: 41.00 42.50 42.00</code><br>
- </li>
- <br>
- <li>ram_used_stat<br>
- RAM usage statistics: minimum, maximum and average values<br>
- Example:<br>
- <code>ram_used_stat: 267.55 1267.75 855.00</code><br>
- </li>
- <br>
- <li>swap_used_stat<br>
- SWAP usage statistics: minimum, maximum and average values<br>
- Example:<br>
- <code>swap_used_stat: 0 1024.00 250.00</code><br>
- </li>
- <br>
- <br>
- </ul>
- <br>
- <b>Get:</b><br><br>
- <ul>
- <li>interval_base<br>
- Lists the specified polling intervalls.
- </li>
- <br>
- <li>interval_multipliers<br>
- Displays update intervals.
- </li>
- <br>
- <li>list<br>
- Lists all readings.
- </li>
- <br>
- <li>update<br>
- Refreshs all readings.
- </li>
- <br>
- <li>version<br>
- Displays the version of SYSMON module.
- </li>
- <br>
- <li>list_lan_devices<br>
- Displays known LAN Devices (FritzBox only).
- </li>
- <br>
- </ul>
- <br>
- <b>Set:</b><br><br>
- <ul>
- <li>interval_multipliers<br>
- Defines update intervals (as in the definition of the device).
- </li>
- <br>
- <li>clean<br>
- Clears user-definable Readings. After an update (manual or automatic) new readings are generated.<br>
- </li>
- <br>
- <li>clear <reading name><br>
- Deletes the Reading entry with the given name. After an update this entry is possibly re-created (if defined). This mechanism allows the selective deleting unnecessary custom entries.<br>
- </li>
- <br>
- <li>password <Passwort><br>
- Specify the password for remote access (usually only necessary once).
- </li>
- <br>
- </ul>
- <br>
- <b>Attributes:</b><br><br>
- <ul>
- <li>filesystems <reading name>[:<mountpoint>[:<comment>]],...<br>
- Specifies the file system to be monitored (a comma-separated list). <br>
- Reading-name is used in the display and logging, the mount point is the basis of the evaluation, comment is relevant to the HTML display (see SYSMON_ShowValuesHTML)<br>
- Examples: <br>
- <code>/boot,/,/media/usb1</code><br>
- <code>fs_boot:/boot,fs_root:/:Root,fs_usb1:/media/usb1:USB-Stick</code><br>
- </li>
- <br>
- <li>network-interfaces <name>[:<interface>[:<comment>]],...<br>
- Comma-separated list of network interfaces that are to be monitored. Each entry consists of the Reading-name, the name of the Netwerk adapter and a comment for the HTML output (see SYSMON_ShowValuesHTML). If no colon is used, the value is used simultaneously as a Reading-name and interface name.<br>
- Example <code>ethernet:eth0:Ethernet,wlan:wlan0:WiFi</code><br>
- </li>
- <br>
- <li>user-defined <readingsName>:<Interval_Minutes>:<Comment>:<Cmd>,...<br>
- This comma-separated list defines user defined Readings with the following data: Reading name, refresh interval (in minutes), a Comment, and operating system command.
- <br>The os commands are executed according to the specified Intervals and are noted as Readings with the specified name. Comments are used for the HTML output (see SYSMON_ShowValuesHTML)..
- <br>All parameter parts are required!
- <br>It is important that the specified commands are executed quickly, because at this time the entire FHEM server is blocked!<br>
- If results of the long-running operations required, these should be set up as a CRON job and store results as a text file.<br><br>
- Example: Display of package updates for the operating system:<br>
- cron-Job:<br>
- <code> sudo apt-get update 2>/dev/null >/dev/null</code>
- <code> apt-get upgrade --dry-run| perl -ne '/(\d*)\s[upgraded|aktualisiert]\D*(\d*)\D*install|^ \S+.*/ and print "$1 aktualisierte, $2 neue Pakete"' 2>/dev/null > /opt/fhem/data/updatestatus.txt</code>
- <br>
- <code>uder-defined</code> attribute<br><code>sys_updates:1440:System Aktualisierungen:cat /opt/fhem/data/updatestatus.txt</code><br>
- the number of available updates is daily recorded as 'sys_updates'.
- </li>
- <br>
- <li>user-fn <fn_name>:<interval_minutes>:<reading_name1>:<reading_name2>...[:<reading_nameX>], ...<br>
- List of perl user subroutines.<br>
- As <fn_name> can be used either the name of a Perl subroutine or a Perl expression.
- The perl function gets the device hash as parameter and must provide an array of values.
- These values are taken according to the parameter <reading_nameX> in Readings.<br>
- A Perl expression must be enclosed in curly braces and can use the following parameters: $ HASH (device hash) and $ NAME (device name).
- Return is expected analogous to a Perl subroutine.<br>
- Important! The separation between multiple user functions must be done with a comma AND a space! Within the function definition commas may not be followed by spaces.
- </li>
- <br>
- <li>disable<br>
- Possible values: 0 and 1. '1' means that the update is stopped.
- </li>
- <br>
- <li>telnet-prompt-regx, telnet-login-prompt-regx<br>
- RegExp to detect login and command line prompt. (Only for access via Telnet.)
- </li>
- <br>
- <li>exclude<br>
- Allows to suppress reading certain information. <br>
- supported values: user-defined (s. user-defined und user-fn), cpucount, uptime, fhemuptime,
- loadavg, cputemp, cpufreq, cpuinfo, diskstat, cpustat, ramswap, filesystem, network,
- fbwlan, fbnightctrl, fbnewmessages, fbdecttemp, fbversion, fbdsl, powerinfo
- </li>
- <br>
- </ul>
- <br>
- <b>Plots:</b><br><br>
- <ul>
- predefined gplot files:<br>
- <ul>
- FileLog versions:<br>
- <code>
- SM_RAM.gplot<br>
- SM_CPUTemp.gplot<br>
- SM_FS_root.gplot<br>
- SM_FS_usb1.gplot<br>
- SM_Load.gplot<br>
- SM_Network_eth0.gplot<br>
- SM_Network_eth0t.gplot<br>
- SM_Network_wlan0.gplot<br>
- SM_CPUStat.gplot<br>
- SM_CPUStatSum.gplot<br>
- SM_CPUStatTotal.gplot<br>
- SM_power_ac.gplot<br>
- SM_power_usb.gplot<br>
- SM_power_battery.gplot<br>
- </code>
- DbLog versions:<br>
- <code>
- SM_DB_all.gplot<br>
- SM_DB_CPUFreq.gplot<br>
- SM_DB_CPUTemp.gplot<br>
- SM_DB_Load.gplot<br>
- SM_DB_Network_eth0.gplot<br>
- SM_DB_RAM.gplot<br>
- </code>
- </ul>
- </ul>
- <br>
- <b>HTML output method (see Weblink): SYSMON_ShowValuesHTML(<SYSMON-Instance>[,<Liste>])</b><br><br>
- <ul>
- The module provides a function that returns selected Readings as HTML.<br>
- As a parameter the name of the defined SYSMON device is expected.<br>
- It can also Reading Group, Clone dummy or other modules be used. Their readings are simple used for display. <br>
- The second parameter is optional and specifies a list of readings to be displayed in the format <code><ReadingName>[:<Comment>[:<Postfix>[:<FormatString>]]]</code>.<br>
- <code>ReadingName</code> is the Name of desired Reading, <code>Comment</code> is used as the display name and postfix is displayed after the value (such as units or as MHz can be displayed).
- If FormatString is specified, the output is formatted with sprintf (s. sprintf in Perl documentation).<br>
- If no <code>Comment</code> is specified, an internally predefined description is used.<br>
- If no list specified, a predefined selection is used (all values are displayed).<br><br>
- <code>define sysv1 weblink htmlCode {SYSMON_ShowValuesHTML('sysmon')}</code><br>
- <code>define sysv2 weblink htmlCode {SYSMON_ShowValuesHTML('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C:%.1f'', 'cpu_freq:CPU Frequenz: MHz'))}</code>
- </ul>
- <br>
- <b>Text output method (see Weblink): SYSMON_ShowValuesHTMLTitled(<SYSMON-Instance>[,<Title>,<Liste>])</b><br><br>
- <ul>
- According to SYSMON_ShowValuesHTML, but with a Title text above. If no title provided, device alias will be used (if any)<br>
- </ul>
- <br>
- <b>Text output method (see Weblink): SYSMON_ShowValuesText(<SYSMON-Instance>[,<Liste>])</b><br><br>
- <ul>
- According to SYSMON_ShowValuesHTML, but formatted as plain text.<br>
- </ul>
- <br>
- <b>Text output method (see Weblink): SYSMON_ShowValuesTextTitled(<SYSMON-Instance>[,<Title>,<Liste>])</b><br><br>
- <ul>
- According to SYSMON_ShowValuesHTMLTitled, but formatted as plain text.<br>
- </ul>
- <br>
- <b>Reading values with perl: SYSMON_getValues(<name>[, <array of desired keys>])</b><br><br>
- <ul>
- Returns a hash ref with desired values. If no array is passed, all values are returned.<br>
- {(SYSMON_getValues("sysmon"))->{'cpu_temp'}}<br>
- {(SYSMON_getValues("sysmon",("cpu_freq","cpu_temp")))->{"cpu_temp"}}<br>
- {join(" ", values (SYSMON_getValues("sysmon")))}<br>
- {join(" ", values (SYSMON_getValues("sysmon",("cpu_freq","cpu_temp"))))}<br>
- </ul>
- <br>
- <b>Examples:</b><br><br>
- <ul>
- <code>
- # Modul-Definition<br>
- define sysmon SYSMON 1 1 1 10<br>
- #attr sysmon event-on-update-reading cpu_temp,cpu_temp_avg,cpu_freq,eth0_diff,loadavg,ram,^~ /.*usb.*,~ /$<br>
- attr sysmon event-on-update-reading cpu_temp,cpu_temp_avg,cpu_freq,eth0_diff,loadavg,ram,fs_.*,stat_cpu_percent<br>
- attr sysmon filesystems fs_boot:/boot,fs_root:/:Root,fs_usb1:/media/usb1:USB-Stick<br>
- attr sysmon network-interfaces eth0:eth0:Ethernet,wlan0:wlan0:WiFi<br>
- attr sysmon group RPi<br>
- attr sysmon room 9.03_Tech<br>
- <br>
- # Log<br>
- define FileLog_sysmon FileLog ./log/sysmon-%Y-%m.log sysmon<br>
- attr FileLog_sysmon group RPi<br>
- attr FileLog_sysmon logtype SM_CPUTemp:Plot,text<br>
- attr FileLog_sysmon room 9.03_Tech<br>
- <br>
- # Visualisierung: CPU-Temperatur<br>
- define wl_sysmon_temp SVG FileLog_sysmon:SM_CPUTemp:CURRENT<br>
- attr wl_sysmon_temp group RPi<br>
- attr wl_sysmon_temp label "CPU Temperatur: Min $data{min2}, Max $data{max2}, Last $data{currval2}"<br>
- attr wl_sysmon_temp room 9.03_Tech<br>
- <br>
- # Visualisierung: Netzwerk-Datenübertragung für eth0<br>
- define wl_sysmon_eth0 SVG FileLog_sysmon:SM_Network_eth0:CURRENT<br>
- attr wl_sysmon_eth0 group RPi<br>
- attr wl_sysmon_eth0 label "Netzwerk-Traffic eth0: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_eth0 room 9.03_Tech<br>
- <br>
- # Visualisierung: Netzwerk-Datenübertragung für wlan0<br>
- define wl_sysmon_wlan0 SVG FileLog_sysmon:SM_Network_wlan0:CURRENT<br>
- attr wl_sysmon_wlan0 group RPi<br>
- attr wl_sysmon_wlan0 label "Netzwerk-Traffic wlan0: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_wlan0 room 9.03_Tech<br>
- <br>
- # Visualisierung: CPU-Auslastung (load average)<br>
- define wl_sysmon_load SVG FileLog_sysmon:SM_Load:CURRENT<br>
- attr wl_sysmon_load group RPi<br>
- attr wl_sysmon_load label "Load Min: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_load room 9.03_Tech<br>
- <br>
- # Visualisierung: RAM-Nutzung<br>
- define wl_sysmon_ram SVG FileLog_sysmon:SM_RAM:CURRENT<br>
- attr wl_sysmon_ram group RPi<br>
- attr wl_sysmon_ram label "RAM-Nutzung Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_ram room 9.03_Tech<br>
- <br>
- # Visualisierung: Dateisystem: Root-Partition<br>
- define wl_sysmon_fs_root SVG FileLog_sysmon:SM_FS_root:CURRENT<br>
- attr wl_sysmon_fs_root group RPi<br>
- attr wl_sysmon_fs_root label "Root Partition Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_fs_root room 9.03_Tech<br>
- <br>
- # Visualisierung: Dateisystem: USB-Stick<br>
- define wl_sysmon_fs_usb1 SVG FileLog_sysmon:SM_FS_usb1:CURRENT<br>
- attr wl_sysmon_fs_usb1 group RPi<br>
- attr wl_sysmon_fs_usb1 label "USB1 Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_fs_usb1 room 9.03_Tech<br>
- <br>
- # Anzeige der Readings zum Einbinden in ein 'Raum'.<br>
- define SysValues weblink htmlCode {SYSMON_ShowValuesHTML('sysmon')}<br>
- attr SysValues group RPi<br>
- attr SysValues room 9.03_Tech<br>
- <br>
- # Anzeige CPU Auslasung<br>
- define wl_sysmon_cpustat SVG FileLog_sysmon:SM_CPUStat:CURRENT<br>
- attr wl_sysmon_cpustat label "CPU(min/max): user:$data{min1}/$data{max1} nice:$data{min2}/$data{max2} sys:$data{min3}/$data{max3} idle:$data{min4}/$data{max4} io:$data{min5}/$data{max5} irq:$data{min6}/$data{max6} sirq:$data{min7}/$data{max7}"<br>
- attr wl_sysmon_cpustat group RPi<br>
- attr wl_sysmon_cpustat room 9.99_Test<br>
- attr wl_sysmon_cpustat plotsize 840,420<br>
- define wl_sysmon_cpustat_s SVG FileLog_sysmon:SM_CPUStatSum:CURRENT<br>
- attr wl_sysmon_cpustat_s label "CPU(min/max): user:$data{min1}/$data{max1} nice:$data{min2}/$data{max2} sys:$data{min3}/$data{max3} idle:$data{min4}/$data{max4} io:$data{min5}/$data{max5} irq:$data{min6}/$data{max6} sirq:$data{min7}/$data{max7}"<br>
- attr wl_sysmon_cpustat_s group RPi<br>
- attr wl_sysmon_cpustat_s room 9.99_Test<br>
- attr wl_sysmon_cpustat_s plotsize 840,420<br>
- define wl_sysmon_cpustatT SVG FileLog_sysmon:SM_CPUStatTotal:CURRENT<br>
- attr wl_sysmon_cpustatT label "CPU-Auslastung"<br>
- attr wl_sysmon_cpustatT group RPi<br>
- attr wl_sysmon_cpustatT plotsize 840,420<br>
- attr wl_sysmon_cpustatT room 9.99_Test<br>
- <br>
- # Anzeige Stromversorgung AC<br>
- define wl_sysmon_power_ac SVG FileLog_sysmon:SM_power_ac:CURRENT<br>
- attr wl_sysmon_power_ac label "Stromversorgung (ac) Spannung: $data{min1} - $data{max1} V, Strom: $data{min2} - $data{max2} mA"<br>
- attr wl_sysmon_power_ac room Technik<br>
- attr wl_sysmon_power_ac group system<br>
- # Anzeige Stromversorgung Battery<br>
- define wl_sysmon_power_bat SVG FileLog_sysmon:SM_power_battery:CURRENT<br>
- attr wl_sysmon_power_bat label "Stromversorgung (bat) Spannung: $data{min1} - $data{max1} V, Strom: $data{min2} - $data{max2} mA"<br>
- attr wl_sysmon_power_bat room Technik<br>
- attr wl_sysmon_power_bat group system<br>
- </code>
- </ul>
- </ul>
- <!-- ================================ -->
- =end html
- =begin html_DE
- <a name="SYSMON"></a>
- <h3>SYSMON</h3>
- (<a href="commandref.html#SYSMON">en</a> | de)
- <ul>
- Dieses Modul liefert diverse Informationen und Statistiken zu dem System, auf dem FHEM-Server ausgeführt wird.
- Weiterhin können auch Remote-Systeme abgefragt werden (Telnet).
- Es werden nur Linux-basierte Systeme unterstützt. Manche Informationen sind hardwarespezifisch und sind daher nicht auf jeder Plattform
- verfügbar.
- Bis jetzt wurde dieses Modul auf folgenden Systemen getestet: Raspberry Pi (Debian Wheezy), BeagleBone Black,
- FritzBox 7390, WR703N unter OpenWrt, CubieTruck und einige andere.
- <br>
- <br>
- Für Informationen zu einer FritzBox beachten Sie bitte auch Module: <a href="#FRITZBOX">FRITZBOX</a> und <a href="#FB_CALLMONITOR">FB_CALLMONITOR</a>.
- <i>Das Modul nutzt das Perlmodule 'Net::Telnet' für den Fernzugriff. Dieses muss ggf. nachinstalliert werden.</i>
- <br><br>
- <b>Define</b>
- <br><br>
- <code>define <name> SYSMON [MODE[:[USER@]HOST][:PORT]] [<M1>[ <M2>[ <M3>[ <M4>]]]]</code><br>
- <br>
- Diese Anweisung erstellt eine neue SYSMON-Instanz.
- Die Parameter M1 bis M4 legen die Aktualisierungsintervalle für verschiedenen Readings (Statistiken) fest.
- Die Parameter sind als Multiplikatoren für die Zeit, die durch INTERVAL_BASE definiert ist, zu verstehen.
- Da diese Zeit fest auf 60 Sekunden gesetzt ist, können die Mx-Parameters als Zeitintervalle in Minuten angesehen werden.<br>
- Wird einer (oder mehrere) Multiplikatoren auf Null gesetzt werden, wird das entsprechende Readings deaktiviert.<br>
- <br>
- Die Parameter sind für die Aktualisierung der Readings nach folgender Schema zuständig:
- <ul>
- <li>M1: (Default-Wert: 1)<br>
- cpu_freq, cpu_temp, cpu_temp_avg, loadavg, stat_cpu, stat_cpu_diff, stat_cpu_percent, stat_cpu_text, power readings<br><br>
- </li>
- <li>M2: (Default-Wert: M1)<br>
- ram, swap<br>
- </li>
- <li>M3: (Default-Wert: M1)<br>
- eth0, eth0_diff, wlan0, wlan0_diff<br><br>
- </li>
- <li>M4: (Default-Wert: 10*M1)<br>
- Filesystem-Informationen<br><br>
- </li>
- <li>folgende Parameter werden immer anhand des Basisintervalls (unabhängig von den Mx-Parameters) aktualisiert:<br>
- fhemuptime, fhemuptime_text, idletime, idletime_text, uptime, uptime_text, starttime, starttime_text<br><br>
- </li>
- </ul>
- Für Abfrage eines entfernten Systems muss mindestens deren Adresse (HOST) angegeben werden, bei Bedarf ergänzt durch den Port und/oder den Benutzernamen.
- Das eventuell benötigte Passwort muss einmalig mit dem Befehl 'set password <pass>' definiert werden.
- Als MODE sind derzeit 'telnet', 'ssh' und 'local' erlaubt. 'local' erfordert keine weiteren Angaben und kann auch ganz weggelassen werden.
- <br>
- Bei SSH-Anmeldung mit Passwort muss 'sshpass' installiert sein (Achtung! Sicherheitstechnisch nicht empfehlenswert! Besser Public-Key-Verfahren benutzen).
- Damit SSH-Anmeldung funktioniert, muss ggf. einmalig eine manuelle SSH-Verbindung an die Remote-Machine von dem FHEM-Acount
- (unter dessen Rechten FHEM läuft) durchgeführt und fingerprint bestätigt werden.
- <br>
- <br>
- <b>Readings:</b>
- <br><br>
- <ul>
- <li>cpu_core_count<br>
- Anzahl der CPU Kerne
- </li>
- <li>cpu_model_name<br>
- CPU Modellname
- </li>
- <li>cpu_bogomips<br>
- CPU Speed: BogoMIPS
- </li>
- <li>cpu_freq (auf den DualCore-Systemen wie Cubietruck auch cpu1_freq)<br>
- CPU-Frequenz
- </li>
- <br>
- <li>cpu_temp<br>
- CPU-Temperatur
- </li>
- <br>
- <li>cpu_temp_avg<br>
- Durchschnitt der CPU-Temperatur, gebildet über die letzten 4 Werte.
- </li>
- <br>
- <li>fhemuptime<br>
- Zeit (in Sekunden) seit dem Start des FHEM-Servers.
- </li>
- <br>
- <li>fhemuptime_text<br>
- Zeit seit dem Start des FHEM-Servers: Menschenlesbare Ausgabe (texttuelle Darstellung).
- </li>
- <br>
- <li>fhemstarttime<br>
- Startzeit (in Sekunden seit 1.1.1970 1:00:00) des FHEM-Servers.
- </li>
- <br>
- <li>fhemstarttime_text<br>
- Startzeit des FHEM-Servers: Menschenlesbare Ausgabe (texttuelle Darstellung).
- </li>
- <br>
- <li>idletime<br>
- Zeit (in Sekunden und in Prozent), die das System (nicht der FHEM-Server!)
- seit dem Start in dem Idle-Modus verbracht hat. Also die Zeit der Inaktivität.
- </li>
- <br>
- <li>idletime_text<br>
- Zeit der Inaktivität des Systems seit dem Systemstart in menschenlesbarer Form.
- </li>
- <br>
- <li>loadavg<br>
- Ausgabe der Werte für die Systemauslastung (load average): 1 Minute-, 5 Minuten- und 15 Minuten-Werte.
- </li>
- <br>
- <li>ram<br>
- Ausgabe der Speicherauslastung.
- </li>
- <br>
- <li>swap<br>
- Benutzung und Auslastung der SWAP-Datei (bzw. Partition).
- </li>
- <br>
- <li>uptime<br>
- Zeit (in Sekenden) seit dem Systemstart.
- </li>
- <br>
- <li>uptime_text<br>
- Zeit seit dem Systemstart in menschenlesbarer Form.
- </li>
- <br>
- <li>starttime<br>
- Systemstart (Sekunden seit Thu Jan 1 01:00:00 1970).
- </li>
- <br>
- <li>starttime_text<br>
- Systemstart in menschenlesbarer Form.
- </li>
- <br>
- <li>Netzwerkinformationen<br>
- Informationen zu den über die angegebene Netzwerkschnittstellen übertragene Datenmengen
- und der Differenz zu der vorherigen Messung.
- <br>
- Beispiele:<br>
- Menge der übertragenen Daten über die Schnittstelle eth0.<br>
- <code>eth0: RX: 940.58 MB, TX: 736.19 MB, Total: 1676.77 MB</code><br>
- Änderung der übertragenen Datenmenge in Bezug auf den vorherigen Aufruf (für eth0).<br>
- <code>eth0_diff: RX: 0.66 MB, TX: 0.06 MB, Total: 0.72 MB</code><br>
- IP and IP v6 Adressen
- <code>eth0_ip 192.168.0.15</code><br>
- <code>eth0_ip6 fe85::49:4ff:fe85:f885/64</code><br>
- </li>
- <br>
- <li>Network Speed (wenn verfügbar)<br>
- Geschwindigkeit der aktuellen Netzwerkverbindung.
- <br>
- Beispiel:<br>
- <code>eth0_speed 100</code><br>
- </li>
- <br>
- <li>Dateisysteminformationen<br>
- Informationen zu der Größe und der Belegung der gewünschten Dateisystemen.<br>
- Seit Version 1.1.0 können Dateisysteme auch benannt werden (s.u.). <br>
- In diesem Fall werden für die diese Readings die angegebenen Namen verwendet.<br>
- Dies soll die Übersicht verbessern und die Erstellung von Plots erleichten.<br>
- Beispiel:<br>
- <code>fs_root: Total: 7340 MB, Used: 3573 MB, 52 %, Available: 3425 MB at /</code>
- </li>
- <br>
- <li>CPU Auslastung<br>
- Informationen zu der Auslastung der CPU(s).<br>
- Beispiel:<br>
- <code>stat_cpu: 10145283 0 2187286 90586051 542691 69393 400342</code><br>
- <code>stat_cpu_diff: 2151 0 1239 2522 10 3 761</code><br>
- <code>stat_cpu_percent: 4.82 0.00 1.81 93.11 0.05 0.00 0.20</code><br>
- <code>stat_cpu_text: user: 32.17 %, nice: 0.00 %, sys: 18.53 %, idle: 37.72 %, io: 0.15 %, irq: 0.04 %, sirq: 11.38 %</code>
- </li>
- <br>
- <li>Benutzerdefinierte Einträge<br>
- Diese Readings sind Ausgaben der Kommanden, die an das Betriebssystem übergeben werden.
- Die entsprechende Angaben werden durch Attributen <code>user-defined</code> und <code>user-fn</code> definiert.
- </li>
- <br>
- <b>FritzBox-spezifische Readings</b>
- <li>wlan_state<br>
- WLAN-Status: on/off
- </li>
- <br>
- <li>wlan_guest_state<br>
- Gast-WLAN-Status: on/off
- </li>
- <br>
- <li>internet_ip<br>
- aktuelle IP-Adresse
- </li>
- <br>
- <li>internet_state<br>
- Status der Internetverbindung: connected/disconnected
- </li>
- <br>
- <li>night_time_ctrl<br>
- Status der Klingelsperre on/off
- </li>
- <br>
- <li>num_new_messages<br>
- Anzahl der neuen Anrufbeantworter-Meldungen
- </li>
- <br>
- <li>fw_version_info<br>
- Angaben zu der installierten Firmware-Version: <VersionNr> <Erstelldatum> <Zeit>
- </li>
- <br>
- <b>DSL Informationen (FritzBox)</b>
- <li>dsl_rate<br>
- Down/Up Verbindungsgeschwindigkeit
- </li>
- <br>
- <li>dsl_synctime<br>
- Sync-Zeit mit Vermittlungsstelle
- </li>
- <br>
- <li>dsl_crc_15<br>
- Nicht behebbare Übertragungsfehler in den letzten 15 Minuten
- </li>
- <br>
- <li>dsl_fec_15<br>
- Behebbare Übertragungsfehler in den letzten 15 Minuten
- </li>
- <br>
- <b>Readings zur Stromversorgung</b>
- <li>power_ac_stat<br>
- Statusinformation für die AC-Buchse: online (0|1), present (0|1), voltage, current<br>
- Beispiel:<br>
- <code>power_ac_stat: 1 1 4.807 264</code><br>
- </li>
- <br>
- <li>power_ac_text<br>
- Statusinformation für die AC-Buchse in menschenlesbarer Form<br>
- Beispiel:<br>
- <code>power_ac_text ac: present / online, Voltage: 4.807 V, Current: 264 mA</code><br>
- </li>
- <br>
- <li>power_usb_stat<br>
- Statusinformation für die USB-Buchse
- </li>
- <br>
- <li>power_usb_text<br>
- Statusinformation für die USB-Buchse in menschenlesbarer Form
- </li>
- <br>
- <li>power_battery_stat<br>
- Statusinformation für die Batterie (wenn vorhanden): online (0|1), present (0|1), voltage, current, actual capacity<br>
- Beispiel:<br>
- <code>power_battery_stat: 1 1 4.807 264 100</code><br>
- </li>
- <br>
- <li>power_battery_text<br>
- Statusinformation für die Batterie (wenn vorhanden) in menschenlesbarer Form
- </li>
- <br>
- <li>power_battery_info<br>
- Menschenlesbare Zusatzinformationen für die Batterie (wenn vorhanden): Technologie, Kapazität, Status, Zustand, Gesamtkapazität<br>
- Beispiel:<br>
- <code>power_battery_info: battery info: Li-Ion , capacity: 100 %, status: Full , health: Good , total capacity: 2100 mAh</code><br>
- Die Kapazität soll in script.bin (z.B. ct-hdmi.bin) eingestellt werden (Parameter pmu_battery_cap). Mit bin2fex konvertieren (bin2fex -> script.fex -> edit -> fex2bin -> script.bin)<br>
- </li>
- <br>
- <li>cpuX_freq_stat<br>
- Frequenz-Statistik für die CPU X: Minimum, Maximum und Durchschnittswert<br>
- Beispiel:<br>
- <code>cpu0_freq_stat: 100 1000 900</code><br>
- </li>
- <br>
- <li>cpuX_idle_stat<br>
- Leerlaufzeit-Statistik für die CPU X: Minimum, Maximum und Durchschnittswert<br>
- Beispiel:<br>
- <code>cpu0_freq_stat: 23.76 94.74 90.75</code><br>
- </li>
- <br>
- <li>cpu[X]_temp_stat<br>
- Temperatur-Statistik für CPU: Minimum, Maximum und Durchschnittswert<br>
- Beispiel:<br>
- <code>cpu_temp_stat: 41.00 42.50 42.00</code><br>
- </li>
- <br>
- <li>ram_used_stat<br>
- Statistik der RAM-Nutzung: Minimum, Maximum und Durchschnittswert<br>
- Example:<br>
- <code>ram_used_stat: 267.55 1267.75 855.00</code><br>
- </li>
- <br>
- <li>swap_used_stat<br>
- Statistik der SWAP-Nutzung: Minimum, Maximum und Durchschnittswert<br>
- Example:<br>
- <code>swap_used_stat: 0 1024.00 250.00</code><br>
- </li>
- <br>
- <br>
- </ul>
- <br>
- <b>Get:</b><br><br>
- <ul>
- <li>interval<br>
- Listet die bei der Definition angegebene Polling-Intervalle auf.
- </li>
- <br>
- <li>interval_multipliers<br>
- Listet die definierten Multipliers.
- </li>
- <br>
- <li>list<br>
- Gibt alle Readings aus.
- </li>
- <br>
- <li>update<br>
- Aktualisiert alle Readings. Alle Werte werden neu abgefragt.
- </li>
- <br>
- <li>version<br>
- Zeigt die Version des SYSMON-Moduls.
- </li>
- <br>
- <br>
- <li>list_lan_devices<br>
- Listet bekannte Geräte im LAN (nur FritzBox).
- </li>
- </ul>
- <br>
- <b>Set:</b><br><br>
- <ul>
- <li>interval_multipliers<br>
- Definiert Multipliers (wie bei der Definition des Gerätes).
- </li>
- <br>
- <li>clean<br>
- Löscht benutzerdefinierbare Readings. Nach einem Update (oder nach der automatischen Aktualisierung) werden neue Readings generiert.<br>
- </li>
- <br>
- <li>clear <reading name><br>
- Löscht den Reading-Eintrag mit dem gegebenen Namen. Nach einem Update (oder nach der automatischen Aktualisierung)
- wird dieser Eintrag ggf. neu erstellt (falls noch definiert). Dieses Mechanismus erlaubt das gezielte Löschen nicht mehr benötigter
- benutzerdefinierten Einträge.<br>
- </li>
- <br>
- <li>password <Passwort><br>
- Definiert das Passwort für den Remote-Zugriff (i.d.R. nur einmalig notwendig).
- </li>
- <br>
- </ul>
- <br>
- <b>Attributes:</b><br><br>
- <ul>
- <li>filesystems <reading name>[:<mountpoint>[:<comment>]],...<br>
- Gibt die zu überwachende Dateisysteme an. Es wird eine kommaseparierte Liste erwartet.<br>
- Reading-Name wird bei der Anzeige und Logging verwendet, Mount-Point ist die Grundlage der Auswertung,
- Kommentar ist relevant für die HTML-Anzeige (s. SYSMON_ShowValuesHTML)<br>
- Beispiel: <code>/boot,/,/media/usb1</code><br>
- oder: <code>fs_boot:/boot,fs_root:/:Root,fs_usb1:/media/usb1:USB-Stick</code><br>
- Im Sinne der besseren Übersicht sollten zumindest Name und MountPoint angegeben werden.
- </li>
- <br>
- <li>network-interfaces <name>[:<interface>[:<comment>]],...<br>
- Kommaseparierte Liste der Netzwerk-Interfaces, die überwacht werden sollen.
- Jeder Eintrag besteht aus dem Reading-Namen, dem Namen
- des Netwerk-Adapters und einem Kommentar für die HTML-Anzeige (s. SYSMON_ShowValuesHTML). Wird kein Doppelpunkt verwendet,
- wird der Wert gleichzeitig als Reading-Name und Interface-Name verwendet.<br>
- Beispiel <code>ethernet:eth0:Ethernet,wlan:wlan0:WiFi</code><br>
- </li>
- <br>
- <li>user-defined <readingsName>:<Interval_Minutes>:<Comment>:<Cmd>,...<br>
- Diese kommaseparierte Liste definiert Einträge mit jeweils folgenden Daten:
- Reading-Name, Aktualisierungsintervall in Minuten, Kommentar und Betriebssystem-Commando.
- <br>Die BS-Befehle werden entsprechend des angegebenen Intervalls ausgeführt und als Readings mit den angegebenen Namen vermerkt.
- Kommentare werden für die HTML-Ausgaben (s. SYSMON_ShowValuesHTML) benötigt.
- <br>Alle Parameter sind nicht optional!
- <br>Es ist wichtig, dass die angegebenen Befehle schnell ausgeführt werden, denn in dieser Zeit wird der gesamte FHEM-Server blockiert!
- <br>Werden Ergebnisse der lang laufenden Operationen benötigt, sollten diese z.B als CRON-Job eingerichtet werden
- und in FHEM nur die davor gespeicherten Ausgaben visualisiert.<br><br>
- Beispiel: Anzeige der vorliegenden Paket-Aktualisierungen für das Betriebssystem:<br>
- In einem cron-Job wird folgendes täglich ausgeführt: <br>
- <code> sudo apt-get update 2>/dev/null >/dev/null</code>
- <code> apt-get upgrade --dry-run| perl -ne '/(\d*)\s[upgraded|aktualisiert]\D*(\d*)\D*install|^ \S+.*/ and print "$1 aktualisierte, $2 neue Pakete"' 2>/dev/null > /opt/fhem/data/updatestatus.txt</code>
- <br>
- Das Attribute <code>uder-defined</code> wird auf <br><code>sys_updates:1440:System Aktualisierungen:cat /opt/fhem/data/updatestatus.txt</code><br> gesetzt.
- Danach wird die Anzahl der verfügbaren Aktualisierungen täglich als Reading 'sys_updates' protokolliert.
- </li>
- <br>
- <li>user-fn <fn_name>:<Interval_Minutes>:<reading_name1>:<reading_name2>...[:<reading_nameX>],...<br>
- Liste der benutzerdefinierten Perlfunktionen.<br>
- Als <fn_name> können entweder Name einer Perlfunktion oder ein Perlausdruck verwendet werden.
- Die Perlfunktion bekommt den Device-Hash als Übergabeparameter und muss ein Array mit Werte liefern.
- Diese Werte werden entsprechend den Parameter <reading_nameX> in Readings übernommen.<br>
- Ein Perlausdruck muss in geschweifte Klammer eingeschlossen werden und kann folgende Paramter verwenden: $HASH (Device-Hash) und $NAME (Device-Name).
- Rückgabe wird analog einer Perlfunktion erwartet.<br>
- Wichtig! Die Trennung zwischen mehreren Benutzerfunktionen muss mit einem Komma UND einem Leerzeichen erfolgen! Innerhalb der Funktiondefinition dürfen Kommas nicht durch Leerzeichen gefolgt werden.
- </li>
- <br>
- <li>disable<br>
- Mögliche Werte: <code>0,1</code>. Bei <code>1</code> wird die Aktualisierung gestoppt.
- </li>
- <br>
- <li>telnet-prompt-regx, telnet-login-prompt-regx<br>
- RegExp zur Erkennung von Login- und Kommandozeile-Prompt. (Nur für Zugriffe über Telnet relevant.)
- </li>
- <br>
- <li>exclude<br>
- Erlaubt das Abfragen bestimmten Informationen zu unterbinden. <br>
- Mögliche Werte: user-defined (s. user-defined und user-fn), cpucount, uptime, fhemuptime,
- loadavg, cputemp, cpufreq, cpuinfo, diskstat, cpustat, ramswap, filesystem, network,
- fbwlan, fbnightctrl, fbnewmessages, fbdecttemp, fbversion, fbdsl, powerinfo
- </li>
- <br>
- </ul>
- <br>
- <b>Plots:</b><br><br>
- <ul>
- Für dieses Modul sind bereits einige gplot-Dateien vordefiniert:<br>
- <ul>
- FileLog-Versionen:<br>
- <code>
- SM_RAM.gplot<br>
- SM_CPUTemp.gplot<br>
- SM_FS_root.gplot<br>
- SM_FS_usb1.gplot<br>
- SM_Load.gplot<br>
- SM_Network_eth0.gplot<br>
- SM_Network_eth0t.gplot<br>
- SM_Network_wlan0.gplot<br>
- SM_CPUStat.gplot<br>
- SM_CPUStatSum.gplot<br>
- SM_CPUStatTotal.gplot<br>
- SM_power_ac.gplot<br>
- SM_power_usb.gplot<br>
- SM_power_battery.gplot<br>
- </code>
- DbLog-Versionen:<br>
- <code>
- SM_DB_all.gplot<br>
- SM_DB_CPUFreq.gplot<br>
- SM_DB_CPUTemp.gplot<br>
- SM_DB_Load.gplot<br>
- SM_DB_Network_eth0.gplot<br>
- SM_DB_RAM.gplot<br>
- </code>
- </ul>
- </ul>
- <br>
- <b>HTML-Ausgabe-Methode (für ein Weblink): SYSMON_ShowValuesHTML(<SYSMON-Instanz>[,<Liste>])</b><br><br>
- <ul>
- Das Modul definiert eine Funktion, die ausgewählte Readings in HTML-Format ausgibt. <br>
- Als Parameter wird der Name des definierten SYSMON-Geräts erwartet.<br>
- Es kann auch ReadingsGroup, CloneDummy oder andere Module genutzt werden, dann werden einfach deren Readings verwendet.<br>
- Der zweite Parameter ist optional und gibt eine Liste der anzuzeigende Readings
- im Format <code><ReadingName>[:<Comment>[:<Postfix>[:<FormatString>]]]</code> an.<br>
- Dabei gibt <code>ReadingName</code> den anzuzeigenden Reading an, der Wert aus <code>Comment</code> wird als der Anzeigename verwendet
- und <code>Postfix</code> wird nach dem eihentlichen Wert angezeigt (so können z.B. Einheiten wie MHz angezeigt werden).
- Mit Hilfe von FormatString kann die Ausgabe beeinflusst werden (s. sprintf in PerlDoku).<br>
- Falls kein <code>Comment</code> angegeben ist, wird eine intern vordefinierte Beschreibung angegeben.
- Bei benutzerdefinierbaren Readings wird ggf. <code>Comment</code> aus der Definition verwendet.<br>
- Wird keine Liste angegeben, wird eine vordefinierte Auswahl verwendet (alle Werte).<br><br>
- <code>define sysv1 weblink htmlCode {SYSMON_ShowValuesHTML('sysmon')}</code><br>
- <code>define sysv2 weblink htmlCode {SYSMON_ShowValuesHTML('sysmon', ('date:Datum', 'cpu_temp:CPU Temperatur: °C', 'cpu_freq:CPU Frequenz: MHz'))}</code>
- </ul>
- <br>
- <b>HTML-Ausgabe-Methode (für ein Weblink): SYSMON_ShowValuesHTMLTitled(<SYSMON-Instance>[,<Title>,<Liste>])</b><br><br>
- <ul>
- Wie SYSMON_ShowValuesHTML, aber mit einer Überschrift darüber. Wird keine Überschrift angegeben, wird alias des Moduls genutzt (falls definiert).<br>
- </ul>
- <br>
- <b>Text-Ausgabe-Methode (see Weblink): SYSMON_ShowValuesText(<SYSMON-Instance>[,<Liste>])</b><br><br>
- <ul>
- Analog SYSMON_ShowValuesHTML, jedoch formatiert als reines Text.<br>
- </ul>
- <br>
- <b>HTML-Ausgabe-Methode (für ein Weblink): SYSMON_ShowValuesTextTitled(<SYSMON-Instance>[,<Title>,<Liste>])</b><br><br>
- <ul>
- Wie SYSMON_ShowValuesText, aber mit einer Überschrift darüber.<br>
- </ul>
- <br>
- <b>Readings-Werte mit Perl lesen: SYSMON_getValues(<name>[, <Liste der gewünschten Schlüssel>])</b><br><br>
- <ul>
- Liefert ein Hash-Ref mit den gewünschten Werten. Wenn keine Liste (array) übergeben wird, werden alle Werte geliefert.<br>
- {(SYSMON_getValues("sysmon"))->{'cpu_temp'}}<br>
- {(SYSMON_getValues("sysmon",("cpu_freq","cpu_temp")))->{"cpu_temp"}}<br>
- {join(" ", values (SYSMON_getValues("sysmon")))}<br>
- {join(" ", values (SYSMON_getValues("sysmon",("cpu_freq","cpu_temp"))))}<br>
- </ul>
- <br>
- <b>Beispiele:</b><br><br>
- <ul>
- <code>
- # Modul-Definition<br>
- define sysmon SYSMON 1 1 1 10<br>
- #attr sysmon event-on-update-reading cpu_temp,cpu_temp_avg,cpu_freq,eth0_diff,loadavg,ram,^~ /.*usb.*,~ /$<br>
- attr sysmon event-on-update-reading cpu_temp,cpu_temp_avg,cpu_freq,eth0_diff,loadavg,ram,fs_.*,stat_cpu_percent<br>
- attr sysmon filesystems fs_boot:/boot,fs_root:/:Root,fs_usb1:/media/usb1:USB-Stick<br>
- attr sysmon network-interfaces eth0:eth0:Ethernet,wlan0:wlan0:WiFi<br>
- attr sysmon group RPi<br>
- attr sysmon room 9.03_Tech<br>
- <br>
- # Log<br>
- define FileLog_sysmon FileLog ./log/sysmon-%Y-%m.log sysmon<br>
- attr FileLog_sysmon group RPi<br>
- attr FileLog_sysmon logtype SM_CPUTemp:Plot,text<br>
- attr FileLog_sysmon room 9.03_Tech<br>
- <br>
- # Visualisierung: CPU-Temperatur<br>
- define wl_sysmon_temp SVG FileLog_sysmon:SM_CPUTemp:CURRENT<br>
- attr wl_sysmon_temp group RPi<br>
- attr wl_sysmon_temp label "CPU Temperatur: Min $data{min2}, Max $data{max2}, Last $data{currval2}"<br>
- attr wl_sysmon_temp room 9.03_Tech<br>
- <br>
- # Visualisierung: Netzwerk-Datenübertragung für eth0<br>
- define wl_sysmon_eth0 SVG FileLog_sysmon:SM_Network_eth0:CURRENT<br>
- attr wl_sysmon_eth0 group RPi<br>
- attr wl_sysmon_eth0 label "Netzwerk-Traffic eth0: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_eth0 room 9.03_Tech<br>
- <br>
- # Visualisierung: Netzwerk-Datenübertragung für wlan0<br>
- define wl_sysmon_wlan0 SVG FileLog_sysmon:SM_Network_wlan0:CURRENT<br>
- attr wl_sysmon_wlan0 group RPi<br>
- attr wl_sysmon_wlan0 label "Netzwerk-Traffic wlan0: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_wlan0 room 9.03_Tech<br>
- <br>
- # Visualisierung: CPU-Auslastung (load average)<br>
- define wl_sysmon_load SVG FileLog_sysmon:SM_Load:CURRENT<br>
- attr wl_sysmon_load group RPi<br>
- attr wl_sysmon_load label "Load Min: $data{min1}, Max: $data{max1}, Aktuell: $data{currval1}"<br>
- attr wl_sysmon_load room 9.03_Tech<br>
- <br>
- # Visualisierung: RAM-Nutzung<br>
- define wl_sysmon_ram SVG FileLog_sysmon:SM_RAM:CURRENT<br>
- attr wl_sysmon_ram group RPi<br>
- attr wl_sysmon_ram label "RAM-Nutzung Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_ram room 9.03_Tech<br>
- <br>
- # Visualisierung: Dateisystem: Root-Partition<br>
- define wl_sysmon_fs_root SVG FileLog_sysmon:SM_FS_root:CURRENT<br>
- attr wl_sysmon_fs_root group RPi<br>
- attr wl_sysmon_fs_root label "Root Partition Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_fs_root room 9.03_Tech<br>
- <br>
- # Visualisierung: Dateisystem: USB-Stick<br>
- define wl_sysmon_fs_usb1 SVG FileLog_sysmon:SM_FS_usb1:CURRENT<br>
- attr wl_sysmon_fs_usb1 group RPi<br>
- attr wl_sysmon_fs_usb1 label "USB1 Total: $data{max1}, Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"<br>
- attr wl_sysmon_fs_usb1 room 9.03_Tech<br>
- <br>
- # Anzeige der Readings zum Einbinden in ein 'Raum'.<br>
- define SysValues weblink htmlCode {SYSMON_ShowValuesHTML('sysmon')}<br>
- attr SysValues group RPi<br>
- attr SysValues room 9.03_Tech<br>
- <br>
- # Anzeige CPU Auslasung<br>
- define wl_sysmon_cpustat SVG FileLog_sysmon:SM_CPUStat:CURRENT<br>
- attr wl_sysmon_cpustat label "CPU(min/max): user:$data{min1}/$data{max1} nice:$data{min2}/$data{max2} sys:$data{min3}/$data{max3} idle:$data{min4}/$data{max4} io:$data{min5}/$data{max5} irq:$data{min6}/$data{max6} sirq:$data{min7}/$data{max7}"<br>
- attr wl_sysmon_cpustat group RPi<br>
- attr wl_sysmon_cpustat room 9.99_Test<br>
- attr wl_sysmon_cpustat plotsize 840,420<br>
- define wl_sysmon_cpustat_s SVG FileLog_sysmon:SM_CPUStatSum:CURRENT<br>
- attr wl_sysmon_cpustat_s label "CPU(min/max): user:$data{min1}/$data{max1} nice:$data{min2}/$data{max2} sys:$data{min3}/$data{max3} idle:$data{min4}/$data{max4} io:$data{min5}/$data{max5} irq:$data{min6}/$data{max6} sirq:$data{min7}/$data{max7}"<br>
- attr wl_sysmon_cpustat_s group RPi<br>
- attr wl_sysmon_cpustat_s room 9.99_Test<br>
- attr wl_sysmon_cpustat_s plotsize 840,420<br>
- define wl_sysmon_cpustatT SVG FileLog_sysmon:SM_CPUStatTotal:CURRENT<br>
- attr wl_sysmon_cpustatT label "CPU-Auslastung"<br>
- attr wl_sysmon_cpustatT group RPi<br>
- attr wl_sysmon_cpustatT plotsize 840,420<br>
- attr wl_sysmon_cpustatT room 9.99_Test<br>
- <br>
- # Anzeige Stromversorgung AC<br>
- define wl_sysmon_power_ac SVG FileLog_sysmon:SM_power_ac:CURRENT<br>
- attr wl_sysmon_power_ac label "Stromversorgung (ac) Spannung: $data{min1} - $data{max1} V, Strom: $data{min2} - $data{max2} mA"<br>
- attr wl_sysmon_power_ac room Technik<br>
- attr wl_sysmon_power_ac group system<br>
- # Anzeige Stromversorgung Battery<br>
- define wl_sysmon_power_bat SVG FileLog_sysmon:SM_power_battery:CURRENT<br>
- attr wl_sysmon_power_bat label "Stromversorgung (bat) Spannung: $data{min1} - $data{max1} V, Strom: $data{min2} - $data{max2} mA"<br>
- attr wl_sysmon_power_bat room Technik<br>
- attr wl_sysmon_power_bat group system<br>
- </code>
- </ul>
- </ul>
- =end html_DE
- =cut
|