From 3e2241b082d8dcc82fa899918928d754a45c4e08 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Fri, 5 Jan 2024 23:16:41 +0100
Subject: [PATCH] update project

---
 README.md                                     |   2 +-
 mkp/fritzbox_smarthome-0.8.5-20240105.mkp     | Bin 0 -> 14253 bytes
 .../fritzbox_smarthome_app_lock.py            |   4 +-
 .../agent_based/fritzbox_smarthome_battery.py |   5 +-
 .../fritzbox_smarthome_device_lock.py         |   5 +-
 .../fritzbox_smarthome_power_meter.py         |  50 +++---
 .../fritzbox_smarthome_power_socket.py        |   5 +-
 .../agent_based/fritzbox_smarthome_switch.py  |  22 +--
 .../fritzbox_smarthome_temperature.py         |  16 +-
 .../fritzbox_smarthome_thermostat.py          | 125 +++++++-------
 .../agent_based/utils/fritzbox_smarthome.py   | 161 +++++++++---------
 source/gui/metrics/fritzbox_smarthome.py      |  35 ++++
 source/packages/fritzbox_smarthome            |   4 +-
 13 files changed, 226 insertions(+), 208 deletions(-)
 create mode 100644 mkp/fritzbox_smarthome-0.8.5-20240105.mkp

diff --git a/README.md b/README.md
index e0a1874..0b5890b 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.4-20231231.mkp "fritzbox_smarthome-0.8.4-20231231.mkp"
+[PACKAGE]: ../../raw/master/mkp/fritzbox_smarthome-0.8.5-20240105.mkp "fritzbox_smarthome-0.8.5-20240105.mkp"
 # AVM Fritz!Box Smarthome
 
 This repository contains a additional check_MK Fritz!Box Agent which can gather informations over the AVM AHA HTTP Interface about SmartHome Devices connected to an Fritz!Box. 
diff --git a/mkp/fritzbox_smarthome-0.8.5-20240105.mkp b/mkp/fritzbox_smarthome-0.8.5-20240105.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..441d4a8ccd116c6f305d7bd5294d679a8aa95c4f
GIT binary patch
literal 14253
zcma*OV{j#2@GTllCbn&JVw~8v?M!SZCz;rqU}D=7+t$Rk?c_w~{p#KO>VEs*_pLv4
z)$YB!x@-4Zt4U+vAclb%mQdiUfGf`p-eeo_vbxFdtP)Pj$>fjJ(-!uXE8d*V@d)Mp
z>utkUR#a+Hj8Uu#YI>mk@=eohy|QN&MB+DDl|qYgmon8d<xvX6FtGxaa;V^6SMgn>
zElA8kgP#G<tRl}lAt50}r0egn?-4acMMcYy0AYYF>4%7(FaT;QWbVFTg7ho<cB%e&
zZ|EV8<;M)|^oybzBJIqKiLZxgSo$`=9dL7Qb{dur?WD&;fNh5KlkN6O*T#<}jh{rF
zhbm2gDg>U`0H(9W4_O%ij*kW8b=_Uv3WM)cyySmX97R~{E7If7+xdxv>=+h_v76A5
z<|<zXO;z`&a+QAjy3~gx#+aqv3r!}R?WNd`OhjF-5o{*ja2<~lFIz+=kPv0c|4nE2
zCv=bL^!hsf%9;I!r(n1fURKm4z1h{*GQQq4;HJf&ayu!?LorI(Dc?pW$)`e-uG$Bp
zCU|0eJOY@g^moC2i+kKfWV<5s$7AG0SavBFgv)oT$H*hz#^TgixI3Q6-7&Wu0W)Rm
z>M(LRoRSH@l!h>2>D&Wvo)!U`;cuNsmUqVwoex0p<i$dY+x?%Ja%{D{CjA=Awwxn6
zzZxYU?jG+Uk|Y5qB}b+?GkcpwQnE=Q>PH-Y+enH#8MeG>02)*NyKT2C^ek#5b|T?9
zFEUhgi^}YfjGa=K?kSfbFgEi<=Tm0XvyOS^`MBS)*pB8x_i}YBXRGJn$*W8YqHseH
z^mzC2(3uy=2Yk6ZId<1Ef*4iW<r;g8&;JI#Unm0({|mESdU28IeEgmXDTXk<*kR6U
z@3lJ>@tZ#L7uf>#>1?~QC@C!tuB~ibti&eOVH2O@fR1y-Hu9a-;ubNlk%+m+Z+-(&
z6!&~xDrl>LF2a?&>H@wO;wDo&WPhoj76P0Q7$(yHP%@|3`fm^^cdVz^h|}o5OX9m7
zZ>j8LtDPP-Pei!$7YSV?JWVK<3qP48Bc<cQPCC^tT>97uFi;!E?DfF3EcNPFRdZ$i
ziRWq4t72Q(dzyU6MakzyUZFtiTl|q>@^4Z@w>A@UVZuZTw&m#3)nOWQ9Op>RsU3!)
zM&g7kwZ;_CivJad?du==hhwreV+6Kyu^?ow6*kRWE&c6aKaiQCZ>Ynz0^9vx5Jlgv
zt>t2~ocR)xNu`HYsq+;dIh+wgPEw2c%bzA|ufBrLR>Xzb+Bx`?D%k>Cy7Da*(dj=4
z4s1!W6_Q6w4pGs@8;_+j@#!x%j)pdL1omNidlzV>%FjY~{JmrY8*qCBp;RBsS`U&B
zCS?ofm#ynH&>#ml+s;yDu({*=R2tzF=0&SI?|`Dr_UyVeeW;Jg6S3`#A)8~+<3G2v
zfTM8`n0p8~4g8+_ezo7*T@*5?@Zsg|-Bx$dD;)){w4c)GEUv`kSo&VEpE$SzB9Cw?
zF+ocr!9x1Ft|dLb%W#~Axb}J>FVG$5y)+fo#xVW7#u-ss6QL)>{`}A5raUA|I?^K0
zixj8mH=GO!M!>Dgffp`p2-_zw+Wg;`NA_G^G{#Kc!<YL*%!9`b_GmyeM6|%@SNVMy
z5mTc-c?7Z{J=}nr9Wn{kkQrJ2Z8O8L$nAS!W%h(_l4Y<Gq#A!Fy;!n1&Jca9{O!@N
z-J+mC3{xyJ8B+;JDSj;-x+GpQy1wY{uXAb!$cMd*+w}G~B;orT#16*(Jx<(tDCJ!8
z)R)5sS^3Rpv)=<O`lpGw3+lc*!>4@OS>q5Nb~GVRA9hku*|tiB#p-cPX}9@R=`SxJ
zkTF4nqI)RG7TAuop;!IOn2<=M`wL8$uaSE71bnvvM}qyFsUGvU)-RfL!8fEqEJP4S
ze!!dhr;JbKG1SlYD<s@qW<M}&m^E-M2lmTx$J49APcd|@5<n>c+#-i|f*YxkKi;!B
zff1?zgz(&$9=k%XQwsw>!aibKHeJWox^7lOPKn#E*%r-@lig(-XrW|!{R5TZ&XUE9
zF`SJ;Qet>_Rj#g@1O#$$Z*P%biC<MJ28&0SxcAZ;W>!J6*h*NEn0D>rI*KJwMuKnC
zcv{+0Jv`KVTSz(HcOT7yaEu=?Etqjm>Ug)M_6a4u{U!BTD_4<Xam+>jrTv@mpyUbM
z^CD^Tz@Q7tug9}hsoqSmFQU;uzbfS%sgfQXXhj=%U)CbB=?VA=(c_b5VkE$=_RV30
z%aef}8B^@*lPKWibdkcGn%7)OpJV6lXKj34nG4-}Ce3}YE&zh{$~W_2Oy>#PhBWlM
zs15&Ewb^nF%<g0m?Y5?d=vR!#tt8qT^6<qZ|C&!pqC~ojr?t9uMpupL?bboynj^*!
z7bDZ{-j-~>u3qSu&Y1~uXX_AgDDG+EA%n`*axZuvDXV91|CNX!Dx<VX_C&op{h_$1
zOjX6Y8<*#AxYK`bkWWJ9Bp4L)W{41VI3xd&h5ua4LgDvs_EjJ|huhYz6f)5>4=?97
z)Q!jp)xN>=PKa^uq7(zy68_!S=dr?~d|s`0G~2}@L!{?s(M!KI&f)pBjdB{RAAAh{
zygxgzLwNq3`xdyk=I{Tj_e={bhgNglBzEO*3C?MQfu8fhH%{qYyI-EBtKtWZ`tepd
zk^|#TaBY_4TjDE{;nGO@1>X$vs01gN=wt`oIK6a}jFO<7Eqt=2sBz-AEFw`U2`wuJ
z7><`|-@rlW#-<2=8X~teNA0X45kia^mon%zY-UMH`0PQJOEd-C@Em5SgjA}PW1g#M
z*)Uuc5=Ll|^MjE1n3d9vdky+gN>+QsSzuB+;-5nP85S1rCgH7CK$6X1<TnD!rj8+J
z!Lva*LXy5vvfNGWVxKS$DtgE_c)??4PT@~Va>#5b-0r0QwX@_pRbd5YFQLZoc$Dui
z<K}BkJ3M1qJH-@5gzDA$TMwxBPpj+H!#{&AM!HEjX^T#NSw}4q+>{`SV{x!t%$YyX
zkKNYN>WpBEIdQt$rxT3-zDLr#oUT7MjScIjfTIsH8iGMk(5+%*nC50b2dG-JFJZmR
z77EEdE#RIPmZ6{s+#aBaz9rRij&fF8>ewWzdR!Z|Z^y~o8gsDTTr9nHCuM~pMyPBz
z?TXmjd(l;dt6D`XDDJ`)PWqus<BpwJ#!^^a0OvZVka9F5i#yx0I)+*#T+uL3)UK4y
zmd4s%ClI;U<~k(0E6Z)=aZ1fD&=L|@e)2H9%>QOuZp<+5_Ljn_LBn+GQ>+<pkff!!
zc_14xX+-vo;YO5E*W@%$&xrQXCBH7;#5kL@{Ah>Xhnsd)JhBvdU_K?4?dTpJIGGvd
z{}n%yq_$|h|4Kvce(zu9nxLbncwea|Z<+V=6S^225*|?lwiFt&5BRKG;O9M+xaf_D
zh-mxrTeS6he9JQe>wA5&77a!>i!_X3t&eA-zi%L{_R{c5Zy0pE{|V14keyoErMZEA
zw^^d=t{+t_7Ox|(KT+;m;P`wM{4%>>rFrcNbmVeYp9J0y7<1DoRPIiC2wgMX7A5~3
zH|*>A{ws^U{)f<NUx)E_3=<|vnedU|aE38T8pe_pp##=zR-x#*j`=iKsEo|ciJlk{
z=J8<`u*;w;OE-s3ZIZTAuHmQRbeQhuW(l-K%ghQ#;87^MfPxQXN)7W%+oq0${TOR(
zN8_A7w>r*5;ltJU%~r13RD0*i(d?64bH#V@n9YGMOaJa}@RClORW7b(k-xnWz#`8k
z)`+HdCN^4u&|AaUn7P`RpdMcy#D-<6FGbsmQB=~d!>q>0k`=vzWGRm*-c<L32Q4g7
znAE{wnHf4D)`9j-I6P<tF&sBl3!y#RJ$-iB>}K_4f3Cil=X?h4eEp9u#rkv`yRC=+
zdY(RaSz*aX#(q@ZXLsL;$<5z*)R*WPtU4TC%3gd%AF&U~;CGGf6NU=GomAWu0<@i}
zh@^IvnU=;cdrRL`J{<>JW`;kxS`~#+`p$;)1RX;zrea%-8_8BS#N#Ypy5;uXB$o}h
zihDZ=lLH%nRr4exWdxYz!#eTnN<^r^OpY;4{tCWpFqS{da(6q9bwq9U&-reJa*`aC
zOUVp^u%cCGPlG~%NyFXWND51QD()Y9xVcFw)!6=SYCtxM&wnG;`%#r$W$F}c;WfT(
zS|$0FS+A*k$yDw?I3#??b)2ADMkH3y8q$7q@B#+3+@dI(EdNnn+f!7Ft$xORn0#rz
z*mejR687^$X7{?9L%J>vm_5@3W@%g?Xf5j&=x^}UFj~~Dd;GOOQM7%D6N}}|7l9NF
zxvUt5tyld$V``xT`TOMEYqbp(ekI2z=z?%tX5A)rsqTFT2R(j<u}~_duHn09R?a`c
z^Xd~6XiCcbiSUz-rxtE%0TYX}a3dSO^XGUr_!u?%7<{ABnu-9Gv*+7ckLE@1gH0|R
z30I<q%dQ7Q7{FQkW0oX<p8I#;8~xyFsZ;L0Dc4F@z0C-Rc9Scjs<M=FdZ?g5y?(qO
zJ5vqy7DiG+<6aE)N5mR9MaaDS=~K97P^k-Cwy=J)`;|9XR7BYgmc9Y&`hk`8B5*Ik
zYq!_AHna*&cG8!tQ9Rp#^V%%xP8%wGN%wY`6eG?^`c0s}jTsac=2o#&izY2l1{}qT
zEsG@V{VDDE@zMjQLDxFXbj37ZRMyxdE)p8qqmqh{7H9#@8|1v23yatzExXzrTj#Kc
zHK#AaP2B3T7UkWQ1fPfS`XEK=T!Znf(9qf4TF!OoglLo0o1Eh*<|GG=Bl{xL;X!#|
z&={<43v+vu7>Ok+OYp~$W`qRac*&}PMkm3HvxQ7GjNXYG6(8#O98cpShGOy;CAnEM
zxvhMFx^#pEd}O>z9UT@=M;obD${>RHb0<O^cFSqj@TiZ`Z`GV)u8r8^`^{>cIcAo;
z_%j6kp0GYXjYwr;&dEWy&ZNJ#-ZiXOM?c(+z5|C|K>`49id^0^90<rSeKlzR0c`Us
zKL8Sg>qx<q{07&rsISnJA6sPcJoQ8$ZdtTJT7owZHSyQ>oIO0VI|000JN|DUd#^-Y
zE(f6AD?r{gfHYSaxDoJG@ct2_%77Fv@PgX-E%6%$su842=GPW01eT10_#LnTMX>p{
zH|;jskKtZVvkU!OjC^V0u){v0hiEi<^j&CFR5X-iCi;Mpb#k2lV<cCT75V#&qLmTa
zYCr_{cqbXA)Sy3<CaTy;yh1nMqz{v8188|}gh~gPF5?ySSeND&7qJy^gMf+UN0pKP
z6S6;&sCr+VugA43iw4A5#G))beg8yprNL%rz!6=*m8EK+({7c5yKy1<=4J6qGMN7n
zHO$w*my)6J=iG1ajf3gqp;9&rwy?j8kH$xOQbHxJgU@T4^1N6gbn%13R<Qq;ArqDI
z_Cq-y=*uZ|^eQfc=@{X$<p%QQ(6f9q-tkII+A|jUD6imQILm_?Sk;B6)V;b1w>z0C
zxF)lw{00e+ewMh+tQKWo2Ul^GGR?|&x~&3C_{Mgn7eCt|8f<?d@rguhWcf3zyuE`#
zH<(3Vi45L|9rS6)n&He%l3hH$lH!S%Sa9XZ4dK6(7zAcUB!{YIWaxT3<@6Nv#b1ll
znj!?W4Jdm?640x1je^W#Y;{Z*+b(0tZ@!}7@t;1rT+BfxcCc*35Y2RPDr)=e+7OZY
zpJb*TN=8pQpjuZ<x$uRQ*_#<R??qJ%$z?h8&#TvmQA@qP7%Kk6Y63@l{h4+=xR}TC
zB-uVpy<K)3q;g63iK~Gmx#2A5MTrY)H352D8JE%DJk78Oo<-X85PCU6-z0Xq=||Ck
zl;zquQDocW+GNmoJv|w4b#)nVz}^fQsuVE>bTLCN^R`EBPFObT1fF!d3#=0_HaxZ>
zzYH2igg0AP3kt~~E-qoka}-6T;winaL9L^(s3xg4=maYQl|IrN%I8*m-!)N<aeUX7
z*w{NE8o!hr5i5-nxnyluoFC7e!wSE=NN<Ydy_|ljvft?6StmX+Y05ov`OKKiD$a6+
z`N^+8`6g{0B=hejtMOzkvH|Payq=&K>HZwfCr!LOEm7hI2XrQo=xQzQ0L-duSO%?q
zbX|}GRqr05J`jHCc($Dci?Ox`vz-Mw01?Ljws^8KfzcY1?YTeWif?UyOHYD#&WVUG
zt?$94?$1wO!rfoJCZFJvrZ402!QwOn;WVZ%+}d+t3sqsGTv{d=&<S0@YKZpPjwJKy
z`2fI8RKbo{!}^OP8qgPp*u%k?9YpD4s=x$<D_|O~z7|0Mn=UFu8IVCaTvJQjC*zt7
z%A$hPy_K{dQT!RLg<#~t*c_=|MV4lM-g)`MTRCLf^E`_vd)<PK6|Cx!xg~<lr;W1o
zkapk6WgW8fsb|^8T+a``83tz3lhJA_A&e>iy^QpMzcH5V=K-JfGZEckcPkK8zDIZ6
z&?If)TnmiZ+=-{;{S~cOFf3BEtHdJ*@sb0ROhj!(Gw;+iOZ^KZ@<HF~ZBv@%*tIJ<
zDZDIHQE^J744vQC%(uX9ZNU0;&==5o?%xjh>BHFdi`4~;YU=yd)(Y_>=0}s5-L8(P
z$N|1!V6m%2{8s08nICY3W@VyB;GtKpKCtrn^UNoo4#6{A+>wu`zH`$~dMpvD8FgR{
zydS2+twJ}QD$JzL9V9fe5wtM4xI8EzULAnDR-;u1LhK}eN_qduxv%-RncxwmRdAoQ
z9ZowhXV&PSUO2SOuEuCx#o?a|vd^hT#MZ!O1|3_Zz3J)S^6MsQ^(JVoxH+xy2)<`#
z?nCFo3&DN-_W1^^#oNm3WciD1>wo9NZRmo~KPaGwqs?%Tv1-{yp&tskBl5G^VkW1r
zqc6i24~~rqTr?I-GRCmmr*0rp57UwQx5kxgU|p)9-&de#e8541RVHw*>?Viz9%g9e
zITv@Z?Xy2dQ@tt<x*2m&${pXfzsEAnJxp&)4f;VrLPg^6i-r?!7K|HZ)FIIfXZcUy
z%*2z&;ZUQa?-H#RJp}p6iYWyl&&zuLF9Hz=AU%>;RbO%dM=ww`aOCAvuK5q}^%Uas
z_5An{p=>+@5~?0gb-Fz<4)pU1yvNDA!-*WV&I=Uyv=8JJ6#k68$vDk89D09PK(#K*
zOPB?M{G)G<y1Rc}ccNO~C{HVsPAfZYv)wEBn{-Q22H)R38qZFrw2qPjtvH>_?~@1|
z5IBCoL>1$@=r9bEUK6A8CWlvDKkT;}L&lT2Bqfa>g^`~J+r~~V1{gKlKz0Og0FD6>
ztyt_+&Q|GoQrMdeWjg(OfV7&piy?7axnlCTwHk!5UT?rZKz)ydhz@j&_#b*KF_npL
z1J>bmWm_hlfvXFp#7GXedUhU`lz2*pwHeckpvrz^5*?+>_9vOnHM7exj(2GM<jUF<
zLnG7k=U(cSfApH=HW*kQ$HugXD#>wYN3rqlh(<-pJqD2#9;{_26Bul`FZ(FUY_G86
zHfq-!dy5FQNFX;0fayy;r<~Lxb}!qHTDF2;>j>CmTtghf8=CYx=)4_KI9)6yP|s`;
zk?HWIY!ud_!T7A><J1_cIFl-#Jg)BQ7Y^)}El?@LRx$SMY0m1=?{po86}b$*+t}L~
zh9(UZ%^F#1>AQwsDx!<wThgD2?tNk<cvmOm?{kL?JTZC?xnc^X40VEyI$?^0^AMs&
zQ!f_#<Z-lAq>GZ1q|?-LYOY+&Q{m`56MX5d>6uCRh8X$-*!v^nAtU%qyHhaZuzuBu
z3*Hi0(}U=s42qztP!ar_o4%tL)T;KUu1YlJhf@KrOUinW7Ijsbep-0h$*3B!VjmvC
zN;hKU699ciDK09cy4u8*s7K`k6-9B1T?cpOpK)E#L6ePLZd?`|g(cD%ddq8Xzr}04
zt49`pA9?5hi=m`m%FP+*K}X4GN}yeV##6M8b6NKhkNqvnVvoRDXdjNH^sM&Jf@Ye-
z7(OMHY%(3oJ}O*teD5O8vnrKXta^XxbXr19u#jwY<yos}bTa?YMf!z>QeP|+gS^>l
zOw@~&*sZRV+VxSloN2h51$Wkkz~|rOR>RaAqMQ1GWV)j--}l~9BPmBNEQvDy9358I
z+#(EY{P!isc?z)D`c~J@>X147b-h)e%C^tLq_j&}zUu7n8zx5ZHi`0pK|{CY@P3sv
zuu;5Gdlr4wSZa5*;e#F|w$=CGR)U(A_Vok}`biSrCJs=4u2<0gNvPBEq59|EdVF2B
z<s-)O=m@*;*K;q^AT&?Y>l!)4N#?Qsykjc)!`tIwwtp#yZH3-~V|u||KgsL1{eHU-
zjJ=nZT8SrZo%~gIW5_P<idLj4kPGD*n}|tMW_Anafu>Y+6N$WV98gj6M&C1LZi`}u
z43662#uxO9K9eN05OW!8%*eKsoz`|~+Rk@k)!drhol?vDmf};ck(OR1`(|l0pL6ux
zNvJu((_8wN&1JEJBPK~W*Bz&|5t!)&JZv_4><PiN2KK7onK=U6wQjt<_kMl#UcUfk
zBS=|ajIU-r(tse-C!3{5R2Lazz5T7z9AxyZo6ojDdXU5MWnhw#U`fb3jBQEu?vM);
zJ_qn#$nE$m{`=YBa>asyaMa-4<pxOm4|~i{?5^>Mc3Wd?xEBu)UV5bmBhmf@sl1_U
zbk*r@nnv$GGGYUu3Xu<Unc~jUUgZ=T$cnaV-k)yv1<rEo*e910w~F|Po~82<E1~gj
zgI6w9bC3F@oZ_K=OI$;@bQ$wqZ?p{Iu;5`bH5yE&XSHL%g9E`51AgYOvHw^J2D*Qg
z9rSuU^vd#otU{VFoXS&l8`zHx_TTVB#QN?fphHrW5h8!?9|Lb1cFe{dXigayOUm$`
zB%$b0UiKZl0H)q?;K3dgIWsF}CCLy~3A$pzV*6RXjAT=qS&1yl3iRv0r0DGp7X1Y>
zCPM7R-id;pb%d4}CsY;eLORz(rQhw?f>dJZ@!w|_$mY`NYJ7rtP&-UWq;cHmSAGMi
zWW{!MjRbqD*jTC_cbMWQ*$R=^;%8@8Yr7r3W8({H#nAr_%S%OOD4f@iJ#dxlqDqXR
z>N%2O8C}jaQ^wti-}R8XfgJ_TFCR&_gD*^aQzyXz#l7IOS0~Yr))hS>aEXUbM9>b?
zx8MBx$^<YI7<0k9gV6nw1W#DzqES0>p`jv9KXt|un5rlTHaq><@H89Ff)brN4_T_l
zddV~t@ZV*V88M+)NNj++bSedRJ4|R(4~4O+p>(apD97!(%$)QL#{As$Sfe;BacXBT
z$q=gN;mo6v|G{cEF<g|xFc|Zy=4Y=7q!xRGgFF}zEOB6zzdPXg^>==7N<4Tu0nE-{
z4c+I212G|ZHyQ~65{-=;38E+WzY*PK2RYCn8I)@)KYc$Dk-KlQdL5M=^7?fsE}~GL
zg8BjQG998--*R7k2|KA%3-|8YreT~i>(Ufry(jv>SMyG5m8fsCkoXENl3eP0wc0EE
zg>N}FfFdasf!>N&O82VEEJshJ!Y`9VZ-1v>sMenz8so}p&u663_!3mB!(nF7&hho_
zE|0A^OCF+&>Fa{XsuxU5boK$}|5~`)@j?Sj<{pt!+^0Om*>gf*sl8r{_qsxDDtyz)
z*HykFG*Mzf{X)P~Cn6t@iwHqD-{E9pDnr=OBudx1al+{@SydTD1*qQQgoI(CR>8nW
z7nX#Ch&Zltn>EF*vqa5EkepqOSmLKGV?1XztRn0$zjJfh%;k%Qd`BkW{GSXF6T+Yn
zD;v;8mH0Y1AraL2Hv#zY36_?YX5Iwv`~s7>frabuX|KTli@3Ru+XWfwW}SnJLP823
zNNbeJrr&_zUAVuHCSR=~-DyJLJ3JNVFL8Si>NV6EZ|EGh`f4miYSav(0`o?V#wGfX
zwOrwaAx5#v(x_R*zY{OzV#tcVb`f0udQ}%S0snKX|K~m`7&^Jl6-SP4u%`s?!Y_Kh
z;FF?0PfvfG=U!LvNxzXN_+<OvcJ4M9gon0XAl`Y1T-k3Nc<(5i?bJBX>Qgyyr~O^a
zhHtw~o`$EB1=$Gzwq5DS)yn4OdR=>;m_rfUxt{fz(9E54@zuniH`(3bcy1C?3NjFJ
zymS_0+Mg#Ju(gbe#LP{uDFFyN&ruoQt~4J_6*L{Gv)^te3Ff|Q?G#KS_=s0P$EwST
zCA|K=lD?W94I&)z85vbM>)IjmUfBBoNKs`X{xF(L*Uk)!_RZ!Hi1YOt4f_`Y-bWp|
zl~adY@$Ll8|7#Ne*TZalZ<#%-I0A<PQ4=1&{yWa$_*3Jt*A{GT4L&9N3x3GoIy?Q$
zOMrv{3Fjr{^j@Q#qjVKq#dlhe#CsZjIC*!QcZ$zt5Ib=q*sM~&N9y=|hbax>Z-m9^
zOv!${k>Pdm{Jv0y$k_FGTyWr{jVsRDMdYpCciqJACvY{R^e(CWyI6d)DoS4#<f%d@
z$3Ly~fKzXYr@-WeG{(UQ2a%PU3Cjs04$V~#E}2M-mq`lDN)ygib_ubIGh`v*92-Iu
zQ_xr^d!8ad2_X39kz0)A3_VYYn;IE`7cAIbT@SoOuNYQv_X}Nci2tcmB{f_1#NPnD
z?@JCkZEqq}A7aRS<SxFh_f*|li$XL=?oEn0#kI?X$C~bUKV4<1(aeKglG=QJvlQHe
z3EemMYwVJkm4EmJ!%M2F+D_2Y%DrLWt<_TzIh6$uERlIPIz<N1N*e)KjU_dLv?&9}
zHDN?+alD(_pzOE@5rTRIJsZq*qN3ZLa=H3Q5^mm>cNtcGorX1rTUYWIQ#6L2j`d7W
z!sgYI5r@xMU?M~5a+4#A)kCf64IMPHNB_edsI|tClL^#rL0FlTA1~Y6^uo6)QIjoU
z<96^mG{o~cFfkagF?Qs8Bysw`l<<GqA5;&z+uXiBo+VAY0t0O5pMlrS0{<0-dEbAO
zDqyW(+;e9x@vWc5<CN_2D)=a4vE=KumalU|23+-@>rE^ByRbk__kVcXgR05i*X-i;
ztas7LJMZ|(sPWirIcb{s%yGadiNwvAM??Y1Y;g9DVHfse`s@un`4%s0nTX^6CcKe&
z>uM4yl$sox9xzCH8i=1&N@|LqH|{`X9qxXDdi<TA197!wJPUPJGye9SqL{D}ZY1kU
zXynVQLXDV2l-B>yKmaegYwGuD6xtgxeg~%hU@cmk9&gh(_gFr)o7V$4u=P&X?0oSr
z^_TT$LEP3HE`}%0696IuRxDni1FAD-EllXR08g>`InNkhH}X#VUmrN&j5SKl?Po(N
zvi+Y}LYB_V)dz;>>EU79yHbHP_7>~qN^4BU{3YKIg>sHT*b_`S`%RMA4WEGhxcme9
zKjZ}9$<E+WPlzGnQ<cq*jp}9mJ>MZ^`>?4tL))2Ttz%sdjB)%YsgKOY!&=ihdCz-_
zMYUeEN|f$WC6gIzj&p6o_7{a;AT#>2k6)JXv_to6G`4cyA(c<z$r6xR?2(Q&!_8Yd
zJu!ZqHE04B*XyQrZyUws->IX5og!j8T{&4E5;!vc<PDp7s<19&J@}QXCoo(2NxWgL
z2Da5}7c?c0QCs{FQqNd=i5hdZKOPFFPYnV6rnVg^u#Z|CDb6fCSk=Zd`f_~^gP@Pe
z?*1x~?SXK~##voO9b4=O(ZXo>N%CDNm!i+GlMHxL`$q-qqljxvcbo<cU92-eMjLlD
zGmRHl86}YAr@1ZU#_uIYh^3$g2w!4!h&(ueNJ73kn)>;xn9aT$X1O-$hiyF96>1F&
z<QAV|$N6tBO=g+#PNTRZ9bhEcaJ8mb8YEJ*qKs>&n3;kreu=~*Z9Ev^1IVo|Ja)!<
z114?S@cZ*%9FgNG{|??+1Pk9;dG!e927&$5V0$}1lL@2Gut7fSKzUEOQOHAoD3%?#
z9FJGrCZ?e?DhjQb&A=oV(ucd1tV6@dvHmWwGTw;y5aJ2l-1JWoCNDS%Q%{2Rk81qa
zxRyy8?C@b*evtdK(~Z#ACK(T=A6pV5N>Wx|);n|;mq{e-=y&bq3~rBVv|$9&%Lddh
zpNjlo-DoFbP6fU}u4MomPm=b%u?1XQRZ5QbWrCyo<yg26#P@Civ{&SKW94}4C@X)(
z_cFu4ouTecwPy>{)57G0L?;SjO{SDIz0FSD9p_-&s^{!<zAbs8oB0_YyH|?5woq_)
zC8}fCULk?@^HBO+r$%ojtH(n6i<0VLyW9;^v`Fi=Kn2;o=w~BBNwXi7x(fCW=BUiJ
z90puY2O;MPPT4p0)e$2LDpKl!Ov~6wDQHG1|C|hRb!XKnXPSfrX}BUhyB)GvJxwb9
z=r@ibAV_@{H3|lI6nLdomh=AQ*4A2gApH4R_WC}Hc=n#4rVoN8bF_s=T|LjhDt1py
zM@((|OoJ+oK5V@uB?a870Z2oisbkCZj%%ZY54;%&GX%|K+HJV`a;LNDBIHdWI&Sq9
zdpMTg9MzBi#{GaUgEPXzzhPNGL{R3dWfi4{+-D!1A&g^dm2*$cE4b$=_*~wE_ZjrN
zLXr~fMFF!#RD~iIjA=B43nXbn9E<DinV5xpag@WFpPdubO6B&NwGOImO3NBaZ#BT@
z*(3j~ed^vln@m~M>7f3yJK4JEsJ@AUCP9~9_S_f6!sR+|9PEmYV<XSFFC&TXzxsnn
zG+RyE_`QfOU#U4Um1@c+WR$Ix9CA%0$N@4-<0qvA8h!e+zvfSa_K!TUkSc~QPK5P=
z)d3Gl5OhOq(mJLn=WhK(^uQ_6FeZA`i7d%)GM_&IdK?)QT!JgbJvX2%&K)vyr3X~I
zzbV1Di_@(`=h0~=02Z5Kq>-XbH`zJm?M5fDMdiVnml`zZ>lW)nNtm{-Zqq?1tf+jW
zfiCylQlF@yhed~&T{lUGgw7Mf_Q)jnydF`XME_PxxkuN{BIxpHCsgk4{nqubgk@FQ
zbuh4g<$U))dpp+%yl??T)dOQzc8`!atEx4lj2bsg6>K`j1=w*X1wQzQsq7|@O%eKR
z(zpRk=)*i!v4!hA<s`pl<UTS|8V=LV6HNt>W*69|``73_%yHnW-#)}0eS7R7FSy_R
zi$p{0UHc#MYw27-DV;IgiuM$^g)_==M%p-?++rZ1Pc6>cl&#_BtX6$r=ipyPA&rh{
z?y<{9axGMG-R$*l_Eu-M8aL}mvow%NfzDjbC^oUQEX1U%Un#KYkt1(M9ER<Q;#FfG
z2CZe>!~d^j(hf5cG_iif7}IR#<ME@i@<C1;uR;sn6k*E$23t#8mT6gXB!X-0G^XVd
z=cW8ZQ>Q@}aBiyFjd!oY618NjOYD$Xd896Hf7xLWJUejL6e@32i<AK6=7Az<-BECZ
z9p_CigsT2Ifw+WwpHATO0~p5?jt7mr>AF7;C;F{m3F6QkWIHd`nSTgXl7cXFo=2ZV
zjH9|ma)B`UL-R_WgESSo!TNZC4w6@2o5<i_!9O&Oo{=Ubr2JTxA1Y93U57T`+^4iK
zcCW(7<rfp5zu_yuLLB7}lSWsVOcQt);b^P0SFa#$WL9)Vrxr~JY_CE|X4ebJ7`fe1
zh<UD3^I}fo-({fRuGgeJMsLpm(v@5M(7il}1p<2Cg{jo3{AaGNz&6b<3G3~jq`u(Z
zc<@9nSkv}`k_2M=HvALD-V)Z9;|X1rQ@$CBZqLDInr{amb!Vn6ic2M`4rYVcvMh|*
zRV-#4SLNsIsE5+e&I2z8aGfA+(@0kRXUQd4bmXfwA%2}79MS@&z5*)ggNa&<IsFQ@
zaC!AxKxZi41kXmdO?}H?hQrb6cMP|>Ud5mP`>)=E>wNj8J_TOoTVDZ@l0r-LwIY&_
zI-a{OnzWumEvBYJ<BWoHW&-_$|9)-o*`9q0?+ASX=U;%(jjMvOuy?`dQ^9D79~TiX
zw}1?vHl%(QoEE72**>=tIRTXlE+VL;0&Km`4@N5Cg;`emS`7&m;!T);c?C|$bQrNa
zFiMZKMWlOc>J0m@?Kk-WPiH_86#}VXe!!Cz=Sb_vkD)rqxWFBy92(>RxvVn(ga^Kl
zxHw+H1Qi-BHpqdlWQ!x7j2CoNT%(gu3+mt+YtACZ0Y%RUZ;hcc4%ke~5!_g92C}lA
zu!`>h9^DjEW36tx^8})s@9K}2dY$jmHMmzZfiYKLD@C?oFOEkAENSGgcpjga>(it<
zfFDBiTlDr`JFY#;2mYcONZUIY(K|SA8XcB3EIjY2?ZX5L8iStK6HTt!@|2^=0J&0+
z*UCV-vA{!u=zLj+3#rVAwoaxh2(Ju7&z$N{Isz@3gE^`VzSur&H}VhdP}Ab;miXw%
zn%6G1u3LWFAAb7>Im==znWOtC7aY$tx*PxRU}Fz>L~7A64}67Hb$}5XS=;kkQOPA|
z*O{OtbmQ6+`3uqxY;gTeF*X)Sr3l?eqTdFJ*==<MPS}s%NQtOCtg^9I-@dM(9==}v
z@bL=_98qEeQO?<!J*`EfxPEF0J#gO|q@#FqlUuM`mD2~boiOb-&i4i1{fjAiS?lN*
zoOY_<@Wb4bV3dsN%9^`>ZM>Bj`fk+VXpzi8;Iv2Hzr=aD<7KTnf;vU+dNTbPDq7?(
zDIg%eo|h2!z2SS8^x7(qI8Z6>l}<b1N_+DDfk3{{vea<yD>1tvDtK-KGRFl`Si~nB
zb0;f-mhp#Wg5e?5)QMhpjxtjqkAMPZyf|-jkU!`?m-G`s%S@_=J&@Tmup?%h1Li0@
zZmp76f#wpwd>5$+O~K7|Lr@6-piSV)IBZ&fHB%hsJ%~umIwV&A=4#%~L`-l>ghhoT
z6Lcoc&Nf_O$=(z&=X}DVOf*@R8a<`k$c$I-&thLoHE44Wq1tZa={vF$=U-=9$Q2*)
z^k2OnaJ=|tA|t)?8l)}Z@5y@jqL$;(PHUuw)~IbbW|WVAedR`{Jfv_892@LH5)qvO
zE=T$yq(RVl_h(~0h73O8Vc&g7oU=x?j{m%wZ24T7Zik%6+3#8S-tUo4OJq&Bo`!Ar
zxy_pqDgdg>yiD_BAW>I)gI)fNsRC46BNk$_{;I^6tYYQvWRBct{!)(M45s`j-EBv?
z7O@6lzH8uBm~JKd;#i`$!v(76HmRow2w`9f<OyNJ<Df|^Je_v@`FHq_a>VU%dlxtx
z@!dxW&x#}2C<NVU-=FGB;uC8LbwHmERjPyUmY!rKF1~edSt8@Z_K7Z!gz*pF(@+j1
z#(ovHR=<>K!cDwVLEolh!nH!SokSdMS>Eh)LY`2rt5$AO%E8OcI7_VY1{bv7s{3)8
zw|Tqx=C7U6`aVb=2Zg^ZWzMa3^y43Kct2gsle<g>cj>oU#vG}c#S`MOVc*J56p5Hb
zBg<gyREKvT^#}F3Spv8)KU{!mxK8n8*_FXX)Z6$T#|Oh<Z~tjn2ZEpwg5xSI5x+uj
zX7{@3bkcK{i=Aim!|F@%L&Y;PGI{cqnyfxv4-$Na&%e8C*)17&`&usIrc3X%@MSAo
zi(XarGjKOp6=gZQ7%MO2w|eTNY+hQ2GU`##b6gJ-NC5y$*(j(TL$5!ie48K47lql=
zXU9NgD|sCh;26Q=LsYHX%Q9eB-~u^U?B`(6zfa?w;@deA^RDF>s2Um#y~!TO8EbKX
zBmt&lqcgrmRKM%{T(A;7gZU*Mqe<Cs6<wA(%Ti9L<kFD!8@yYfC{WA^WPBE=65G-%
z{a|x5dRnIq#?but{=@i+G0F%a1&!xxqIXqLU0UsduIj-=6}O-L((A25>o1Io5ts)X
z^&=LI0AY<@33MDgv`<&t^a=6{ZwGMTLu<;ek#pQ;+v&{^40n_1Qz(gKq_TRmr05q;
zh;jU8DB+eG4nHNAIxYAv!!4xCG5e^AfiYEBgM>G)7iKBWlPBe(8Yew%GpVDbpK;X(
zStpIT<}}8HX3g^58+AGHE!DCzcOjc_9k#|Yew`&6E`bzgs?4Ht2u!39(ftFtT|6QN
z7f&4)4E08%!Q@zIb{@0(L)9gyES93=aOBsN<QBpnJIkcUA2Ni0B9?X)wik$raT4X_
zv9gqi5fHSxdoe_tqgP2WlT8S4v}`|Pf4Z7x)_D5=Cq2i>vtS;{d8)ycj&PW_ZAE>F
z=l?TR6BJFyYHXF4aLl3})<djRvl~r}#m{SdGLhieCqJ-l#&yLb5TP4eaWo^n+c6U`
zGjmr*+DNzif_wsf97#Ts^&jI7{$#CFR-Tb9TbiK!yQz1{r21^=y^#m&6`Oil75NIP
z6NnE$ZsZJ@&9Z7}Q@J}e5MpMSY|XDs<H0-@@{gJ>i7yiCzpLGk>&D8&C@N;V{%gP9
zR({#OZPWC7B`j1YO|eB>R#Dns%M5nm8O5mSMYDQV0_XfZu&l^FtL^&R+M4j{4H5IP
z>^fSN6~YkK>O;^!zl!Qa;5QZc#$@nhC_1k=>@4elnr$p%q9m=0-P0q{DigMDx*r+q
zH8Wq04U5~CI&VyRQPws%NR`V3Aq<9yS|Yi!nPq7nWyRGS(lzNdAyB%csYxCul6Dna
z{I58Tj>0<2F3g9zGu(CTiTv-dgm^OZpi>O-pEpPU<e~m9AhIFAZ29R}8J#noZH2_e
z7Gnagq*Sh}+-(3?BF0T5%i>qmrH*CY7Rwn1*g7Dz4@}2iO|H;gc>#mD$`zb8|7*>=
z_o`Q3UyqyN!k-P@{(2gP^}|oW8G)(n7;C0%VS(t;h(<Kvpen4SjFIp;{gzP;%<B2C
z7+hAp8ZA-w4_h%*>XgBDRw89twmwwYhgGTjSC&JccXoa)<8FlywcLk*pQ1u;@<*#3
zA@mdsHv8K#xPB2=MM%=e{xmj}R+wPzsubc1_ngb*Zt;3KAT`&JIrg4-y+%#PL=3Yn
zW^Gq6bi70;?^l{Lc^w<v2_JtXLsBj7feZ(bzIq0#`u81X>|VrgDipN5)ROWb$#OK6
z2cksiNR>`WY&u~JM71Y{p;KS056Kfq7Y7CwUz`9Z9RH;s5Ds1?FO&Pms<(w6x^<L2
zGOIJB^6v9hIMj43sAKmr<f|MqvgZV%%-tpwS`pNXh>nY_S!M}h(`2uI`lgs9qks7?
zh)?sdd>KEy5HGBQW)E_JPFG!BL+qCe(6MP6{k)gfJO8!qL2|f+*gA~$&lzq1Kqn?6
z6k^kK@R+KxrQhowe`9qo75#Gh(j@fH=KxdNHOJ%(*1tcB)4;aq0ktM&j31qj$DuO+
zA`oh+?fZ+f^x>wMXoeV>bf-hs=xjxMa(4{xiP8<n9xPUrQh?Ju1^aqZNo!^*(xi9)
z2k-sA1KA%xcEbZNJ`!>QB)>+x(`LZ0bYyB%H;sN|+-Y|W_2AT(UJ|0_#uu==``74b
z@bn?@g9e`L$XzX?m*Hy~;{`(g!VsJ|^DDX?rOe2H%_Ftnj<E^K=^FL)&&_``6G2z=
z$6g#vYMp!Mx8uMVIMyzi{TzX&x~siSS0RvbebOMuKdUYQ3QcQ&bg_=g6>foLYe}q~
z)mHac#{K)9jOA-yyj4#PQ<+g!M}hEX>f^iSo9XcFIKKgQzJ^K0ReGp1l<+1xO<1UN
zixW+;Hbz<@Ih`8IYiBk)O-(7Wqz&bsw8Ro?vsR{cNK6KJIwOQX<5<IgTeu_$#O6wZ
zPSA${y6yg<R9++16MvCV0A3aeCqknGR2USKWM4xMat|V<3%~J8087?$oigZk__Dcw
z-D_N=k2ng4)Yt=~5EwE3NHj(zd4DZvK-E01p{va%R%jNHYdbK_O#>oac%<kwVM5aW
z+nu4wnHlJ`U#_voq+kcpaB?_|arN)wZ_O8nt+QfW;p3=Baml3&ONsL18lc0v{A%K~
z@(p6Ppef8Zqnl|e1qi`ENyD$I9HnAmG?5Lw7fN(7rAZ5A=?8Oq>x~Vu9BoWfZ%nLU
z`!YpEnQ|g<&3KRA{~lkX;2<i0lP+G>pIK}dW>r%svfjKL8lUS@T}FaYE$xv>qTD1?
zq90E+n9yxc!;6m)cOBViZu-2ZABC0Q1I#3iH+pp#B{OlP5dW23tT2KvN}AOfJAJAc
ziyhB_$0C=vi*mKErLS7?{BMyXs{4pSJ{ev}LC@7pRDpgqQeStFvVN$cuG~#K;U01S
zOwJ{n<RtrADL^zu6(&(RH(CQO#tT_lr$Yg_KM-?B{^y%Qhy!#w4UPG=p^Q4=kA1Ad
zbk&)W5+1E_BXx&=aq7d4dIN;LqYPJd?hjwl?%xeN0&QU;q>GFF`K^(QUT@Y*dHSzM
z#CzHAjA6xkFF%1f%LVb^9-ohw&>OHH`4+frQBTdBAuf%I7;kT(^vY-u?#ZlZe@D_q
z?PG*!y??6VnuZ(cNV1_=y`mgZ5=7{ei&(^mZdLZvP&rGA$HRx0K+D^LpG(1#L{}q8
zk4jym!&Hc0-dG_{@wY@Sy``H&KJV?as|{pgJPe(RqLYQyd@7+ycfX4IPU4NNwbP}k
z)dU+>QVe-n=y(riN_qtYPsb0*mOqzSR6B~bu`=eA?>YZ*%FlI*HaIdo)EZL>ZBQ`F
z*-UW>Ol<nWa&pePwxoyYRVs>60QslbUaITLF1ei4641zVnNEfT+*9fs#r64rO8h#l
meNL?;qM|#(Vz0Uf=>Lhu`v2D{OgnGEke%SZ28bXii2nyHUmO(x

literal 0
HcmV?d00001

diff --git a/source/agent_based/fritzbox_smarthome_app_lock.py b/source/agent_based/fritzbox_smarthome_app_lock.py
index b52314e..8582225 100644
--- a/source/agent_based/fritzbox_smarthome_app_lock.py
+++ b/source/agent_based/fritzbox_smarthome_app_lock.py
@@ -42,9 +42,7 @@ def discovery_fritzbox_smarthome_app_lock_multiple(
 def check_fritzbox_smarthome_app_lock_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-    if section.lock is None:
+    if not isinstance(section, AvmSmartHomeDevice) or section.lock is None:
         return
 
     def _get_status(status: int):
diff --git a/source/agent_based/fritzbox_smarthome_battery.py b/source/agent_based/fritzbox_smarthome_battery.py
index 61d597b..57f3556 100644
--- a/source/agent_based/fritzbox_smarthome_battery.py
+++ b/source/agent_based/fritzbox_smarthome_battery.py
@@ -42,10 +42,7 @@ def discovery_fritzbox_smarthome_battery_multiple(
 def check_fritzbox_smarthome_battery_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-
-    if section.battery_low is None:
+    if not isinstance(section, AvmSmartHomeDevice) or section.battery_low is None:
         return
 
     _battery_low = {
diff --git a/source/agent_based/fritzbox_smarthome_device_lock.py b/source/agent_based/fritzbox_smarthome_device_lock.py
index 6c088fd..a6e1bc2 100644
--- a/source/agent_based/fritzbox_smarthome_device_lock.py
+++ b/source/agent_based/fritzbox_smarthome_device_lock.py
@@ -42,10 +42,7 @@ def discovery_fritzbox_smarthome_device_lock_multiple(
 def check_fritzbox_smarthome_device_lock_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-
-    if section.device_lock is None:
+    if not isinstance(section, AvmSmartHomeDevice) or section.device_lock is None:
         return
 
     def _get_status(status: int):
diff --git a/source/agent_based/fritzbox_smarthome_power_meter.py b/source/agent_based/fritzbox_smarthome_power_meter.py
index 6e1c096..9b0f610 100644
--- a/source/agent_based/fritzbox_smarthome_power_meter.py
+++ b/source/agent_based/fritzbox_smarthome_power_meter.py
@@ -15,6 +15,7 @@ from typing import Dict
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     GetRateError,
+    Metric,
     Result,
     Service,
     State,
@@ -32,7 +33,7 @@ def discovery_fritzbox_smarthome_voltage_single(
         section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> DiscoveryResult:
     if isinstance(section, AvmSmartHomeDevice):
-        if section.power_meter and section.power_meter.voltage:
+        if section.power_meter and section.power_meter.voltage is not None:
             yield Service()
 
 
@@ -41,7 +42,7 @@ def discovery_fritzbox_smarthome_voltage_multiple(
 ) -> DiscoveryResult:
     if not isinstance(section, AvmSmartHomeDevice):
         for device_id, device in section.items():
-            if device.power_meter and device.power_meter.voltage:
+            if device.power_meter and device.power_meter.voltage is not None:
                 yield Service(item=str(device_id))
 
 
@@ -50,7 +51,7 @@ def check_fritzbox_smarthome_voltage_single(
 ) -> CheckResult:
     if not isinstance(section, AvmSmartHomeDevice):
         return
-    if section.power_meter and section.power_meter.voltage:
+    if section.power_meter and section.power_meter.voltage is not None:
         yield from check_levels(
             label='Voltage',
             levels_lower=params.get('levels_lower'),
@@ -96,7 +97,7 @@ def discovery_fritzbox_smarthome_power_single(
         section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> DiscoveryResult:
     if isinstance(section, AvmSmartHomeDevice):
-        if section.power_meter and section.power_meter.power:
+        if section.power_meter and section.power_meter.power is not None:
             yield Service()
 
 
@@ -105,7 +106,7 @@ def discovery_fritzbox_smarthome_power_multiple(
 ) -> DiscoveryResult:
     if not isinstance(section, AvmSmartHomeDevice):
         for device_id, device in section.items():
-            if device.power_meter and device.power_meter.power:
+            if device.power_meter and device.power_meter.power is not None:
                 yield Service(item=str(device_id))
 
 
@@ -115,7 +116,7 @@ def check_fritzbox_smarthome_power_single(
     if not isinstance(section, AvmSmartHomeDevice):
         return
 
-    if section.power_meter and section.power_meter.power:
+    if section.power_meter and section.power_meter.power is not None:
         yield from check_levels(
             value=section.power_meter.power,
             metric_name='power',
@@ -161,7 +162,7 @@ def discovery_fritzbox_smarthome_energy_single(
         section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> DiscoveryResult:
     if isinstance(section, AvmSmartHomeDevice):
-        if section.power_meter and section.power_meter.energy:
+        if section.power_meter and section.power_meter.energy is not None:
             yield Service()
 
 
@@ -170,7 +171,7 @@ def discovery_fritzbox_smarthome_energy_multiple(
 ) -> DiscoveryResult:
     if not isinstance(section, AvmSmartHomeDevice):
         for device_id, device in section.items():
-            if device.power_meter and device.power_meter.energy:
+            if device.power_meter and device.power_meter.energy is not None:
                 yield Service(item=str(device_id))
 
 
@@ -180,32 +181,37 @@ def check_fritzbox_smarthome_energy_single(
     if not isinstance(section, AvmSmartHomeDevice):
         return
 
-    if section.power_meter and section.power_meter.energy:
-        try:
-            energy = get_rate(
-                value_store=get_value_store(),
-                key='energy',
-                time=time_now(),
-                value=section.power_meter.energy,
-                raise_overflow=True
-            )
-        except GetRateError as e:
-            yield Result(state=State.OK, notice=str(e))
+    if section.power_meter and section.power_meter.power is not None:
+        value_store = get_value_store()
+        if not (last_timestamp := value_store.get('last_timestamp')):
+            value_store['last_timestamp'] = time_now()
         else:
+            time_span = time_now() - last_timestamp
+            value_store['last_timestamp'] = time_now()
+            energy = section.power_meter.power / 3600 * time_span
+
             yield from check_levels(
                 value=energy,
-                metric_name='energy',
+                metric_name='energy_current',
                 label='Consumption current',
                 render_func=lambda x: physical_precision(v=x, precision=3, unit_symbol="Wh"),
                 levels_lower=params.get('levels_lower'),
                 levels_upper=params.get('levels_upper'),
             )
+            yield Result(
+                state=State.OK,
+                notice=f'Consumption current is an estimation, '
+                       f'assuming constant power usage of {section.power_meter.power}W '
+                       f'for the last {time_span:.2f} seconds'
+            )
 
+    if section.power_meter and section.power_meter.energy is not None:
         yield Result(
             state=State.OK,
-            summary=f'Consumption total: '
-                    f'{physical_precision(v=section.power_meter.energy, precision=3, unit_symbol="Wh")}'
+            summary=f'Consumption total'
+                    f': {physical_precision(v=section.power_meter.energy, precision=3, unit_symbol="Wh")}'
         )
+        yield Metric(name='energy_total', value=section.power_meter.energy)
 
 
 def check_fritzbox_smarthome_energy_multiple(
diff --git a/source/agent_based/fritzbox_smarthome_power_socket.py b/source/agent_based/fritzbox_smarthome_power_socket.py
index d702cb9..3a96807 100644
--- a/source/agent_based/fritzbox_smarthome_power_socket.py
+++ b/source/agent_based/fritzbox_smarthome_power_socket.py
@@ -42,10 +42,7 @@ def discovery_fritzbox_smarthome_power_socket_multiple(
 def check_fritzbox_smarthome_power_socket_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-
-    if not section.switch:
+    if not isinstance(section, AvmSmartHomeDevice) or not section.switch:
         return
 
     def _get_status(status: int):
diff --git a/source/agent_based/fritzbox_smarthome_switch.py b/source/agent_based/fritzbox_smarthome_switch.py
index 7bfeac1..8700754 100644
--- a/source/agent_based/fritzbox_smarthome_switch.py
+++ b/source/agent_based/fritzbox_smarthome_switch.py
@@ -26,7 +26,7 @@ def discovery_fritzbox_smarthome_switch_single(
         section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> DiscoveryResult:
     if isinstance(section, AvmSmartHomeDevice):
-        if section.switch is not None:
+        if section.simple_on_off is not None:
             yield Service()
 
 
@@ -42,21 +42,17 @@ def discovery_fritzbox_smarthome_switch_multiple(
 def check_fritzbox_smarthome_switch_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-
-    if not section.simple_on_off:
+    if not isinstance(section, AvmSmartHomeDevice) or section.simple_on_off is None:
         return
 
-    if section.simple_on_off:
-        def _get_status(status: int):
-            _simple_onf_off_state = {
-                0: 'off',
-                1: 'on',
-            }
-            return _simple_onf_off_state.get(status, f'unknown ({status})')
+    def _get_status(status: int):
+        _simple_onf_off_state = {
+            0: 'off',
+            1: 'on',
+        }
+        return _simple_onf_off_state.get(status, f'unknown ({status})')
 
-        yield Result(state=State.OK, summary=f'State: {_get_status(section.switch.state)}')
+    yield Result(state=State.OK, summary=f'State: {_get_status(section.switch.state)}')
 
 
 def check_fritzbox_smarthome_switch_multiple(
diff --git a/source/agent_based/fritzbox_smarthome_temperature.py b/source/agent_based/fritzbox_smarthome_temperature.py
index 42875b7..86ebd47 100644
--- a/source/agent_based/fritzbox_smarthome_temperature.py
+++ b/source/agent_based/fritzbox_smarthome_temperature.py
@@ -38,17 +38,15 @@ def discovery_fritzbox_smarthome_temperature_multiple(
 def check_fritzbox_smarthome_temperature_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
-        return
-
-    if not section.temperature:
+    if not isinstance(section, AvmSmartHomeDevice) or not section.temperature:
         return
 
-    yield from check_temperature(
-        reading=section.temperature.celsius,
-        params=params,
-    )
-    if section.temperature.offset != 0:
+    if section.temperature.celsius:
+        yield from check_temperature(
+            reading=section.temperature.celsius,
+            params=params,
+        )
+    if section.temperature.offset:
         _status = section.temperature.celsius + section.temperature.offset * -1
         _message = (
             f'Temperature measured at the thermostat: '
diff --git a/source/agent_based/fritzbox_smarthome_thermostat.py b/source/agent_based/fritzbox_smarthome_thermostat.py
index 2579f61..fcd6244 100644
--- a/source/agent_based/fritzbox_smarthome_thermostat.py
+++ b/source/agent_based/fritzbox_smarthome_thermostat.py
@@ -46,74 +46,73 @@ def discovery_fritzbox_smarthome_thermostat_multiple(
 def check_fritzbox_smarthome_thermostat_single(
         params, section: AvmSmartHomeDevice | Dict[str, AvmSmartHomeDevice]
 ) -> CheckResult:
-    if not isinstance(section, AvmSmartHomeDevice):
+    if not isinstance(section, AvmSmartHomeDevice) or not (thermostat := section.thermostat):
         return
 
-    if not section.thermostat:
+    if not thermostat.temp_current:
         return
 
-    if thermostat := section.thermostat:
-        _error_codes = {
-            0: 'no error',
-            1: 'No adaptation possible. Is the thermostat correctly mounted on the radiator?',
-            2: 'Valve stroke too short or battery power too low. Open and close the '
-               'valve tappet several times by hand or insert new batteries.',
-            3: 'No valve movement possible. Valve tappet free?',
-            4: 'The installation is currently being prepared.',
-            5: 'The thermostat is in installation mode and can be mounted on the heating valve.',
-            6: 'The thermostat now adapts to the stroke of the heating valve',
-        }
-
-        if thermostat.temp_target == 126.5:  # == radiator off
-            yield Result(state=State.OK, summary=f'Temperature current: {thermostat.temp_current}°C')
-            yield Result(state=State.OK, summary=f'Temperature target: radiator off')
-        else:
-            deviation = thermostat.temp_current - thermostat.temp_target
-            if deviation == 0:
-                yield Result(state=State.OK, summary=f'Temperature current: {thermostat.temp_target}°C')
-            else:
-                _message = f'Temperature current: {thermostat.temp_current}°C (deviation from target {deviation}°C)'
-                _state = State.OK
-                if params.get('deviation'):
-                    warn, crit = params['deviation']
-                    if abs(deviation) >= crit:
-                        _state = State.CRIT
-                    elif abs(deviation) >= warn:
-                        _state = State.WARN
-                yield Result(state=_state, summary=_message)
-
-            yield Result(
-                state=State.OK,
-                summary=f'Target: {thermostat.temp_target}°C',
-                details=f'Temperature target: {thermostat.temp_target}°C'
-            )
-            yield Metric(name='temp_target', value=thermostat.temp_target)
-
-        yield Result(state=State.OK, notice=f'Temperature economic: {thermostat.temp_economic}°C')
-        yield Result(state=State.OK, notice=f'Temperature comfort: {thermostat.temp_comfort}°C')
-
-        yield Metric(name='temp_current', value=thermostat.temp_current)
-        yield Metric(name='temp_comfort', value=thermostat.temp_comfort)
-        yield Metric(name='temp_economic', value=thermostat.temp_economic)
-
-        if thermostat.next_change:
-            yield Result(
-                state=State.OK,
-                notice=f'End of period: {strftime(_TIME_FORMAT, localtime(thermostat.next_change.end_period))}'
-            )
-            yield Result(
-                state=State.OK,
-                notice=f'Temperature target after end of period: {thermostat.next_change.temp_change_to}°C'
-            )
-
-        _message = f'Error code: {_error_codes.get(thermostat.error_code, f"unknown error {thermostat.error_code}")}'
-        if thermostat.error_code == 0:
-            yield Result(state=State.OK, notice=_message)
+    _error_codes = {
+        0: 'no error',
+        1: 'No adaptation possible. Is the thermostat correctly mounted on the radiator?',
+        2: 'Valve stroke too short or battery power too low. Open and close the '
+           'valve tappet several times by hand or insert new batteries.',
+        3: 'No valve movement possible. Valve tappet free?',
+        4: 'The installation is currently being prepared.',
+        5: 'The thermostat is in installation mode and can be mounted on the heating valve.',
+        6: 'The thermostat now adapts to the stroke of the heating valve',
+    }
+
+    if thermostat.temp_target == 126.5:  # == radiator off
+        yield Result(state=State.OK, summary=f'Temperature current: {thermostat.temp_current}°C')
+        yield Result(state=State.OK, summary=f'Temperature target: radiator off')
+    else:
+        deviation = thermostat.temp_current - thermostat.temp_target
+        if deviation == 0:
+            yield Result(state=State.OK, summary=f'Temperature current: {thermostat.temp_target}°C')
         else:
-            yield Result(
-                state=State(params.get('state_on_error', 1)),
-                summary=f'Error Code: {thermostat.error_code} (see details)',
-                details=_message)
+            _message = f'Temperature current: {thermostat.temp_current}°C (deviation from target {deviation}°C)'
+            _state = State.OK
+            if params.get('deviation'):
+                warn, crit = params['deviation']
+                if abs(deviation) >= crit:
+                    _state = State.CRIT
+                elif abs(deviation) >= warn:
+                    _state = State.WARN
+            yield Result(state=_state, summary=_message)
+
+        yield Result(
+            state=State.OK,
+            summary=f'Target: {thermostat.temp_target}°C',
+            details=f'Temperature target: {thermostat.temp_target}°C'
+        )
+        yield Metric(name='temp_target', value=thermostat.temp_target)
+
+    yield Result(state=State.OK, notice=f'Temperature economic: {thermostat.temp_economic}°C')
+    yield Result(state=State.OK, notice=f'Temperature comfort: {thermostat.temp_comfort}°C')
+
+    yield Metric(name='temp_current', value=thermostat.temp_current)
+    yield Metric(name='temp_comfort', value=thermostat.temp_comfort)
+    yield Metric(name='temp_economic', value=thermostat.temp_economic)
+
+    if thermostat.next_change:
+        yield Result(
+            state=State.OK,
+            notice=f'End of period: {strftime(_TIME_FORMAT, localtime(thermostat.next_change.end_period))}'
+        )
+        yield Result(
+            state=State.OK,
+            notice=f'Temperature target after end of period: {thermostat.next_change.temp_change_to}°C'
+        )
+
+    _message = f'Error code: {_error_codes.get(thermostat.error_code, f"unknown error {thermostat.error_code}")}'
+    if thermostat.error_code == 0:
+        yield Result(state=State.OK, notice=_message)
+    else:
+        yield Result(
+            state=State(params.get('state_on_error', 1)),
+            summary=f'Error Code: {thermostat.error_code} (see details)',
+            details=_message)
 
 
 def check_fritzbox_smarthome_thermostat_multiple(
diff --git a/source/agent_based/utils/fritzbox_smarthome.py b/source/agent_based/utils/fritzbox_smarthome.py
index b6a9137..25c4b8b 100644
--- a/source/agent_based/utils/fritzbox_smarthome.py
+++ b/source/agent_based/utils/fritzbox_smarthome.py
@@ -18,49 +18,35 @@ from typing import Any, List, Dict
 
 @dataclass(frozen=True)
 class AvmTemperature:
-    celsius: float
-    offset: float
-
-
-@dataclass(frozen=True)
-class AvmAlert:
-    last_alert_chg_timestamp: int
-    state: int
-
-
-@dataclass(frozen=True)
-class AvmButton:
-    last_pressed_timestamp: int
-    id: int | None = None
-    identifier: int | None = None
-    name: str | None = None
+    celsius: float | None
+    offset: float | None
 
 
 @dataclass(frozen=True)
 class AvmPowerMeter:
-    energy: float
-    power: float
-    voltage: float
+    energy: float | None
+    power: float | None
+    voltage: float | None
 
 
 @dataclass(frozen=True)
 class AvmSimpleOnOff:
-    state: int
+    state: int | None
 
 
 @dataclass(frozen=True)
 class AvmNextChange:
-    end_period: int
-    temp_change_to: float
+    end_period: int | None
+    temp_change_to: float | None
 
 
 @dataclass(frozen=True)
 class AvmThermostat:
-    error_code: int
-    temp_comfort: float
-    temp_current: float
-    temp_economic: float
-    temp_target: float
+    error_code: int | None
+    temp_comfort: float | None
+    temp_current: float | None
+    temp_economic: float | None
+    temp_target: float | None
     adaptive_heating_active: int | None = None
     adaptive_heating_running: int | None = None
     battery: float | None = None
@@ -75,12 +61,12 @@ class AvmThermostat:
 @dataclass(frozen=True)
 class AvmSwitch:
     mode: str
-    state: int
+    state: int | None
 
 
 @dataclass(frozen=True)
 class AvmSmartHomeDevice:
-    fbm: int
+    fbm: int | None
     functions: List[str]
     fw_version: str
     id: str
@@ -111,87 +97,96 @@ _AVM_NEXT_CHANGE = 'nextchange'
 def _get_battery_low(device: Dict[str, Any]) -> int | None:
     try:
         return int(device[_AVM_THERMOSTAT]['batterylow'])
-    except KeyError:
+    except (KeyError, ValueError):
         pass
 
-    return None
-
 
 def _get_lock(device: Dict[str, Any]) -> int | None:
     try:
         return int(device[_AVM_THERMOSTAT]['lock'])
-    except KeyError:
+    except (KeyError, ValueError):
         pass
 
     try:
         return int(device[_AVM_SWITCH]['lock'])
-    except KeyError:
+    except (KeyError, ValueError):
         pass
 
-    return None
-
 
 def _get_device_lock(device: Dict[str, Any]) -> int | None:
     try:
         return int(device[_AVM_THERMOSTAT]['devicelock'])
-    except KeyError:
+    except (KeyError, ValueError):
         pass
 
     try:
         return int(device[_AVM_SWITCH]['devicelock'])
-    except KeyError:
+    except (KeyError, ValueError):
         pass
 
-    return None
+
+def _get_int(value: str | None) -> int | None:
+    if value is not None and value.isdigit():
+        return int(value)
+
+
+def _get_float(value: str | None, scale: float = 1.0) -> float | None:
+    if value is not None and value.isdigit():
+        return float(value) / scale
 
 
 def parse_avm_smarthome_device(raw_device: Dict[str, Any]) -> AvmSmartHomeDevice:
     return AvmSmartHomeDevice(
-            battery_low=_get_battery_low(raw_device),
-            device_lock=_get_device_lock(raw_device),
-            fbm=int(raw_device['functionbitmask']),
-            functions=get_avm_device_functions_from_fbm(int(raw_device['functionbitmask'])),
-            fw_version=str(raw_device['fwversion']),
-            id=str(raw_device['id']),
-            identifier=str(raw_device['identifier']),
-            lock=_get_lock(raw_device),
-            manufacturer=str(raw_device['manufacturer']),
-            name=str(raw_device['name']),
-            present=int(raw_device['present']),
-            product_name=str(raw_device['productname']),
-            tx_busy=int(raw_device['txbusy']) if raw_device.get('txbusy') else None,
-            temperature=AvmTemperature(
-                celsius=float(raw_device[_AVM_TEMPERATURE]['celsius']) / 10.0,
-                offset=float(raw_device[_AVM_TEMPERATURE]['offset']) / 10.0,
-            ) if raw_device.get(_AVM_TEMPERATURE) else None,
-            thermostat=AvmThermostat(
-                temp_current=float(raw_device[_AVM_THERMOSTAT]['tist']) / 2.0,
-                temp_target=float(raw_device[_AVM_THERMOSTAT]['tsoll']) / 2.0,
-                temp_economic=float(raw_device[_AVM_THERMOSTAT]['absenk']) / 2.0,
-                temp_comfort=float(raw_device[_AVM_THERMOSTAT]['komfort']) / 2.0,
-                error_code=int(raw_device[_AVM_THERMOSTAT]['errorcode']),
-                next_change=AvmNextChange(
-                    end_period=int(raw_device[_AVM_THERMOSTAT][_AVM_NEXT_CHANGE]['endperiod']),
-                    temp_change_to=float(raw_device[_AVM_THERMOSTAT][_AVM_NEXT_CHANGE]['tchange']) / 2.0,
-                ) if raw_device[_AVM_THERMOSTAT].get(_AVM_NEXT_CHANGE) else None,
-            ) if raw_device.get(_AVM_THERMOSTAT) else None,
-            switch=AvmSwitch(
-                state=int(raw_device[_AVM_SWITCH]['state']),
-                mode=str(raw_device[_AVM_SWITCH]['mode']),
-            ) if raw_device.get(_AVM_SWITCH) else None,
-            power_meter=AvmPowerMeter(
-                voltage=float(raw_device[_AVM_POWER_METER]['voltage']) / 1000,
-                power=float(raw_device[_AVM_POWER_METER]['power']) / 1000,
-                energy=float(raw_device[_AVM_POWER_METER]['energy']),  # / 1000,
-            ) if raw_device.get(_AVM_POWER_METER) else None,
-            simple_on_off=AvmSimpleOnOff(
-                state=int(raw_device[_AVM_SIMPLE_ON_OFF]['state']),
-            ) if raw_device.get(_AVM_SIMPLE_ON_OFF) else None,
-        )
-
-
-def get_avm_device_functions_from_fbm(fbm: int) -> List[str]:
+        battery_low=_get_battery_low(raw_device),
+        device_lock=_get_device_lock(raw_device),
+        fbm=_get_int(raw_device.get('functionbitmask')),
+        functions=get_avm_device_functions_from_fbm(_get_int(raw_device.get('functionbitmask'))),
+        fw_version=str(raw_device['fwversion']),
+        id=str(raw_device['id']),
+        identifier=str(raw_device['identifier']),
+        lock=_get_lock(raw_device),
+        manufacturer=str(raw_device['manufacturer']),
+        name=str(raw_device['name']),
+        present=_get_int(raw_device.get('present')),
+        product_name=str(raw_device['productname']),
+        tx_busy=_get_int(raw_device.get('txbusy')),
+        temperature=AvmTemperature(
+                celsius=_get_float(value=raw_device[_AVM_TEMPERATURE].get('celsius'), scale=10.0),
+                offset=_get_float(value=raw_device[_AVM_TEMPERATURE].get('offset'), scale=10.0),
+        ) if raw_device.get(_AVM_TEMPERATURE) else None,
+        thermostat=AvmThermostat(
+            temp_current=_get_float(value=raw_device[_AVM_THERMOSTAT].get('tist'), scale=2.0),
+            temp_target=_get_float(value=raw_device[_AVM_THERMOSTAT].get('tsoll'), scale=2.0),
+            temp_economic=_get_float(value=raw_device[_AVM_THERMOSTAT].get('absenk'), scale=2.0),
+            temp_comfort=_get_float(value=raw_device[_AVM_THERMOSTAT].get('komfort'), scale=2.0),
+            error_code=_get_int(value=raw_device[_AVM_THERMOSTAT].get('errorcode')),
+            next_change=AvmNextChange(
+                end_period=_get_int(raw_device[_AVM_THERMOSTAT][_AVM_NEXT_CHANGE].get('endperiod')),
+                temp_change_to=_get_float(
+                    value=raw_device[_AVM_THERMOSTAT][_AVM_NEXT_CHANGE].get('tchange'), scale=2.0
+                ),
+            ) if raw_device[_AVM_THERMOSTAT].get(_AVM_NEXT_CHANGE) else None,
+        ) if raw_device.get(_AVM_THERMOSTAT) else None,
+        switch=AvmSwitch(
+            state=_get_int(raw_device[_AVM_SWITCH].get('state')),
+            mode=str(raw_device[_AVM_SWITCH]['mode']),
+        ) if raw_device.get(_AVM_SWITCH) else None,
+        power_meter=AvmPowerMeter(
+            voltage=_get_float(raw_device[_AVM_POWER_METER].get('voltage'),1000),
+            power=_get_float(raw_device[_AVM_POWER_METER].get('power'), 1000),
+            energy=_get_float(raw_device[_AVM_POWER_METER].get('energy')),  # / 1000,
+        ) if raw_device.get(_AVM_POWER_METER) else None,
+        simple_on_off=AvmSimpleOnOff(
+            state=_get_int(raw_device[_AVM_SIMPLE_ON_OFF].get('state')),
+        ) if raw_device.get(_AVM_SIMPLE_ON_OFF) else None,
+    )
+
+
+def get_avm_device_functions_from_fbm(fbm: int | None) -> List[str]:
     functions = []
+    if fbm is None:
+        return functions
+
     if fbm >> 0 & 1:
         functions.append('HAN-FUN Device')
     if fbm >> 2 & 1:
diff --git a/source/gui/metrics/fritzbox_smarthome.py b/source/gui/metrics/fritzbox_smarthome.py
index 7a8fc12..f7cdc27 100644
--- a/source/gui/metrics/fritzbox_smarthome.py
+++ b/source/gui/metrics/fritzbox_smarthome.py
@@ -30,6 +30,18 @@ check_metrics["check_mk-fritzbox_smarthome_thermostat_multiple"] = {
     "temp_comfort": {"auto_graph": False},
 }
 
+metric_info["energy_total"] = {
+    "title": _("Energy total"),
+    "color": "31/b",
+    "unit": "wh",
+}
+
+metric_info["energy_current"] = {
+    "title": _("Energy current"),
+    "color": "16/b",
+    "unit": "wh",
+}
+
 metric_info["temp_current"] = {
     "title": _("Temperature current"),
     "color": "26/a",
@@ -51,6 +63,20 @@ metric_info["temp_comfort"] = {
     "unit": "c",
 }
 
+graph_info["fritzbox_smart_home_energy_surrent"] = {
+    "title": "Electrical energy consumption current",
+    "metrics": [
+        ("energy_current", "area")
+    ]
+}
+
+graph_info["fritzbox_smart_home_energy_total"] = {
+    "title": "Electrical energy consumption total",
+    "metrics": [
+        ("energy_total", "area")
+    ]
+}
+
 graph_info["fritzbox_smart_home_temp_control"] = {
     "title": _("Thermostat temperature control"),
     "metrics": [
@@ -78,3 +104,12 @@ perfometer_info.append(('stacked', [
         'total': 50,
     }
 ]))
+
+perfometer_info.append(
+    {
+        "type": "logarithmic",
+        "metric": "energy_current",
+        "half_value": 100,
+        "exponent": 3,
+    }
+)
\ No newline at end of file
diff --git a/source/packages/fritzbox_smarthome b/source/packages/fritzbox_smarthome
index 0d4ae91..4d2081e 100644
--- a/source/packages/fritzbox_smarthome
+++ b/source/packages/fritzbox_smarthome
@@ -49,7 +49,7 @@
                    'plugins/views/fritzbox_smarthome.py']},
  'name': 'fritzbox_smarthome',
  'title': 'Fritz!Box SmartHome',
- 'version': '0.8.4-20231231',
+ 'version': '0.8.5-20240105',
  'version.min_required': '2.2.0b1',
- 'version.packaged': '2.2.0p14',
+ 'version.packaged': '2.2.0p17',
  'version.usable_until': None}
-- 
GitLab