From 0553f3701d42ad821be8eee41095c02e89c7ce79 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 5 Oct 2026 18:47:15 +0000 Subject: [PATCH 1/9] Keep blocking board I/O out of the event loop - Create dScriptBoardHA (reverse DNS + GetStatus + GetConfig over blocking sockets) in an executor instead of the event loop. - Add async_check_available(); heartbeats only run a lightweight GetStatus (config changes are detected by ValidateBoardConfig right after - before, the full InitBoard updated the counts first so new entities were never detected) and the board sensor uses the async check as well. - Availability checks reset the firmware marker first so a board that stops answering is actually reported unavailable; check_available returns True on success (heartbeats logged "unavailable" every time). - Board sensor polls the web page via the shared aiohttp session with a 10s timeout and always closes the connection (urlopen had no timeout and leaked connections on the board). - Await and import async_dScript_GetEntityByUniqueID in ValidateBoardConfig (was an undefined name). - Require dScriptModule>=3.5.0 (request serialization, timeouts). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 12242 bytes .../__pycache__/board.cpython-311.pyc | Bin 0 -> 19989 bytes .../__pycache__/config_flow.cpython-311.pyc | Bin 0 -> 10460 bytes .../configuration_schema.cpython-311.pyc | Bin 0 -> 3920 bytes .../__pycache__/const.cpython-311.pyc | Bin 0 -> 2386 bytes .../__pycache__/cover.cpython-311.pyc | Bin 0 -> 12138 bytes .../__pycache__/diagnostics.cpython-311.pyc | Bin 0 -> 4261 bytes .../__pycache__/entities.cpython-311.pyc | Bin 0 -> 11542 bytes .../__pycache__/light.cpython-311.pyc | Bin 0 -> 6257 bytes .../__pycache__/sensor.cpython-311.pyc | Bin 0 -> 1617 bytes .../__pycache__/sensor_board.cpython-311.pyc | Bin 0 -> 8850 bytes .../__pycache__/sensor_button.cpython-311.pyc | Bin 0 -> 4969 bytes .../__pycache__/sensor_motion.cpython-311.pyc | Bin 0 -> 3933 bytes .../__pycache__/server.cpython-311.pyc | Bin 0 -> 17526 bytes .../__pycache__/services.cpython-311.pyc | Bin 0 -> 8014 bytes .../__pycache__/switch.cpython-311.pyc | Bin 0 -> 6468 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 15023 bytes custom_components/dscriptmodule/board.py | 33 ++++++++++++++++-- custom_components/dscriptmodule/manifest.json | 4 +-- .../dscriptmodule/sensor_board.py | 23 ++++++------ custom_components/dscriptmodule/server.py | 2 +- 21 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/config_flow.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/cover.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/sensor.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/sensor_motion.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/server.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/services.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc create mode 100644 custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc diff --git a/custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..480b3ae77ca28280233e9cf30c5989aeb72eca79 GIT binary patch literal 12242 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 WSZ~n10?tHD#yEB0VB8@iv;V)H-LPT+ literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99e17fb79d6cb02f1d0d447e8cee78cbd494917f GIT binary patch literal 19989 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 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e1e2bfc1a2eea6a7bc1bb049f16abaf7cf68157 GIT binary patch literal 3920 zcmcguO>Emn79LWREX$Pq6aW7tOzgCF>{Xp?-8OETMzQ5YsB9UQ?TuM)8Cs+jsifo` zQc060O@IbHEDCII?O_-2DNWHFa_Aw4^wOe5F9pbeLJR@{0_-k!dvlQ%D0RY}5R|X}^>y|ieuVx`1h<4r9qQ3Gh0w=n2}y`Y5+%_J zrP4f2k-kUqs0`0IeMa%}UKnE(AMbOX4ZI(oUZqhD@Bs(oQ<_wkXVoAdR6~5IY}c%| zq+mX^m2ZQQ2Fb7NQQP@;wS(_aJNZtvi|nO*d$;g@38YZP_8WzXRPV z_dEkSDEB=9eQ=k#LvsI4w6pqiE?#c0e@93Ad_~(Kcki^XeUps0-kKkFc8DcABn7V{ zeneuDXe4xLcq*S;&!h`j)HC@UmrR|LRZ-*C^O%#8DV*8RXY*1)k;6ZbrAH{cNzCQ) zx`Wn0^v+~*qA~})P|BG}kaIfD$l8d)tUKbkQ;{5xDrk3Q+c%we08XdNR1ys${Ycev2;o0oq3gI-^KGj*$y>`c{pG6WGF`vo zWjb4li0pui(_eFYuwOeYvin@!4PfNw6;=X=Pq-R{QuGSE%N6=PI$3^Rpe~?yJS*q| zHR8MUT12~;OHFcE)(beti8)Sl5;d1!%gQO8yO7b(aj62vkbJrGqEe7G4zhSTNnIK} zsByo80hmKb%es)5UyLQ@lERa67w!PBFgYIQF1`K?c9Yz?m{DYDk^`gRgIf5YHZrmw zlbEu-lDt+(<2|JBIiFW-U+J8&{R{G+3K=X**yrfLIZU#TO{dP=J`E0%TpE+~g$biD z32sdCsm*NUv5w&~gD{CGn~vo$2`Ag1*dPa)sNg1|B-b0e!Flsc-u7yWEN|G2(RWg^ z1GBv{#(8XeU@5y%5K@Y$X@Xz}1VMF~#F(H`aXRYzG1}mDZXt823C0i+_1njvPzdv^D z-q^7(SH5S>u_bG4$zYdFcG+T=i)VQ2jPUq`^JmR*(Ha*GcFknhEOxCZr7bC2eEU69 zx@t*ROBQ`MmHXl2_rk}&eE0h~GyJ9%e$!xAO?K5{SBr0*wcbi^H~A(5KO)}?O+S&w z@DKeQLd~5Ys-Hy6&|WLF*YH1~ZZ(e@{?T6^G_`Ld+B;NjD%ZfPVJ*?a27!VsRo1;WM> z+X%(%=j$=&WMxCf8o|QVQGk4t0TKY~?1r++ZhcIL$?e_tmgXl^EfLfqcaVsLswJ9} z4B*h*;dUu)G(u{K!^;6*M~T|WE6svXa~p*n=_4wVpfTB2%#mh4X~+TUFc%a4e1;xD zi!eE4e)S(KQT;eR0V27JX&sRMwmlR@ZK1H?)Q9MRQD3)Ew^3iWQ0SWTtLaoR57Dqu zU$<$7f-rfOCV;331HJgfy3I6^>HhysFKQe7sLN_Su=$GFI%c(wU28DVSgD$5?BU+w zPf~x)ZZR#_rmn}0*1?;r1~X|glNK|1=j7d3S@F?;G5m_b95tDv7IXB@k-JA-MbBp3 zU=EwiVT(C@`^XnByW{l+FWve5-It7$OXjP~)~m}drf)N6FcT&-VKEc8@fQ~%Ya9Za h`u2GsYwYtF2=aiB@>Cnpf!NYQL2h`w!LLJj{0F(CY(M}2 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af06d225f1dfe0d56a6233167526b8b7711fd424 GIT binary patch literal 2386 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 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..caa4b65e7bb1302eedc61d827f6455395a76546c GIT binary patch literal 4261 zcmdTHU2NON`FNxx%Can5PVF>_9omVVDsjAJU4|mdlBx1fyu`{D$HA)9*L84h$zrs9z6DmI=%S0v_A~P~A zG8)ZL2J38*)wm4j)wyCo3ub~^C=>GNK#|Yzpc5#DGhx8NVviQdL_Arj*sDb|QLoMy z`?Odl2KBJqQ|#9UG6PVL$h~=*i8t^dB?@0S&@@eXYMUYC0sQ@v8Iq&Qu-tbZNI8}{ zC=bg+Kjbn`%Yh}5IJo|m8CA;ZhGnZ+OR&nNl407ys$mLtUJ>M_tf`jlMMEwZ6+zW) zC1*;uYUtA+VCMp}pt5y~(T% zE3;WPn0pwLePtUs4_aKiw^b$E;Q51=_bRhV_3s`dcHgeXabmu-$#z5lL%FZWTsNET z!CmDIwsUQ6umx|Ap+*5C?-l#$W{r@&Eeg@5Y&!_H!{09q*`Qha0+9oo?5pfj1K(zD zlULXm$Zh5`#XZ=~hrMy{h&m~>;$@FE?IC2>30v6Zc1C=I$|2mB|8dm$ZWjL^MLpcj zhka2$wi`#eXU|Haas(r3x9jxo(~0iW>D#9h`&={9-_4uGiKZ z;b4MnXp*W6cvivj15ori>*>$Y)5n;$zWk*9mDcRMp$nRSZr|)U##e;K8SO?p`0jxY zQuG_Uyrded5G>1$HET^#5GGucvToGJ4fcBezhdpj#3d0oG4r|sS-DltxqNeZy1c*q zRN2JS(G5u!EXAztMz77zBvaSL)YbId!n_-veI=`u@Hzvx1k*H3mxVil8y3ZE5$+G7 z==O*Wr=ZT+YbC|yMNyYD1!q!&u0}0OT2V@SQ5{J9NWfTh~ z0u;Q4w60#$r8Rf_)3=d14ULb$-+C4<6@Q1{7Wpd|`O)I{7oGUCzy9_c<+om~aOoMMt-)`o_Nqxx>uUe-IMBME~i*x(91xiASf-zp?zgl{Z&@ zBfcg6NvoWCv3lx7=jcm!xx3tlJCOr*LIZ7}(KR$5PEmlf^c&dYEM1~7$}(L+B+^?b z%TgJ~6sdwLh=7@+d8BgG^wB0ZxIbOF6W1kB6y3R0Kp4IfF^AWL&7 z%TpB_WN86qEo6CY%^e3+b(%Zjv*%D#%{301ko+H0M*OMA&-{z8osS)`c;yuI(eKFm0hco|L{f@cey6hd31(^2!W|$}+H^ zJ{|CciEZ`auSPty)mI1JX@^X;e>L)Dr}L|k=bg^4&QTn*8{kR&&}+{*{S#Z!+R*4d x-g)YzL*nlbjQ@1FIxv3kxyry)bzo{M)Ec%zrfT7#ExyhjV*2Z(3o!AT`fn!C4SfIr literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3cde8e28029740d316646b4076ce551fae0bc12 GIT binary patch literal 11542 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 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3280b07b937af80acb1208b3c7f45d6843eb16c4 GIT binary patch literal 6257 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 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca8e8d19dfbe55ea1e1df848611b8c1045038492 GIT binary patch literal 8850 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 Xf*9v2+WetM`oFiTe|P~G*}?w}L`G}J literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9ffd9aa2bb2b9fccee449e8ed287eabdc581a22 GIT binary patch literal 4969 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 N4(%jyPx0vZ{R>7DX6^t0 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..787c25f9a55a49494111b2797e70e17c99a5088d GIT binary patch literal 6468 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 IDD3?H1=WW12LJ#7 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60d61826d4a42a5c9d7187e0b2c390fab886f689 GIT binary patch literal 15023 zcmdTrTWlLwcEjOoNQxpQ>OoPqOv#dC$+oN{e#LQY>p{t~t%vn;ti)z04kc0MLmrMS ziy7KZHrT2Q1FHrB>;~CJA9d=jH)uXutUtO%n#ZnNB*0KRf>{Cv3>4dTf&I{88z7th z^qf1K;ZULydAIw~;qc6z`#kq`UiZx3*zHydu225+)0yEGiu!kaQ7*k4(EX0qQPgc} zlwzrIiq)}nL>HyUAriv+h(2l$;iMXN_;}y}$@yck`cvZA|ygKS0 zck3vc3Rz}q6m&zL4*<{m@RzUgTGk%g#+Dv~SGI*Md&@Aso!!IkWh>q?j@OY;C4_cB zXdhb#Aurp??q_#GsGc=VQB%~Uo^4~B;k|)14O7j}ChOQlkPFZ9(KtI733;bOk=YRE zot%pW`EWdz_%$}%tjpR0u~?iBkT`gCOoe!VG!XO$Se6SV5)ftV4#xr!2-w5X**FKu zq{e=XITeqF+7pRzf)B)ah_H3WW0T=2UySD#;MLX6vJejQ;ZUM85Q$6#f|nt>q;sIZ z+u!9I>+SRn{~8CO*_bUOk?mbweqaAc??|t2IBO?SgBJ!)clbI-vZk(qzV_b!?DnqV z&Y|AH5jo?9kqd*qk%7*E(f*P4k&&TnjgmYvFxcBUGC-;$xi}*$NP^9tVncq|lDX9RNMYJ+v9`&}2r-li-RuSpfCpXdtbFs0*ZD3QCCHDM(V z=9cD7`8Rz&@*Nwbw+K8cPVicwZ6m**@>9`0knNzZC^)SpjbnSzD{tLL-V?M>YDxn zHLq(nB@e;+^1}M^=GK>YGR{T4y@TF;-uVC*m?dj8&Upigg;>xVx)ut~;nIXfLx*RR zyP6V^aorO2Pjd07KRkQXi>b!}Cd=B|juzhi$+mAVI~fQ^LM*9ccT=LZDbd_)<8WTM zG5}d48=9D#;z}`W@m&jsW)ZEdF~o6kE~|$Xl(qQ%!AKyH@cXk?e{PdN*uXE$hO&&` z9}7f7et)x`tHet5FbG*)D1n5_>-B!aKtCgi*4c$@^(Ot}>LDxs6B2-%)S7`YcG15o z-M(BdmNuqK8>Q05Mg3#O@k9F$>|)jN&rJ{Mhn;C=P+|r}W-wzb70a7eY)zuADdVbM zI*@UcFIvBTY^zwKbWo8Ns+FAja@Xq6s5o{$J@m3P^s+eqiZmXQ#%EW#tK$5%G`Ape z3;zum={o7(Qk12Oh8KWqTZUi5wWi1RA&~Gu$KE`0occ%Iaq6F}9Xs^@%(Rzuc=Vrm zjPTN(HIO~3-C4K}zlVFY4r0$xI(eT$q;f55_N)>I`%uTLdk$7N^#M%7eVht%=_p>^ z4LQ<_1$tRigHjTAc;VjS^nxy-yXE0+`8=@i=??(k`)W_PHa?$BZGyAD z0B5>jM{lTcJze1)`3CZPoHZ0;`#p*^zOEmmZtK4feDc;DYb4aCJYSYjAAJF~DlN$8 zf^jfuvE{4tX@b76O+i0XqNL8KREpoO#K8=#D>0+?r3m#gru5hKh&M|@8tP+CKHH9D z<)~LC{9fQl-T=>Y;fXmul<>wUy#a4xHWUm`hJ)Vt#7rp2CwCCCLCBGRkc&@ofoL=w zo9aSxfYc(Z^Cug>Bainb$jISj_b2y%Yu+MM$VmtgR|TbI@}p~^HDRHMO z?P!o34H!ACd+e;fZGYP?)^&Y8`H)>5c}0BHF9t&Ckx6M}GVPp_oKvE6>T!9^JNuS( z>GB4tyg@7}ey`aSJih*_ges|AqiCZ&57ch-d|9=6ZbTd%OP@P0ojWgH7?&=v(uMfy zl{xY1eEP~Y>B==AgPg8|(8Nwc6FUh_?4&bH$)Z8|5#ncrR*?4L%)Hgn)Uk*9WRJD0 zME}Xb_L45M{xh=?UV^~fO@O+v%Au%UJ=7fg67%UUIH45QVQ<#Z7g+YPJ@a2>^c0qi_pYDH6>VGZm z3`ov^=nQu^w?IINv*`cG=wOFH-HKiy-5m#hIeLV`mX1|(F}#W-B&MDQdW zAZuU)d?0I>h{q#Ar0&XvOPGjLKL=q*5vK%dMoFi%YDa#R3%VJVK;>go2CV|JiMXWG zmIbj0+SLkTe`wphx-BUxj}eG&f1Wb_-`2UTQRviRq6A~1kdrbArs6qy4S@pT5ymku z7N*RC`KIpHD}p&MvI(@T9)eIgCFnVWUsWW^5By-6xPh6kd?axrf@|F%#1qod4ZO%SMmevSXW{OHBoYX0Bi2P zy6%Y5O{bXa3}VibkVfn^CZErVy+fg3D10^KWrvAn$U6}aaBNP{^`aJyig->jPae?- zs<{IGo)F)GWjYpm2akFap#T@024UDcv4AB(l}CxVKY8doiw23+$vYX2u`(7|FxmB; z<+_QM?&agT#<5K(S)jI;a|d9MWLcRZ)XyJgHB1UALsk!>GKZ`rsdwjpB$HJj{fYJR0C4C*>Z${#omm2+k2L~yCiq> zy{4bEO70hawpViZJaV5|ai4kEn|6;$?yco8#!ITu7yECr3+b7;WardQ<8q==BlIyTolDnUH z>K=Ixu6Pcv9_o9@r9DHEXGpAAe=k}x4!7v=W;~5|UzI%1J@On{@f`YS;p4`%r$_Si z0D7)E(Y5Q|0RVEtnM$u%xf{Z_Z@hiuZt5d8UHzg|{i5i65jeQTDce!{#lcZ&@RIo2 zM4AaoOi*Nkfc_${SWc#iM;b z1~+u4Q7O2g8>PRZsPptIs2sdXUqpT3Jbek%)W;M?+NUuNAmrO3B)SC{R;Gzz1()Yr zo#npc)Thsh9X(NnU_=Qd%PuoJ@kLIKZIwnXwJ!oH9j zZJ^mcQmkWPlx&~gE-mv^*=EPnl-F`l87aa-eNR(|%)q@HwYp}zhF_wTBC}NFoZJxv z->uInJn&&rSU$dWDqFM_m7v>&<8 z1^P8iQy*bs*P6jN%M9iNNLb<`FaH#~Rt4I%(1Q3@r@nJP^(nIp;eM;HO#kT%?RH;@ z{__$eykyJeX(sYl?zr%q?J84g-*||4F>7asEB~+8Qwe*aW>j5Tn>Wv7wAw*Fc5?#GtK^HK!c?Jd2uFqbDN5D_ zIahJ>{s++Q`|y{qlwL5XCEgTF+S>EjkmC(AY7qqofa{o!RyUjjBhS{DNb#{0%v9F7yspHIdhk+|eOazs$Uz64f>2)LE5IL! z;>L?LX;-2a{|)Qf%rfZGkg|e%gPFBNz^x%=BVlUVqt{(QCrgcs2 zMb~=~J4v}vese4P&AHjwfo*D?_;%~B1Opkr-6>{E^HR2H-OP+v8Cz%vXt35ffbUe& zC~Brb3A5#e`$TJ7f>l(Wa=|FLa+IzTgutCj$wVoCN(sZRtjLdMsv>6BrU^!E8h<8V zN??SFLdu%hU$8QZQ-I2?jR4fW&Q^2l?*$j%SJ*y`04OtgyXR$+%>71ivF0RDvy`g< zqvCtIYKs`T)?-9df>S#_=#~Pb0;66yf2m4-K!Z2r%F}b9at00kFlVO*^x1 zJimoLRcqVO(kW=etF)nQyAWfb@jn$RH{*0#JoBqVTN}!zLfLYQ(vtQmR2HsU*!5eS z*N=X)q`URg4V-6kOPt5Or4cdy$@mZ`&-YaYI%jzV?xUk%r{baeI$k7{aW+_AEnl5$OmKoP~VJNd#^>XID|yyXO6(lZ z$736!`{L-}m5VlIjS;LoYeJ8U;B?j)#JaQg1gQ<2y@)rM@(S)GP-V6xmr6!B`QlbO zo}Wf_QQ$}>&upb|f81L{RU)fRsf|qMW_F5#1qBVlJDJhBSunACl`4oI3pWCD0o^B~ z0iJC<94jRIwt^(&3CFGmB4Jjo(TnR|al=6j!5I@y1CDR8It`j+hb=&1@ZU?G*kXCL z5cmUep#Zx8Zild86Uo6XR-i!uN+{!0Wc4S{ZKcLd)&P!65lhV;jiu%=ObR*o$elj` zVr*zKFc;xDV!A=?BWr@epM%|mL|1kPA{HHT7NQ3YTw~kG`w5|o5SeohB^PcOK|g{~ z1Sl17FC!R4a2~-q1Y-z>5TGKPHJ}S5hq3{OEH&%&cg`jFc(gmrMML2J8RAgZ(zp$v zZHE|-vev%#PFURNlAJZ6n`n$}uF{;k^kB|j1Sr~N8D$oT!AUkWq0~(bO>!Ry`UG== zG{F~9&3Y97;k@JU$iP6yX>>t0lf?q|hFYZo|3=eA)*5Cp-((m_gmISmQTd?e1fD47 z4tLf)Ljnj3*D~ zGBT+EVUhrX|KO9_U29a0z5cfdmdtCkyR2Sar1=E{`2|>~WSN}8(x>Smtgvzz;{ZYw zz{j5Y_x9b>r9CZ@r$wwNa%burmQFvZ-m!dSrFxH8z2~DI>A+cdu8t+3iaEd*>N~IV z(GNopLyx^LJ(!lfJ$ITO*ETF4zUNEVJ}1>a2Zr3r`p51a@7v$Ci@WB;c>&5?({D2I31Oy!CowziBDlg?Q|d3GypBa;{xmrY=b3ju%r!^ep2rf z>tB3uN~-sL%s%vq!{g$sP}gj_{)$w8<&NobQ}@UG!_hA;i5G*?#fTW2gNoxivORZ^ z-3btC_ihEArhm0<=lgx{_K7V;)x>iZmHWeGh-+%p873Hpn zIV;lub&2uf)z<-qd6;pSy&h#O#}Kap`4spf9m2FJni$qE(}dhi!CXQXd;q#}dKTZ} zbW(o!^jMkxj2_a?>ihICBR%?lJ!DZI=P|PKWsCy|`2c2Wy>||3e>uWcRu2In7|v=u zqCc1+JM>;p+Ic{79uS=ee!n)V0~$c6!Pj4n>2j`a#b|I?ygVyiUI6q|dV3ao*H06Y zKSU4X^695Xup{^Y%*N!!JVpmFatsCl3dCp*(-QF23lxaabC{++u4AO-2F3w|d;m8k z$%zPX(YLyET_)-?lhwCR|CzJB+_zi*`EDb;{KC*_8#Yt_>g?EmPH*_)gbrT5q`GwQ zlGf4ilGa;?o;RoM?KMNK=9OJ0h+1hiLe$Fhq0K@*S|cHHzSfDEONv(8 zgV|3ZAac@a456^Zkr2U=Ahi>|kn*$fp!^-n1>dc3V4wow5wtw;VId#JWKHm8 z3ut`uS5+2SXN!agdFSsv&K8vz1YHS!rIh6SQ$Z|4~H=USn zfu5ZOl;MLOBJ7r7q{Hvmd>#jbP>;p;BX|}8I^d84NFty8nED;OQ$&{ghB+pGCU=~h zhd8v@C4L1EzID;*GE}2T?k7}(Sa@d&Um-O^xy8aeL+um`?+jIXll;^GY+&6!k=m=h zGt>dG@Xk;^vG86q&^p*cn*pl{Q~y}tq{??LRZC?J%SX~>d!@3yH_a-ZX=?A9)k+xo z2Iwi#fkS=~P-nx0B4FEg9Xicy0#E8Hb#PKz1hi2dbT literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/board.py b/custom_components/dscriptmodule/board.py index f192a2f..563ce96 100644 --- a/custom_components/dscriptmodule/board.py +++ b/custom_components/dscriptmodule/board.py @@ -30,6 +30,7 @@ create_entity_unique_id ) from .utils import ( + async_dScript_GetEntityByUniqueID, async_dScript_setup_entry, ProgrammingDebug, async_ProgrammingDebug, @@ -42,7 +43,8 @@ async def async_setup_dScriptBoard(hass: HomeAssistant, entry: ConfigEntry, tcp_ """Set up a new dScriptBoard.""" try: _LOGGER.debug("%s - %s: async_setup_dScriptBoard: setup board", entry.entry_id, tcp_ip) - dSBoard = dScriptBoardHA(entry.entry_id, tcp_ip, tcp_port, protocol, aeskey) + # board init does blocking network I/O (DNS + GetStatus + GetConfig) - never run it inside the event loop + dSBoard = await hass.async_add_executor_job(dScriptBoardHA, entry.entry_id, tcp_ip, tcp_port, protocol, aeskey) entry_data=hass.data[DOMAIN][entry.entry_id] if not entry_data[KNOWN_DATA].get(dSBoard.MACAddress, None) is None and not entry_data[KNOWN_DATA][dSBoard.MACAddress].get(CONF_PYOJBECT, None) is None: _LOGGER.warning("%s - %s: async_setup_dScriptBoard: board already exists: %s", entry.entry_id, tcp_ip, dSBoard.name) @@ -102,7 +104,7 @@ async def async_dScript_ValidateBoardConfig(hass: HomeAssistant, entry: ConfigEn elif counts_pre[platform] > count_post: for identifier in list(range(int(count_post)+1,int(counts_pre[platform])+1)): uniqueid = create_entity_unique_id(dSBoard, identifier, platform) - entity_object = async_dScript_GetEntityByUniqueID(hass, entry.entry_id, uniqueid, dSBoard.MACAddress) + entity_object = await async_dScript_GetEntityByUniqueID(hass, entry.entry_id, uniqueid, dSBoard.MACAddress) if entity_object is None: _LOGGER.warning("%s - %s: async_dScript_ValidateBoardConfig: unable to find remove entity: %s", entry.entry_id, dSBoard.name, uniqueid) continue @@ -166,8 +168,10 @@ def __init__(self, entry_id: str, tcp_ip, tcp_port=DEFAULT_PORT, protocol=DEFAUL def check_available(self): + """Blocking availability check - only call from an executor thread""" try: _LOGGER.debug("%s - %s: dScriptBoardHA check_available: connect", self._HostName, self.IP) + self._SystemFirmwareMajor = 0 #reset to detect a board which is no longer reachable self.InitBoard() if self._SystemFirmwareMajor == 0: #no firmware data means not connected _LOGGER.error("%s - %s: dScriptBoardHA check_available: not connected", self._HostName, self.IP) @@ -177,7 +181,31 @@ def check_available(self): _LOGGER.error("%s - %s: dScriptBoardHA check_available: connect failed: %s (%s.%s)", self._HostName, self.IP, str(e), e.__class__.__module__, type(e).__name__) self.available = False return False + return self._check_available_post_process() + + async def async_check_available(self, full=True): + """Async availability check - full=False only checks GetStatus (lightweight, used for heartbeats)""" + try: + _LOGGER.debug("%s - %s: dScriptBoardHA async_check_available: connect (full: %s)", self._HostName, self.IP, full) + self._SystemFirmwareMajor = 0 #reset to detect a board which is no longer reachable + if full: + await self.async_InitBoard() + else: + await self.async_GetStatus() + if self._SystemFirmwareMajor == 0: #no firmware data means not connected + _LOGGER.error("%s - %s: dScriptBoardHA async_check_available: not connected", self._HostName, self.IP) + self.available = False + return False + except Exception as e: + _LOGGER.error("%s - %s: dScriptBoardHA async_check_available: connect failed: %s (%s.%s)", self._HostName, self.IP, str(e), e.__class__.__module__, type(e).__name__) + self.available = False + return False + return self._check_available_post_process() + + + def _check_available_post_process(self): + """Post-process board data after a successful connection""" try: _LOGGER.debug("%s - %s: dScriptBoardHA check_available: post-process", self._HostName, self.IP) self.MACAddress = str(self._MACAddress) @@ -191,6 +219,7 @@ def check_available(self): self._HostName, self._SystemFirmwareMajor, self._SystemFirmwareMinor, self._ApplicationFirmwareMajor, self._ApplicationFirmwareMinor, self._CustomFirmeware, self.MACAddress, self.IP, self._Protocol) self.available = True + return True def _cleanup_macaddress(self): diff --git a/custom_components/dscriptmodule/manifest.json b/custom_components/dscriptmodule/manifest.json index b9f3a2c..3096c61 100644 --- a/custom_components/dscriptmodule/manifest.json +++ b/custom_components/dscriptmodule/manifest.json @@ -1,10 +1,10 @@ { "domain": "dscriptmodule", "name": "robot-electronics dScript modules", - "version": "3.6.2", + "version": "3.7.0", "config_flow": "true", "documentation": "https://github.com/mk-maddin/dScriptModule-HA", - "requirements": ["dScriptModule>=3.4.0", "getmac>=0.9.2", "aiofiles>=23.2.1"], + "requirements": ["dScriptModule>=3.5.0", "getmac>=0.9.2", "aiofiles>=23.2.1"], "dependencies": ["light","cover","switch", "sensor", "binary_sensor"], "codeowners": ["@mk-maddin"], "iot_class": "local_push" diff --git a/custom_components/dscriptmodule/sensor_board.py b/custom_components/dscriptmodule/sensor_board.py index f207f0e..043f981 100644 --- a/custom_components/dscriptmodule/sensor_board.py +++ b/custom_components/dscriptmodule/sensor_board.py @@ -4,13 +4,13 @@ from typing import Final import logging import asyncio -import urllib.request -import socket +import aiohttp from homeassistant.core import HomeAssistant from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.const import ( ATTR_MODEL, ATTR_VOLTAGE, @@ -102,23 +102,26 @@ async def async_local_poll(self) -> None: """Async: Poll the latest status from device""" try: _LOGGER.debug("%s - %s.%s: async_local_poll", self._entry_id, self._board.name, self.uniqueid) - state = await self.hass.async_add_executor_job(urllib.request.urlopen,self._onlineurl) - state = state.getcode() + session = async_get_clientsession(self.hass) + async with session.get(self._onlineurl, timeout=aiohttp.ClientTimeout(total=10)) as response: # always closes the connection to the board + state = response.status + await response.read() if self._NoGetUpdateCounter >= 10: self._NoGetUpdateCounter = 0 await self._board.async_GetStatus() #await self.hass.async_add_executor_job(self._board.GetStatus) else: self._NoGetUpdateCounter += 1 - except urllib.error.URLError: state = 404 - except socket.timeout: state = 408 - except OSError: state = 113 - except urllib.error.HTTPError as e: state = e.code + except asyncio.TimeoutError: state = 408 + except aiohttp.ClientResponseError as e: state = e.status + except aiohttp.ClientConnectionError: state = 113 + except aiohttp.ClientError: state = 404 + except OSError: state = 113 except Exception as e: _LOGGER.error("%s - %s.%s: async_local_poll failed: %s (%s.%s)", self._entry_id, self._board.name, self.uniqueid, str(e), e.__class__.__module__, type(e).__name__) return None try: - if not state == 200 and self._board.available == True: self._board.check_available() - elif state == 200 and self._board.available == False: self._board.check_available() + if not state == 200 and self._board.available == True: await self._board.async_check_available() + elif state == 200 and self._board.available == False: await self._board.async_check_available() else: _LOGGER.debug("%s - %s: async_local_poll board available unchanged: %s", self._board.friendlyname, self._name, self._board.available) self._state = str(state) diff --git a/custom_components/dscriptmodule/server.py b/custom_components/dscriptmodule/server.py index 08d7d6b..09a6568 100644 --- a/custom_components/dscriptmodule/server.py +++ b/custom_components/dscriptmodule/server.py @@ -123,7 +123,7 @@ async def async_dSBoardHeartbeat(self, sender, event) -> None: self.hass.async_create_task(async_setup_dScriptBoard(self.hass, self._entry, sender.sender)) else: _LOGGER.debug("%s - async_dSBoardHearbeat: known board %s", sender.sender, dSBoard.friendlyname) - if not dSBoard.check_available() == True: + if not await dSBoard.async_check_available(full=False) == True: # GetStatus only - config is validated below _LOGGER.warning("%s - async_dSBoardHearbeat: board unavailable %s", sender.sender, dSBoard.friendlyname) if dSBoard._CustomFirmeware: self.hass.async_create_task(self.async_dSBoardGetConfig(sender, event)) From 35f0b22ff9c98600d0b797b8c81cc3df261847a6 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 14:23:39 +0000 Subject: [PATCH 2/9] Fix hassfest/HACS validation errors and options flow on current HA - manifest.json: config_flow must be a boolean, keys sorted as required by hassfest, add issue_tracker. - services.yaml: "dscription" typos made the file invalid; the entity selector of updatebutton had integration and domain swapped. - hacs.json: remove iot_class (not a hacs.json key, belongs to manifest). - Options flow: do not assign config_entry on HA versions that provide it as a property (raises AttributeError since HA 2025.12, the options dialog could not be opened). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- custom_components/dscriptmodule/config_flow.py | 3 ++- custom_components/dscriptmodule/manifest.json | 11 ++++++----- custom_components/dscriptmodule/services.yaml | 10 +++++----- hacs.json | 1 - 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/custom_components/dscriptmodule/config_flow.py b/custom_components/dscriptmodule/config_flow.py index 17f1fe8..4f300d6 100644 --- a/custom_components/dscriptmodule/config_flow.py +++ b/custom_components/dscriptmodule/config_flow.py @@ -79,7 +79,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow): def __init__(self, config_entry: config_entries.ConfigEntry) -> None: """Initialize options flow.""" _LOGGER.debug("%s - OptionsFlowHandler: __init__: %s", DOMAIN, config_entry) - self.config_entry = config_entry + if not isinstance(getattr(type(self), "config_entry", None), property): + self.config_entry = config_entry # only needed for HA < 2024.11 - newer versions provide config_entry themselves (setting it raises since 2025.12) async def async_step_init(self, user_input: Dict[str, Any] = None) -> Dict[str, Any]: """Manage the options for the custom component.""" diff --git a/custom_components/dscriptmodule/manifest.json b/custom_components/dscriptmodule/manifest.json index 3096c61..3e8c2c9 100644 --- a/custom_components/dscriptmodule/manifest.json +++ b/custom_components/dscriptmodule/manifest.json @@ -1,11 +1,12 @@ { "domain": "dscriptmodule", "name": "robot-electronics dScript modules", - "version": "3.7.0", - "config_flow": "true", + "codeowners": ["@mk-maddin"], + "config_flow": true, + "dependencies": ["light", "cover", "switch", "sensor", "binary_sensor"], "documentation": "https://github.com/mk-maddin/dScriptModule-HA", + "iot_class": "local_push", + "issue_tracker": "https://github.com/mk-maddin/dScriptModule-HA/issues", "requirements": ["dScriptModule>=3.5.0", "getmac>=0.9.2", "aiofiles>=23.2.1"], - "dependencies": ["light","cover","switch", "sensor", "binary_sensor"], - "codeowners": ["@mk-maddin"], - "iot_class": "local_push" + "version": "3.7.0" } diff --git a/custom_components/dscriptmodule/services.yaml b/custom_components/dscriptmodule/services.yaml index c8074c8..86a3b13 100644 --- a/custom_components/dscriptmodule/services.yaml +++ b/custom_components/dscriptmodule/services.yaml @@ -1,4 +1,4 @@ -# Describes the format for available HomeKit services +# Describes the format for available dscriptmodule services serverstop: name: Stop dScriptServer @@ -10,7 +10,7 @@ serverstart: updatebutton: name: Update dScriptButton - dscription: Trigger update of virtual Button entity from dScriptBoard + description: Trigger update of virtual Button entity from dScriptBoard fields: entity_id: name: Entity @@ -20,12 +20,12 @@ updatebutton: - sensor.ds_speis_button1 selector: entity: - integration: sensor - domain: dscriptmodule + integration: dscriptmodule + domain: sensor heartbeatknownboards: name: Hearbeat KnownBoards - dscription: Trigger heartbeat to each known/cached dScriptBoard + description: Trigger heartbeat to each known/cached dScriptBoard fields: entry_id: name: Config entry ID diff --git a/hacs.json b/hacs.json index ea5315b..97c7043 100644 --- a/hacs.json +++ b/hacs.json @@ -1,6 +1,5 @@ { "name": "Robot-Electronics dScript Modules", - "iot_class": "Local Push", "homeassistant": "2024.6.0", "hide_default_branch": false, "hacs": "1.34.0" From 169d3527e5aa5ab5ca2dae502bda6435f5e08a20 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 14:23:39 +0000 Subject: [PATCH 3/9] Add hassfest, HACS and pytest workflows with integration tests - validate.yml: hassfest and HACS action (brands check ignored until the integration is listed in home-assistant/brands). - tests.yml: pytest with pytest-homeassistant-custom-component. - Tests: config/options flow, setup/unload with the integrated dScriptServer, end-to-end with an emulated board (heartbeat creates entities, light control, push updates, no duplicate entities on repeated heartbeats, requests to a board are never parallel). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- .github/workflows/tests.yml | 22 ++++++ .github/workflows/validate.yml | 26 ++++++++ .gitignore | 3 + pytest.ini | 4 ++ requirements_test.txt | 4 ++ tests/__init__.py | 1 + tests/conftest.py | 78 ++++++++++++++++++++++ tests/test_config_flow.py | 41 ++++++++++++ tests/test_init.py | 118 +++++++++++++++++++++++++++++++++ 9 files changed, 297 insertions(+) create mode 100644 .github/workflows/tests.yml create mode 100644 .github/workflows/validate.yml create mode 100644 .gitignore create mode 100644 pytest.ini create mode 100644 requirements_test.txt create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_config_flow.py create mode 100644 tests/test_init.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..0dda533 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,22 @@ +name: Tests + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + pytest: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements_test.txt + - name: Run tests + run: pytest -v diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..4c63906 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,26 @@ +name: Validate + +on: + push: + pull_request: + schedule: + - cron: "0 3 * * 1" + workflow_dispatch: + +jobs: + hassfest: + name: Hassfest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: home-assistant/actions/hassfest@master + + hacs: + name: HACS + runs-on: ubuntu-latest + steps: + - uses: hacs/action@main + with: + category: integration + # the integration is not (yet) listed in https://github.com/home-assistant/brands + ignore: brands diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a160f49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +*.py[cod] +.pytest_cache/ diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..778f4ed --- /dev/null +++ b/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +testpaths = tests +asyncio_mode = auto +asyncio_default_fixture_loop_scope = function diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..f0ef3c8 --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,4 @@ +pytest-homeassistant-custom-component==0.13.316 # Home Assistant 2026.2.3 +dScriptModule>=3.5.0 +getmac>=0.9.2 +aiofiles>=23.2.1 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..362009b --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for the dscriptmodule integration.""" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..99cd604 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,78 @@ +"""Fixtures for dscriptmodule tests.""" +import asyncio +import socket + +import pytest + +from custom_components.dscriptmodule.const import DEFAULT_PORT + +BOARD_IP = "127.0.0.2" # boards and the integrated dScriptServer need different IPs (both use port 17123) +STATUS = bytes([34, 4, 13, 3, 8, 120, 1, 11]) # dS2824, FW 4.13, App 3.8 +CONFIG = bytes([0, 1, 2, 0xAB, 4, 5, 24, 2, 1, 1, 1, 1]) # 24 relays, 2 lights, 1 shutter, 1 socket, 1 motion, 1 button + + +@pytest.fixture(autouse=True) +def auto_enable_custom_integrations(enable_custom_integrations): + """Enable custom integrations in all tests.""" + yield + + +def free_port(ip="127.0.0.1"): + with socket.socket() as s: + s.bind((ip, 0)) + return s.getsockname()[1] + + +class FakeBoard: + """Emulates a dS2824 running dScriptRoomControl (one request per TCP connection).""" + + def __init__(self): + self.requests = [] + self.lights = {1: 0, 2: 0} + self.server = None + + def response(self, data): + cmd = data[0] + if cmd == 0x30: return STATUS + if cmd == 0x50: return CONFIG + if cmd == 0x40: + self.lights[data[1]] = data[2] + return bytes([0]) + if cmd == 0x51: return bytes([self.lights.get(data[1], 0)]) + if cmd == 0x52: return bytes([100, 0]) + if cmd == 0x53: return bytes([0]) + if cmd in (0x54, 0x55): return bytes([0]) + return bytes([0]) + + async def handle(self, reader, writer): + try: + data = await reader.read(100) + if data: + self.requests.append(bytes(data)) + writer.write(self.response(data)) + await writer.drain() + finally: + writer.close() + + async def start(self): + self.server = await asyncio.start_server(self.handle, BOARD_IP, DEFAULT_PORT) + return self + + async def stop(self): + self.server.close() + await self.server.wait_closed() + + async def trigger(self, server_port, payload): + """Send a status trigger to the integrated dScriptServer like the firmware does.""" + reader, writer = await asyncio.open_connection("127.0.0.1", server_port, local_addr=(BOARD_IP, 0)) + writer.write(payload) + await writer.drain() + await reader.read(10) + writer.close() + + +@pytest.fixture +async def fake_board(): + board = await FakeBoard().start() + yield board + await board.stop() diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py new file mode 100644 index 0000000..8a66b1d --- /dev/null +++ b/tests/test_config_flow.py @@ -0,0 +1,41 @@ +"""Tests for the config and options flow.""" +from homeassistant import config_entries +from homeassistant.const import CONF_FRIENDLY_NAME, CONF_PORT, CONF_PROTOCOL +from homeassistant.core import HomeAssistant +from homeassistant.data_entry_flow import FlowResultType +from pytest_homeassistant_custom_component.common import MockConfigEntry + +from custom_components.dscriptmodule.const import CONF_AESKEY, CONF_LISTENIP, DOMAIN + +USER_INPUT = { + CONF_FRIENDLY_NAME: "My dScript", + CONF_LISTENIP: "127.0.0.1", + CONF_PORT: 17999, + CONF_PROTOCOL: "binary", + CONF_AESKEY: "", +} + + +async def test_user_flow_creates_entry(hass: HomeAssistant) -> None: + result = await hass.config_entries.flow.async_init(DOMAIN, context={"source": config_entries.SOURCE_USER}) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "resource" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], USER_INPUT) + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "My dScript" + assert result["data"] == USER_INPUT + + +async def test_options_flow_updates_entry_data(hass: HomeAssistant) -> None: + entry = MockConfigEntry(domain=DOMAIN, data=USER_INPUT, source=config_entries.SOURCE_USER) + entry.add_to_hass(hass) + + result = await hass.config_entries.options.async_init(entry.entry_id) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "resource" + + new_input = {**USER_INPUT, CONF_PORT: 18000} + result = await hass.config_entries.options.async_configure(result["flow_id"], new_input) + assert result["type"] is FlowResultType.CREATE_ENTRY + assert entry.data[CONF_PORT] == 18000 diff --git a/tests/test_init.py b/tests/test_init.py new file mode 100644 index 0000000..d6db24a --- /dev/null +++ b/tests/test_init.py @@ -0,0 +1,118 @@ +"""End-to-end tests with an emulated board: setup, heartbeat, control, push updates, unload.""" +import asyncio + +import pytest +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import CONF_FRIENDLY_NAME, CONF_PORT, CONF_PROTOCOL, STATE_OFF, STATE_ON +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er +from pytest_homeassistant_custom_component.common import MockConfigEntry + +from custom_components.dscriptmodule.const import CONF_AESKEY, CONF_LISTENIP, CONF_SERVER, CONF_PYOJBECT, DOMAIN + +from .conftest import BOARD_IP, free_port + +pytestmark = pytest.mark.usefixtures("socket_enabled") + + +@pytest.fixture(autouse=True) +def allow_board_ip(socket_enabled): + """The emulated board listens on BOARD_IP - allow connections to it.""" + import pytest_socket + pytest_socket.socket_allow_hosts(["127.0.0.1", BOARD_IP], allow_unix_socket=True) + + +async def wait_for(predicate, timeout=15.0): + for _ in range(int(timeout / 0.1)): + if predicate(): + return True + await asyncio.sleep(0.1) + return predicate() + + +async def setup_entry(hass: HomeAssistant): + port = free_port() + entry = MockConfigEntry(domain=DOMAIN, title="test", data={ + CONF_FRIENDLY_NAME: "test", CONF_LISTENIP: "127.0.0.1", CONF_PORT: port, + CONF_PROTOCOL: "binary", CONF_AESKEY: ""}) + entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + return entry, port + + +def light_entity_ids(hass): + registry = er.async_get(hass) + return sorted(e.entity_id for e in registry.entities.values() if e.platform == DOMAIN and e.domain == "light") + + +async def test_setup_and_unload_without_boards(hass: HomeAssistant) -> None: + entry, port = await setup_entry(hass) + assert entry.state is ConfigEntryState.LOADED + server = hass.data[DOMAIN][entry.entry_id][CONF_SERVER][CONF_PYOJBECT] + assert server.dScriptServer.State is True + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + assert server.dScriptServer.State is False + + +async def test_heartbeat_creates_board_entities_and_controls_light(hass: HomeAssistant, fake_board) -> None: + entry, port = await setup_entry(hass) + + # a new board announces itself with a heartbeat trigger (cmd 0, state -1) + await fake_board.trigger(port, bytes([0, 0, 255])) + assert await wait_for(lambda: len(light_entity_ids(hass)) == 2), light_entity_ids(hass) + await hass.async_block_till_done() + light = light_entity_ids(hass)[0] + + # turning the light on sends SetLight (0x40) to the board + await hass.services.async_call("light", "turn_on", {"entity_id": light}, blocking=True) + assert any(r[0] == 0x40 and r[2] == 1 for r in fake_board.requests) + + # the firmware pushes the new state (GetLight trigger) - entity follows without polling + await fake_board.trigger(port, bytes([81, 1, 1])) + assert await wait_for(lambda: hass.states.get(light) is not None and hass.states.get(light).state == STATE_ON) + await fake_board.trigger(port, bytes([81, 1, 0])) + assert await wait_for(lambda: hass.states.get(light).state == STATE_OFF) + + # a second heartbeat of a known board must not create duplicates + await fake_board.trigger(port, bytes([0, 0, 255])) + await asyncio.sleep(0.5) + await hass.async_block_till_done() + assert len(light_entity_ids(hass)) == 2 + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + + +async def test_requests_to_board_are_never_parallel(hass: HomeAssistant, fake_board) -> None: + entry, port = await setup_entry(hass) + active = 0 + max_active = 0 + original = fake_board.handle + + async def counting_handle(reader, writer): + nonlocal active, max_active + active += 1 + max_active = max(max_active, active) + try: + await asyncio.sleep(0.02) + await original(reader, writer) + finally: + active -= 1 + + fake_board.handle = counting_handle + await fake_board.stop() + await fake_board.start() + + await fake_board.trigger(port, bytes([0, 0, 255])) + assert await wait_for(lambda: len(light_entity_ids(hass)) == 2) + await hass.async_block_till_done() + lights = light_entity_ids(hass) + max_active = 0 + await asyncio.gather(*[hass.services.async_call("light", "toggle", {"entity_id": lights}, blocking=True) for _ in range(5)]) + assert max_active == 1 + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() From cacde62eb873863054e093cd7b6d2870e4abe6d3 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 14:27:25 +0000 Subject: [PATCH 4/9] CI: use Node 24 versions of checkout and setup-python actions Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- .github/workflows/tests.yml | 4 ++-- .github/workflows/validate.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0dda533..78f0a40 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,8 +10,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: "3.13" - name: Install dependencies diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 4c63906..9d86a1d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -12,7 +12,7 @@ jobs: name: Hassfest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: home-assistant/actions/hassfest@master hacs: From c1d19a9f735ec55d2679fcb061376a3869635439 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 15:22:48 +0000 Subject: [PATCH 5/9] Fix logging calls with wrong argument count (broke board setup in CI) The debug message at the end of the availability check had 10 placeholders but 9 arguments. With debug logging enabled (as in the GitHub workflow) pytest raises on such formatting errors, so board setup and entry unload aborted; in production the log lines were lost. Same for the unload listener message and the heartbeat service messages. - pytest.ini: log_level = DEBUG so local runs behave like CI - tests/test_logging_calls.py checks all logging calls via AST Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- custom_components/dscriptmodule/__init__.py | 2 +- custom_components/dscriptmodule/board.py | 2 +- custom_components/dscriptmodule/services.py | 4 +-- pytest.ini | 1 + tests/test_logging_calls.py | 31 +++++++++++++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 tests/test_logging_calls.py diff --git a/custom_components/dscriptmodule/__init__.py b/custom_components/dscriptmodule/__init__.py index 65e6571..5cd93c5 100644 --- a/custom_components/dscriptmodule/__init__.py +++ b/custom_components/dscriptmodule/__init__.py @@ -141,7 +141,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.data[DOMAIN][entry.entry_id].pop(CONF_ADD_ENTITIES) if all_ok: - _LOGGER.debug("%s - async_unload_entry: Unload option updates listener: %s.%s ", entry.entry_id, FUNC_OPTION_UPDATES) + _LOGGER.debug("%s - async_unload_entry: Unload option updates listener: %s", entry.entry_id, FUNC_OPTION_UPDATES) hass.data[DOMAIN][entry.entry_id][FUNC_OPTION_UPDATES]() _LOGGER.debug("%s - async_unload_entry: Remove data store: %s.%s ", entry.entry_id, DOMAIN, entry.entry_id) hass.data[DOMAIN].pop(entry.entry_id) diff --git a/custom_components/dscriptmodule/board.py b/custom_components/dscriptmodule/board.py index 563ce96..4393fda 100644 --- a/custom_components/dscriptmodule/board.py +++ b/custom_components/dscriptmodule/board.py @@ -216,7 +216,7 @@ def _check_available_post_process(self): return False _LOGGER.debug("%s - %s: dScriptBoardHA check_available complete: FW: %s.%s | App: %s.%s | Custom: %s | MAC: %s | IP: %s | Prot: %s", - self._HostName, self._SystemFirmwareMajor, self._SystemFirmwareMinor, + self._HostName, self.IP, self._SystemFirmwareMajor, self._SystemFirmwareMinor, self._ApplicationFirmwareMajor, self._ApplicationFirmwareMinor, self._CustomFirmeware, self.MACAddress, self.IP, self._Protocol) self.available = True return True diff --git a/custom_components/dscriptmodule/services.py b/custom_components/dscriptmodule/services.py index dab428d..6d47059 100644 --- a/custom_components/dscriptmodule/services.py +++ b/custom_components/dscriptmodule/services.py @@ -97,12 +97,12 @@ async def async_service_HeartbeatKnownBoards(hass: HomeAssistant, call) -> None return False for board_entry in list(entry_data.get(KNOWN_DATA, [])): - _LOGGER.debug("%s - async_service_HeartbeatKnownBoards: processing board entry: %s ", call, DOMAIN, board_entry) + _LOGGER.debug("%s - %s: async_service_HeartbeatKnownBoards: processing board entry: %s", DOMAIN, call, board_entry) board_entry = entry_data[KNOWN_DATA][board_entry] ip_address = board_entry.get(CONF_IP_ADDRESS, None) if ip_address is None: continue - _LOGGER.debug("%s - async_service_HeartbeatKnownBoards: processing board entry: %s ", call, DOMAIN, ip_address) + _LOGGER.debug("%s - %s: async_service_HeartbeatKnownBoards: heartbeat board IP: %s", DOMAIN, call, ip_address) sender = DummySender(ip_address) await BuiltInServer.async_dSBoardHeartbeat(sender, 'service_heartbeat') #hass.async_create_task(async_setup_dScriptBoard(hass, entry, ip_address)) diff --git a/pytest.ini b/pytest.ini index 778f4ed..bfa884c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,4 @@ testpaths = tests asyncio_mode = auto asyncio_default_fixture_loop_scope = function +log_level = DEBUG diff --git a/tests/test_logging_calls.py b/tests/test_logging_calls.py new file mode 100644 index 0000000..622bf43 --- /dev/null +++ b/tests/test_logging_calls.py @@ -0,0 +1,31 @@ +"""Every logging call must have as many arguments as its format string has placeholders. + +A mismatch only shows up when the message is formatted (e.g. with debug logging enabled) - pytest then raises, +in production the log line is lost. This already broke board setup once (10 placeholders, 9 arguments). +""" +import ast +import os +import re + +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +LEVELS = {"debug", "info", "warning", "error", "exception", "critical"} +PLACEHOLDER = re.compile(r"%(?!%)[-#0 +]*\d*(?:\.\d+)?[sdifrx]") + + +def test_logging_placeholders_match_arguments(): + mismatches = [] + for base, _dirs, files in os.walk(os.path.join(ROOT, "custom_components")): + for name in files: + if not name.endswith(".py"): + continue + path = os.path.join(base, name) + with open(path, encoding="utf-8") as fh: + tree = ast.parse(fh.read(), path) + for node in ast.walk(tree): + if (isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr in LEVELS + and node.args and isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str)): + need = len(PLACEHOLDER.findall(node.args[0].value)) + have = len(node.args) - 1 + if need != have: + mismatches.append("%s:%s: %s placeholders, %s arguments" % (os.path.relpath(path, ROOT), node.lineno, need, have)) + assert mismatches == [] From 453e8c7ffc06f8741cdbffed4bf4b515da906bae Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 08:20:29 +0000 Subject: [PATCH 6/9] Version 3.8.0: status.htm polling and diagnostic sensors - The board sensor polls the small page status.htm (firmware >= 3.9) instead of index.htm. It carries temperature, voltage and load, so the extra GetStatus connection every 10th poll is no longer needed. Boards without the page (404) fall back to index.htm + GetStatus as before; status.htm is retried every 20 polls (firmware update). - New diagnostic sensors per board, disabled by default: temperature, voltage and load (dScript instructions/s, maximum of the last minute, attribute last_second). They are updated via a dispatcher signal of the board sensor (no own polling, no extra connection). The existing attributes of the board sensor are unchanged. - Tests for the status page and the fallback on older firmware. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- custom_components/dscriptmodule/board.py | 25 +++++ custom_components/dscriptmodule/const.py | 12 ++- custom_components/dscriptmodule/manifest.json | 2 +- .../dscriptmodule/sensor_board.py | 40 ++++++-- .../dscriptmodule/sensor_diagnostic.py | 95 +++++++++++++++++++ custom_components/dscriptmodule/utils.py | 6 +- tests/test_init.py | 68 +++++++++++++ 7 files changed, 236 insertions(+), 12 deletions(-) create mode 100644 custom_components/dscriptmodule/sensor_diagnostic.py diff --git a/custom_components/dscriptmodule/board.py b/custom_components/dscriptmodule/board.py index 4393fda..7a95a36 100644 --- a/custom_components/dscriptmodule/board.py +++ b/custom_components/dscriptmodule/board.py @@ -150,6 +150,9 @@ class dScriptBoardHA(dScriptBoard): friendlyname = None MACAddress = '00:00:00:00:00:00' _ConnectedBoardSensors = 1 #set this fixed to 1 as we have a single board status sensor implemented in HA + _InstrPerSec = None #dScript instructions per second (last second) - firmware >= 3.9 via status.htm only + _InstrPerSecMax = None #maximum of _InstrPerSec within the last minute + _StatusPageSupported = None #None = unknown, True = status.htm available (firmware >= 3.9), False = older firmware def __init__(self, entry_id: str, tcp_ip, tcp_port=DEFAULT_PORT, protocol=DEFAULT_PROTOCOL, aeskey=DEFAULT_AESKEY): """Initialize the object.""" @@ -222,6 +225,28 @@ def _check_available_post_process(self): return True + def update_from_status_page(self, text) -> bool: + """Take over the values of the board page status.htm (key=value lines, firmware >= 3.9)""" + try: + values = {} + for line in str(text).splitlines(): + key, sep, value = line.strip().partition('=') + if sep: + values[key.strip()] = value.strip() + temperature = int(values['temperature']) + voltage = int(values['voltage']) + instr = int(values['instr_per_sec']) + instr_max = int(values['instr_per_sec_max']) + except (KeyError, ValueError) as e: + _LOGGER.debug("%s - %s: dScriptBoardHA update_from_status_page: unexpected content: %s (%s.%s)", self._HostName, self.IP, str(e), e.__class__.__module__, type(e).__name__) + return False + self._Temperature = temperature / 10.0 + self._Volts = voltage / 10.0 + self._InstrPerSec = instr + self._InstrPerSecMax = instr_max + return True + + def _cleanup_macaddress(self): """Cleanup own MacAddress format""" try: diff --git a/custom_components/dscriptmodule/const.py b/custom_components/dscriptmodule/const.py index c4e4caa..339ca52 100644 --- a/custom_components/dscriptmodule/const.py +++ b/custom_components/dscriptmodule/const.py @@ -39,7 +39,10 @@ "getshutter": "cover", "getmotion": "sensor_motion", "getbutton": "sensor_button", - "getboard_dummy": "sensor_board" + "getboard_dummy": "sensor_board", + "getboardtemperature_dummy": "sensor_temperature", + "getboardvoltage_dummy": "sensor_voltage", + "getboardload_dummy": "sensor_load" } DSCRIPT_ENTITYTYPETOCOUNTATTR: Final = { @@ -49,5 +52,10 @@ "cover": "_ConnectedShutters", "sensor_motion": "_ConnectedMotionSensors", "sensor_button": "_ConnectedButtons", - "sensor_board": "_ConnectedBoardSensors" + "sensor_board": "_ConnectedBoardSensors", + "sensor_temperature": "_ConnectedBoardSensors", + "sensor_voltage": "_ConnectedBoardSensors", + "sensor_load": "_ConnectedBoardSensors" } + +SIGNAL_BOARD_STATUS: Final = DOMAIN + "_board_status_{}" # format with board MAC address - sent after new temperature / voltage / load values diff --git a/custom_components/dscriptmodule/manifest.json b/custom_components/dscriptmodule/manifest.json index 3e8c2c9..3803a25 100644 --- a/custom_components/dscriptmodule/manifest.json +++ b/custom_components/dscriptmodule/manifest.json @@ -8,5 +8,5 @@ "iot_class": "local_push", "issue_tracker": "https://github.com/mk-maddin/dScriptModule-HA/issues", "requirements": ["dScriptModule>=3.5.0", "getmac>=0.9.2", "aiofiles>=23.2.1"], - "version": "3.7.0" + "version": "3.8.0" } diff --git a/custom_components/dscriptmodule/sensor_board.py b/custom_components/dscriptmodule/sensor_board.py index 043f981..4387e70 100644 --- a/custom_components/dscriptmodule/sensor_board.py +++ b/custom_components/dscriptmodule/sensor_board.py @@ -11,6 +11,7 @@ from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.const import ( ATTR_MODEL, ATTR_VOLTAGE, @@ -31,6 +32,7 @@ CATTR_PROTOCOL, CATTR_SW_TYPE, DOMAIN, + SIGNAL_BOARD_STATUS, ) from .utils import( @@ -56,6 +58,9 @@ class dScriptBoardSensor(dScriptPlatformEntity): _onlineurl = STATE_UNKNOWN _configurl = STATE_UNKNOWN _NoGetUpdateCounter = 999 + _statusurl = STATE_UNKNOWN + _StatusPageRetryCounter = 0 + _StatusPageRetryPolls = 20 #polls until status.htm is tried again on a board without it (firmware update) def _init_platform_specific(self, **kwargs): """Platform specific init actions""" @@ -63,6 +68,7 @@ def _init_platform_specific(self, **kwargs): self._firmware = str(self._board._SystemFirmwareMajor) + "." + str(self._board._SystemFirmwareMinor) self._software = str(self._board._ApplicationFirmwareMajor) + "." + str(self._board._ApplicationFirmwareMinor) self._onlineurl= "http://" + self._board.IP + "/index.htm" + self._statusurl= "http://" + self._board.IP + "/status.htm" self._configurl= "http://" + self._board.IP + "/_config.htm" # def _state_post_process(self, state): @@ -103,14 +109,32 @@ async def async_local_poll(self) -> None: try: _LOGGER.debug("%s - %s.%s: async_local_poll", self._entry_id, self._board.name, self.uniqueid) session = async_get_clientsession(self.hass) - async with session.get(self._onlineurl, timeout=aiohttp.ClientTimeout(total=10)) as response: # always closes the connection to the board - state = response.status - await response.read() - if self._NoGetUpdateCounter >= 10: - self._NoGetUpdateCounter = 0 - await self._board.async_GetStatus() - #await self.hass.async_add_executor_job(self._board.GetStatus) - else: self._NoGetUpdateCounter += 1 + state = None + if self._board._StatusPageSupported is not False or self._StatusPageRetryCounter >= self._StatusPageRetryPolls: + # firmware >= 3.9: small page with temperature, voltage and load - no extra GetStatus connection needed + self._StatusPageRetryCounter = 0 + async with session.get(self._statusurl, timeout=aiohttp.ClientTimeout(total=10)) as response: # always closes the connection to the board + state = response.status + text = await response.text(errors='replace') + if state == 200: + self._board._StatusPageSupported = self._board.update_from_status_page(text) + elif state == 404: + _LOGGER.debug("%s - %s: async_local_poll: no status.htm (firmware < 3.9) - using index.htm", self._board.friendlyname, self._name) + self._board._StatusPageSupported = False + state = None + else: + self._StatusPageRetryCounter += 1 + if state is None: + async with session.get(self._onlineurl, timeout=aiohttp.ClientTimeout(total=10)) as response: # always closes the connection to the board + state = response.status + await response.read() + if not self._board._StatusPageSupported: + if self._NoGetUpdateCounter >= 10: + self._NoGetUpdateCounter = 0 + await self._board.async_GetStatus() + #await self.hass.async_add_executor_job(self._board.GetStatus) + else: self._NoGetUpdateCounter += 1 + async_dispatcher_send(self.hass, SIGNAL_BOARD_STATUS.format(self._board.MACAddress)) except asyncio.TimeoutError: state = 408 except aiohttp.ClientResponseError as e: state = e.status except aiohttp.ClientConnectionError: state = 113 diff --git a/custom_components/dscriptmodule/sensor_diagnostic.py b/custom_components/dscriptmodule/sensor_diagnostic.py new file mode 100644 index 0000000..a453f8a --- /dev/null +++ b/custom_components/dscriptmodule/sensor_diagnostic.py @@ -0,0 +1,95 @@ +"""Diagnostic sensors of a dScriptBoard: temperature, voltage and load (disabled by default).""" + +from __future__ import annotations +from typing import Final +import logging + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorStateClass, +) +from homeassistant.const import ( + UnitOfElectricPotential, + UnitOfTemperature, +) +from homeassistant.core import callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity import EntityCategory + +from .entities import dScriptPlatformEntity +from .const import SIGNAL_BOARD_STATUS + +_LOGGER: Final = logging.getLogger(__name__) +PLATFORM = 'sensor' + + +class dScriptBoardDiagnosticSensor(SensorEntity, dScriptPlatformEntity): + """Base class: shows a value of the board object, updated when the board sensor signals new values.""" + + _platform = PLATFORM + _board_attr = None + _attr_entity_category = EntityCategory.DIAGNOSTIC + _attr_entity_registry_enabled_default = False + _attr_state_class = SensorStateClass.MEASUREMENT + + @property + def should_poll(self) -> bool: + """No polling - the board sensor reads the values and signals updates.""" + return False + + @property + def native_value(self): + """Return the current value of the board.""" + return getattr(self._board, self._board_attr, None) + + @property + def available(self) -> bool: + """Available while the board is reachable and provides the value.""" + return bool(self._board.available) and self.native_value is not None + + async def async_added_to_hass(self) -> None: + """Subscribe to new board values.""" + self.async_on_remove(async_dispatcher_connect(self.hass, SIGNAL_BOARD_STATUS.format(self._board.MACAddress), self._async_board_status_updated)) + + @callback + def _async_board_status_updated(self) -> None: + """Write the new board values.""" + self.async_write_ha_state() + + async def async_local_poll(self) -> None: + """Async: values are read by the board sensor - just write the current state""" + self.async_write_ha_state() + + async def async_local_push(self, state=None) -> None: + """Async: values are read by the board sensor - just write the current state""" + self.async_write_ha_state() + + +class dScriptTemperatureSensor(dScriptBoardDiagnosticSensor): + """Internal board temperature.""" + + _board_attr = '_Temperature' + _attr_device_class = SensorDeviceClass.TEMPERATURE + _attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS + + +class dScriptVoltageSensor(dScriptBoardDiagnosticSensor): + """Supplied voltage of the board.""" + + _board_attr = '_Volts' + _attr_device_class = SensorDeviceClass.VOLTAGE + _attr_native_unit_of_measurement = UnitOfElectricPotential.VOLT + + +class dScriptLoadSensor(dScriptBoardDiagnosticSensor): + """dScript instructions per second - maximum of the last minute (firmware >= 3.9).""" + + _board_attr = '_InstrPerSecMax' + _icon = 'mdi:speedometer' + _attr_native_unit_of_measurement = 'instr/s' + + @property + def extra_state_attributes(self): + """Value of the last second in addition to the maximum of the last minute.""" + return {'last_second': self._board._InstrPerSec} diff --git a/custom_components/dscriptmodule/utils.py b/custom_components/dscriptmodule/utils.py index 4c4a5bc..f635fdc 100644 --- a/custom_components/dscriptmodule/utils.py +++ b/custom_components/dscriptmodule/utils.py @@ -155,6 +155,7 @@ async def async_dScript_setup_entry(hass: HomeAssistant, entry: ConfigEntry, asy from .sensor_board import dScriptBoardSensor from .sensor_button import dScriptButtonSensor from .sensor_motion import dScriptMotionSensor + from .sensor_diagnostic import dScriptLoadSensor, dScriptTemperatureSensor, dScriptVoltageSensor DSCRIPT_ENTITYTYPETOOBJECT: Final = { "light": dScriptLight, @@ -163,7 +164,10 @@ async def async_dScript_setup_entry(hass: HomeAssistant, entry: ConfigEntry, asy "cover": dScriptCover, "sensor_motion": dScriptMotionSensor, "sensor_button": dScriptButtonSensor, - "sensor_board": dScriptBoardSensor + "sensor_board": dScriptBoardSensor, + "sensor_temperature": dScriptTemperatureSensor, + "sensor_voltage": dScriptVoltageSensor, + "sensor_load": dScriptLoadSensor } try: diff --git a/tests/test_init.py b/tests/test_init.py index d6db24a..1191f14 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -116,3 +116,71 @@ async def counting_handle(reader, writer): assert await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done() + + +MAC = "00:01:02:ab:04:05" +STATUS_PAGE = "app=3.9\ntemperature=267\nvoltage=121\ninstr_per_sec=1200\ninstr_per_sec_max=1500\n" + + +def board_entity(hass, entry, dSEntityType): + devices = hass.data[DOMAIN][entry.entry_id]["devices"] + return devices.get(MAC, {}).get("dscriptmodule_" + MAC.replace(":", "") + "_" + dSEntityType + "1") + + +async def test_status_page_feeds_diagnostic_sensors(hass: HomeAssistant, fake_board, aioclient_mock) -> None: + aioclient_mock.get("http://" + BOARD_IP + "/status.htm", text=STATUS_PAGE) + registry = er.async_get(hass) + entry, port = await setup_entry(hass) + # diagnostic sensors are disabled by default - enable temperature and load before they are created + for sensor in ("sensor_temperature", "sensor_load"): + registry.async_get_or_create("sensor", DOMAIN, "dscriptmodule_" + MAC.replace(":", "") + "_" + sensor + "1", config_entry=entry) + + await fake_board.trigger(port, bytes([0, 0, 255])) + assert await wait_for(lambda: board_entity(hass, entry, "sensor_board") is not None) + await hass.async_block_till_done() + + requests_before = len(fake_board.requests) + await board_entity(hass, entry, "sensor_board").async_local_poll() + await hass.async_block_till_done() + + temperature = board_entity(hass, entry, "sensor_temperature").entity_id + load = board_entity(hass, entry, "sensor_load").entity_id + assert hass.states.get(temperature).state == "26.7" + assert hass.states.get(load).state == "1500" + assert hass.states.get(load).attributes["last_second"] == 1200 + assert board_entity(hass, entry, "sensor_board")._board._StatusPageSupported is True + assert len(fake_board.requests) == requests_before, "status.htm replaces the extra GetStatus connection" + + voltage = registry.async_get_entity_id("sensor", DOMAIN, "dscriptmodule_" + MAC.replace(":", "") + "_sensor_voltage1") + voltage_entry = registry.async_get(voltage) + assert voltage_entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION + assert voltage_entry.entity_category == "diagnostic" + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + + +async def test_older_firmware_without_status_page(hass: HomeAssistant, fake_board, aioclient_mock) -> None: + aioclient_mock.get("http://" + BOARD_IP + "/status.htm", status=404) + aioclient_mock.get("http://" + BOARD_IP + "/index.htm", text="") + entry, port = await setup_entry(hass) + await fake_board.trigger(port, bytes([0, 0, 255])) + assert await wait_for(lambda: board_entity(hass, entry, "sensor_board") is not None) + await hass.async_block_till_done() + + board_sensor = board_entity(hass, entry, "sensor_board") + requests_before = len(fake_board.requests) + await board_sensor.async_local_poll() + await hass.async_block_till_done() + + assert board_sensor._board._StatusPageSupported is False + assert hass.states.get(board_sensor.entity_id).state == "200" + assert any(r[0] == 0x30 for r in fake_board.requests[requests_before:]), "temperature/voltage still come from GetStatus" + assert board_sensor._board._InstrPerSecMax is None + + calls = aioclient_mock.call_count + await board_sensor.async_local_poll() # status.htm is not requested again on every poll + assert aioclient_mock.call_count == calls + 1 + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() From a3c5fc6ce14ad6c76124055d7b4795f2ae8e515a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 09:25:28 +0000 Subject: [PATCH 7/9] Stop tracking compiled __pycache__ files 17 .pyc files were committed although .gitignore excludes __pycache__/; they changed with every local Python run. Files stay on disk. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- .../__pycache__/__init__.cpython-311.pyc | Bin 12242 -> 0 bytes .../__pycache__/board.cpython-311.pyc | Bin 19989 -> 0 bytes .../__pycache__/config_flow.cpython-311.pyc | Bin 10460 -> 0 bytes .../configuration_schema.cpython-311.pyc | Bin 3920 -> 0 bytes .../__pycache__/const.cpython-311.pyc | Bin 2386 -> 0 bytes .../__pycache__/cover.cpython-311.pyc | Bin 12138 -> 0 bytes .../__pycache__/diagnostics.cpython-311.pyc | Bin 4261 -> 0 bytes .../__pycache__/entities.cpython-311.pyc | Bin 11542 -> 0 bytes .../__pycache__/light.cpython-311.pyc | Bin 6257 -> 0 bytes .../__pycache__/sensor.cpython-311.pyc | Bin 1617 -> 0 bytes .../__pycache__/sensor_board.cpython-311.pyc | Bin 8850 -> 0 bytes .../__pycache__/sensor_button.cpython-311.pyc | Bin 4969 -> 0 bytes .../__pycache__/sensor_motion.cpython-311.pyc | Bin 3933 -> 0 bytes .../__pycache__/server.cpython-311.pyc | Bin 17526 -> 0 bytes .../__pycache__/services.cpython-311.pyc | Bin 8014 -> 0 bytes .../__pycache__/switch.cpython-311.pyc | Bin 6468 -> 0 bytes .../__pycache__/utils.cpython-311.pyc | Bin 15023 -> 0 bytes 17 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/config_flow.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/cover.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/sensor.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/sensor_motion.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/server.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/services.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc delete mode 100644 custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc diff --git a/custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 480b3ae77ca28280233e9cf30c5989aeb72eca79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12242 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 WSZ~n10?tHD#yEB0VB8@iv;V)H-LPT+ diff --git a/custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/board.cpython-311.pyc deleted file mode 100644 index 99e17fb79d6cb02f1d0d447e8cee78cbd494917f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19989 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 diff --git a/custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/configuration_schema.cpython-311.pyc deleted file mode 100644 index 8e1e2bfc1a2eea6a7bc1bb049f16abaf7cf68157..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3920 zcmcguO>Emn79LWREX$Pq6aW7tOzgCF>{Xp?-8OETMzQ5YsB9UQ?TuM)8Cs+jsifo` zQc060O@IbHEDCII?O_-2DNWHFa_Aw4^wOe5F9pbeLJR@{0_-k!dvlQ%D0RY}5R|X}^>y|ieuVx`1h<4r9qQ3Gh0w=n2}y`Y5+%_J zrP4f2k-kUqs0`0IeMa%}UKnE(AMbOX4ZI(oUZqhD@Bs(oQ<_wkXVoAdR6~5IY}c%| zq+mX^m2ZQQ2Fb7NQQP@;wS(_aJNZtvi|nO*d$;g@38YZP_8WzXRPV z_dEkSDEB=9eQ=k#LvsI4w6pqiE?#c0e@93Ad_~(Kcki^XeUps0-kKkFc8DcABn7V{ zeneuDXe4xLcq*S;&!h`j)HC@UmrR|LRZ-*C^O%#8DV*8RXY*1)k;6ZbrAH{cNzCQ) zx`Wn0^v+~*qA~})P|BG}kaIfD$l8d)tUKbkQ;{5xDrk3Q+c%we08XdNR1ys${Ycev2;o0oq3gI-^KGj*$y>`c{pG6WGF`vo zWjb4li0pui(_eFYuwOeYvin@!4PfNw6;=X=Pq-R{QuGSE%N6=PI$3^Rpe~?yJS*q| zHR8MUT12~;OHFcE)(beti8)Sl5;d1!%gQO8yO7b(aj62vkbJrGqEe7G4zhSTNnIK} zsByo80hmKb%es)5UyLQ@lERa67w!PBFgYIQF1`K?c9Yz?m{DYDk^`gRgIf5YHZrmw zlbEu-lDt+(<2|JBIiFW-U+J8&{R{G+3K=X**yrfLIZU#TO{dP=J`E0%TpE+~g$biD z32sdCsm*NUv5w&~gD{CGn~vo$2`Ag1*dPa)sNg1|B-b0e!Flsc-u7yWEN|G2(RWg^ z1GBv{#(8XeU@5y%5K@Y$X@Xz}1VMF~#F(H`aXRYzG1}mDZXt823C0i+_1njvPzdv^D z-q^7(SH5S>u_bG4$zYdFcG+T=i)VQ2jPUq`^JmR*(Ha*GcFknhEOxCZr7bC2eEU69 zx@t*ROBQ`MmHXl2_rk}&eE0h~GyJ9%e$!xAO?K5{SBr0*wcbi^H~A(5KO)}?O+S&w z@DKeQLd~5Ys-Hy6&|WLF*YH1~ZZ(e@{?T6^G_`Ld+B;NjD%ZfPVJ*?a27!VsRo1;WM> z+X%(%=j$=&WMxCf8o|QVQGk4t0TKY~?1r++ZhcIL$?e_tmgXl^EfLfqcaVsLswJ9} z4B*h*;dUu)G(u{K!^;6*M~T|WE6svXa~p*n=_4wVpfTB2%#mh4X~+TUFc%a4e1;xD zi!eE4e)S(KQT;eR0V27JX&sRMwmlR@ZK1H?)Q9MRQD3)Ew^3iWQ0SWTtLaoR57Dqu zU$<$7f-rfOCV;331HJgfy3I6^>HhysFKQe7sLN_Su=$GFI%c(wU28DVSgD$5?BU+w zPf~x)ZZR#_rmn}0*1?;r1~X|glNK|1=j7d3S@F?;G5m_b95tDv7IXB@k-JA-MbBp3 zU=EwiVT(C@`^XnByW{l+FWve5-It7$OXjP~)~m}drf)N6FcT&-VKEc8@fQ~%Ya9Za h`u2GsYwYtF2=aiB@>Cnpf!NYQL2h`w!LLJj{0F(CY(M}2 diff --git a/custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/const.cpython-311.pyc deleted file mode 100644 index af06d225f1dfe0d56a6233167526b8b7711fd424..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2386 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 diff --git a/custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/diagnostics.cpython-311.pyc deleted file mode 100644 index caa4b65e7bb1302eedc61d827f6455395a76546c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4261 zcmdTHU2NON`FNxx%Can5PVF>_9omVVDsjAJU4|mdlBx1fyu`{D$HA)9*L84h$zrs9z6DmI=%S0v_A~P~A zG8)ZL2J38*)wm4j)wyCo3ub~^C=>GNK#|Yzpc5#DGhx8NVviQdL_Arj*sDb|QLoMy z`?Odl2KBJqQ|#9UG6PVL$h~=*i8t^dB?@0S&@@eXYMUYC0sQ@v8Iq&Qu-tbZNI8}{ zC=bg+Kjbn`%Yh}5IJo|m8CA;ZhGnZ+OR&nNl407ys$mLtUJ>M_tf`jlMMEwZ6+zW) zC1*;uYUtA+VCMp}pt5y~(T% zE3;WPn0pwLePtUs4_aKiw^b$E;Q51=_bRhV_3s`dcHgeXabmu-$#z5lL%FZWTsNET z!CmDIwsUQ6umx|Ap+*5C?-l#$W{r@&Eeg@5Y&!_H!{09q*`Qha0+9oo?5pfj1K(zD zlULXm$Zh5`#XZ=~hrMy{h&m~>;$@FE?IC2>30v6Zc1C=I$|2mB|8dm$ZWjL^MLpcj zhka2$wi`#eXU|Haas(r3x9jxo(~0iW>D#9h`&={9-_4uGiKZ z;b4MnXp*W6cvivj15ori>*>$Y)5n;$zWk*9mDcRMp$nRSZr|)U##e;K8SO?p`0jxY zQuG_Uyrded5G>1$HET^#5GGucvToGJ4fcBezhdpj#3d0oG4r|sS-DltxqNeZy1c*q zRN2JS(G5u!EXAztMz77zBvaSL)YbId!n_-veI=`u@Hzvx1k*H3mxVil8y3ZE5$+G7 z==O*Wr=ZT+YbC|yMNyYD1!q!&u0}0OT2V@SQ5{J9NWfTh~ z0u;Q4w60#$r8Rf_)3=d14ULb$-+C4<6@Q1{7Wpd|`O)I{7oGUCzy9_c<+om~aOoMMt-)`o_Nqxx>uUe-IMBME~i*x(91xiASf-zp?zgl{Z&@ zBfcg6NvoWCv3lx7=jcm!xx3tlJCOr*LIZ7}(KR$5PEmlf^c&dYEM1~7$}(L+B+^?b z%TgJ~6sdwLh=7@+d8BgG^wB0ZxIbOF6W1kB6y3R0Kp4IfF^AWL&7 z%TpB_WN86qEo6CY%^e3+b(%Zjv*%D#%{301ko+H0M*OMA&-{z8osS)`c;yuI(eKFm0hco|L{f@cey6hd31(^2!W|$}+H^ zJ{|CciEZ`auSPty)mI1JX@^X;e>L)Dr}L|k=bg^4&QTn*8{kR&&}+{*{S#Z!+R*4d x-g)YzL*nlbjQ@1FIxv3kxyry)bzo{M)Ec%zrfT7#ExyhjV*2Z(3o!AT`fn!C4SfIr diff --git a/custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/entities.cpython-311.pyc deleted file mode 100644 index f3cde8e28029740d316646b4076ce551fae0bc12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11542 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 diff --git a/custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/light.cpython-311.pyc deleted file mode 100644 index 3280b07b937af80acb1208b3c7f45d6843eb16c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6257 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 diff --git a/custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/sensor_board.cpython-311.pyc deleted file mode 100644 index ca8e8d19dfbe55ea1e1df848611b8c1045038492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8850 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 Xf*9v2+WetM`oFiTe|P~G*}?w}L`G}J diff --git a/custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/sensor_button.cpython-311.pyc deleted file mode 100644 index d9ffd9aa2bb2b9fccee449e8ed287eabdc581a22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4969 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 N4(%jyPx0vZ{R>7DX6^t0 diff --git a/custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/switch.cpython-311.pyc deleted file mode 100644 index 787c25f9a55a49494111b2797e70e17c99a5088d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6468 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 IDD3?H1=WW12LJ#7 diff --git a/custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc b/custom_components/dscriptmodule/__pycache__/utils.cpython-311.pyc deleted file mode 100644 index 60d61826d4a42a5c9d7187e0b2c390fab886f689..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15023 zcmdTrTWlLwcEjOoNQxpQ>OoPqOv#dC$+oN{e#LQY>p{t~t%vn;ti)z04kc0MLmrMS ziy7KZHrT2Q1FHrB>;~CJA9d=jH)uXutUtO%n#ZnNB*0KRf>{Cv3>4dTf&I{88z7th z^qf1K;ZULydAIw~;qc6z`#kq`UiZx3*zHydu225+)0yEGiu!kaQ7*k4(EX0qQPgc} zlwzrIiq)}nL>HyUAriv+h(2l$;iMXN_;}y}$@yck`cvZA|ygKS0 zck3vc3Rz}q6m&zL4*<{m@RzUgTGk%g#+Dv~SGI*Md&@Aso!!IkWh>q?j@OY;C4_cB zXdhb#Aurp??q_#GsGc=VQB%~Uo^4~B;k|)14O7j}ChOQlkPFZ9(KtI733;bOk=YRE zot%pW`EWdz_%$}%tjpR0u~?iBkT`gCOoe!VG!XO$Se6SV5)ftV4#xr!2-w5X**FKu zq{e=XITeqF+7pRzf)B)ah_H3WW0T=2UySD#;MLX6vJejQ;ZUM85Q$6#f|nt>q;sIZ z+u!9I>+SRn{~8CO*_bUOk?mbweqaAc??|t2IBO?SgBJ!)clbI-vZk(qzV_b!?DnqV z&Y|AH5jo?9kqd*qk%7*E(f*P4k&&TnjgmYvFxcBUGC-;$xi}*$NP^9tVncq|lDX9RNMYJ+v9`&}2r-li-RuSpfCpXdtbFs0*ZD3QCCHDM(V z=9cD7`8Rz&@*Nwbw+K8cPVicwZ6m**@>9`0knNzZC^)SpjbnSzD{tLL-V?M>YDxn zHLq(nB@e;+^1}M^=GK>YGR{T4y@TF;-uVC*m?dj8&Upigg;>xVx)ut~;nIXfLx*RR zyP6V^aorO2Pjd07KRkQXi>b!}Cd=B|juzhi$+mAVI~fQ^LM*9ccT=LZDbd_)<8WTM zG5}d48=9D#;z}`W@m&jsW)ZEdF~o6kE~|$Xl(qQ%!AKyH@cXk?e{PdN*uXE$hO&&` z9}7f7et)x`tHet5FbG*)D1n5_>-B!aKtCgi*4c$@^(Ot}>LDxs6B2-%)S7`YcG15o z-M(BdmNuqK8>Q05Mg3#O@k9F$>|)jN&rJ{Mhn;C=P+|r}W-wzb70a7eY)zuADdVbM zI*@UcFIvBTY^zwKbWo8Ns+FAja@Xq6s5o{$J@m3P^s+eqiZmXQ#%EW#tK$5%G`Ape z3;zum={o7(Qk12Oh8KWqTZUi5wWi1RA&~Gu$KE`0occ%Iaq6F}9Xs^@%(Rzuc=Vrm zjPTN(HIO~3-C4K}zlVFY4r0$xI(eT$q;f55_N)>I`%uTLdk$7N^#M%7eVht%=_p>^ z4LQ<_1$tRigHjTAc;VjS^nxy-yXE0+`8=@i=??(k`)W_PHa?$BZGyAD z0B5>jM{lTcJze1)`3CZPoHZ0;`#p*^zOEmmZtK4feDc;DYb4aCJYSYjAAJF~DlN$8 zf^jfuvE{4tX@b76O+i0XqNL8KREpoO#K8=#D>0+?r3m#gru5hKh&M|@8tP+CKHH9D z<)~LC{9fQl-T=>Y;fXmul<>wUy#a4xHWUm`hJ)Vt#7rp2CwCCCLCBGRkc&@ofoL=w zo9aSxfYc(Z^Cug>Bainb$jISj_b2y%Yu+MM$VmtgR|TbI@}p~^HDRHMO z?P!o34H!ACd+e;fZGYP?)^&Y8`H)>5c}0BHF9t&Ckx6M}GVPp_oKvE6>T!9^JNuS( z>GB4tyg@7}ey`aSJih*_ges|AqiCZ&57ch-d|9=6ZbTd%OP@P0ojWgH7?&=v(uMfy zl{xY1eEP~Y>B==AgPg8|(8Nwc6FUh_?4&bH$)Z8|5#ncrR*?4L%)Hgn)Uk*9WRJD0 zME}Xb_L45M{xh=?UV^~fO@O+v%Au%UJ=7fg67%UUIH45QVQ<#Z7g+YPJ@a2>^c0qi_pYDH6>VGZm z3`ov^=nQu^w?IINv*`cG=wOFH-HKiy-5m#hIeLV`mX1|(F}#W-B&MDQdW zAZuU)d?0I>h{q#Ar0&XvOPGjLKL=q*5vK%dMoFi%YDa#R3%VJVK;>go2CV|JiMXWG zmIbj0+SLkTe`wphx-BUxj}eG&f1Wb_-`2UTQRviRq6A~1kdrbArs6qy4S@pT5ymku z7N*RC`KIpHD}p&MvI(@T9)eIgCFnVWUsWW^5By-6xPh6kd?axrf@|F%#1qod4ZO%SMmevSXW{OHBoYX0Bi2P zy6%Y5O{bXa3}VibkVfn^CZErVy+fg3D10^KWrvAn$U6}aaBNP{^`aJyig->jPae?- zs<{IGo)F)GWjYpm2akFap#T@024UDcv4AB(l}CxVKY8doiw23+$vYX2u`(7|FxmB; z<+_QM?&agT#<5K(S)jI;a|d9MWLcRZ)XyJgHB1UALsk!>GKZ`rsdwjpB$HJj{fYJR0C4C*>Z${#omm2+k2L~yCiq> zy{4bEO70hawpViZJaV5|ai4kEn|6;$?yco8#!ITu7yECr3+b7;WardQ<8q==BlIyTolDnUH z>K=Ixu6Pcv9_o9@r9DHEXGpAAe=k}x4!7v=W;~5|UzI%1J@On{@f`YS;p4`%r$_Si z0D7)E(Y5Q|0RVEtnM$u%xf{Z_Z@hiuZt5d8UHzg|{i5i65jeQTDce!{#lcZ&@RIo2 zM4AaoOi*Nkfc_${SWc#iM;b z1~+u4Q7O2g8>PRZsPptIs2sdXUqpT3Jbek%)W;M?+NUuNAmrO3B)SC{R;Gzz1()Yr zo#npc)Thsh9X(NnU_=Qd%PuoJ@kLIKZIwnXwJ!oH9j zZJ^mcQmkWPlx&~gE-mv^*=EPnl-F`l87aa-eNR(|%)q@HwYp}zhF_wTBC}NFoZJxv z->uInJn&&rSU$dWDqFM_m7v>&<8 z1^P8iQy*bs*P6jN%M9iNNLb<`FaH#~Rt4I%(1Q3@r@nJP^(nIp;eM;HO#kT%?RH;@ z{__$eykyJeX(sYl?zr%q?J84g-*||4F>7asEB~+8Qwe*aW>j5Tn>Wv7wAw*Fc5?#GtK^HK!c?Jd2uFqbDN5D_ zIahJ>{s++Q`|y{qlwL5XCEgTF+S>EjkmC(AY7qqofa{o!RyUjjBhS{DNb#{0%v9F7yspHIdhk+|eOazs$Uz64f>2)LE5IL! z;>L?LX;-2a{|)Qf%rfZGkg|e%gPFBNz^x%=BVlUVqt{(QCrgcs2 zMb~=~J4v}vese4P&AHjwfo*D?_;%~B1Opkr-6>{E^HR2H-OP+v8Cz%vXt35ffbUe& zC~Brb3A5#e`$TJ7f>l(Wa=|FLa+IzTgutCj$wVoCN(sZRtjLdMsv>6BrU^!E8h<8V zN??SFLdu%hU$8QZQ-I2?jR4fW&Q^2l?*$j%SJ*y`04OtgyXR$+%>71ivF0RDvy`g< zqvCtIYKs`T)?-9df>S#_=#~Pb0;66yf2m4-K!Z2r%F}b9at00kFlVO*^x1 zJimoLRcqVO(kW=etF)nQyAWfb@jn$RH{*0#JoBqVTN}!zLfLYQ(vtQmR2HsU*!5eS z*N=X)q`URg4V-6kOPt5Or4cdy$@mZ`&-YaYI%jzV?xUk%r{baeI$k7{aW+_AEnl5$OmKoP~VJNd#^>XID|yyXO6(lZ z$736!`{L-}m5VlIjS;LoYeJ8U;B?j)#JaQg1gQ<2y@)rM@(S)GP-V6xmr6!B`QlbO zo}Wf_QQ$}>&upb|f81L{RU)fRsf|qMW_F5#1qBVlJDJhBSunACl`4oI3pWCD0o^B~ z0iJC<94jRIwt^(&3CFGmB4Jjo(TnR|al=6j!5I@y1CDR8It`j+hb=&1@ZU?G*kXCL z5cmUep#Zx8Zild86Uo6XR-i!uN+{!0Wc4S{ZKcLd)&P!65lhV;jiu%=ObR*o$elj` zVr*zKFc;xDV!A=?BWr@epM%|mL|1kPA{HHT7NQ3YTw~kG`w5|o5SeohB^PcOK|g{~ z1Sl17FC!R4a2~-q1Y-z>5TGKPHJ}S5hq3{OEH&%&cg`jFc(gmrMML2J8RAgZ(zp$v zZHE|-vev%#PFURNlAJZ6n`n$}uF{;k^kB|j1Sr~N8D$oT!AUkWq0~(bO>!Ry`UG== zG{F~9&3Y97;k@JU$iP6yX>>t0lf?q|hFYZo|3=eA)*5Cp-((m_gmISmQTd?e1fD47 z4tLf)Ljnj3*D~ zGBT+EVUhrX|KO9_U29a0z5cfdmdtCkyR2Sar1=E{`2|>~WSN}8(x>Smtgvzz;{ZYw zz{j5Y_x9b>r9CZ@r$wwNa%burmQFvZ-m!dSrFxH8z2~DI>A+cdu8t+3iaEd*>N~IV z(GNopLyx^LJ(!lfJ$ITO*ETF4zUNEVJ}1>a2Zr3r`p51a@7v$Ci@WB;c>&5?({D2I31Oy!CowziBDlg?Q|d3GypBa;{xmrY=b3ju%r!^ep2rf z>tB3uN~-sL%s%vq!{g$sP}gj_{)$w8<&NobQ}@UG!_hA;i5G*?#fTW2gNoxivORZ^ z-3btC_ihEArhm0<=lgx{_K7V;)x>iZmHWeGh-+%p873Hpn zIV;lub&2uf)z<-qd6;pSy&h#O#}Kap`4spf9m2FJni$qE(}dhi!CXQXd;q#}dKTZ} zbW(o!^jMkxj2_a?>ihICBR%?lJ!DZI=P|PKWsCy|`2c2Wy>||3e>uWcRu2In7|v=u zqCc1+JM>;p+Ic{79uS=ee!n)V0~$c6!Pj4n>2j`a#b|I?ygVyiUI6q|dV3ao*H06Y zKSU4X^695Xup{^Y%*N!!JVpmFatsCl3dCp*(-QF23lxaabC{++u4AO-2F3w|d;m8k z$%zPX(YLyET_)-?lhwCR|CzJB+_zi*`EDb;{KC*_8#Yt_>g?EmPH*_)gbrT5q`GwQ zlGf4ilGa;?o;RoM?KMNK=9OJ0h+1hiLe$Fhq0K@*S|cHHzSfDEONv(8 zgV|3ZAac@a456^Zkr2U=Ahi>|kn*$fp!^-n1>dc3V4wow5wtw;VId#JWKHm8 z3ut`uS5+2SXN!agdFSsv&K8vz1YHS!rIh6SQ$Z|4~H=USn zfu5ZOl;MLOBJ7r7q{Hvmd>#jbP>;p;BX|}8I^d84NFty8nED;OQ$&{ghB+pGCU=~h zhd8v@C4L1EzID;*GE}2T?k7}(Sa@d&Um-O^xy8aeL+um`?+jIXll;^GY+&6!k=m=h zGt>dG@Xk;^vG86q&^p*cn*pl{Q~y}tq{??LRZC?J%SX~>d!@3yH_a-ZX=?A9)k+xo z2Iwi#fkS=~P-nx0B4FEg9Xicy0#E8Hb#PKz1hi2dbT From c3a7a7312d9f3cddf03beb2765ff705c7d3ece70 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 09:25:28 +0000 Subject: [PATCH 8/9] Board sensor: drop temperature/voltage attributes, live versions - Temperature and voltage are separate diagnostic sensors now, the duplicate attributes of the board sensor are removed. - sw_version / firmware attributes are read live from the board object (were fixed at entity creation, stale after a firmware update). - status.htm also updates the app version, as the former GetStatus on every 10th poll did (that GetStatus only refreshed module id, versions, voltage and temperature; entity counts come from GetConfig on every heartbeat and are not affected). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NVLmxv3Hbmdd6Nzf6zPp3p --- custom_components/dscriptmodule/board.py | 4 ++++ custom_components/dscriptmodule/sensor_board.py | 12 ++---------- tests/test_init.py | 3 +++ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/custom_components/dscriptmodule/board.py b/custom_components/dscriptmodule/board.py index 7a95a36..cd18051 100644 --- a/custom_components/dscriptmodule/board.py +++ b/custom_components/dscriptmodule/board.py @@ -240,6 +240,10 @@ def update_from_status_page(self, text) -> bool: except (KeyError, ValueError) as e: _LOGGER.debug("%s - %s: dScriptBoardHA update_from_status_page: unexpected content: %s (%s.%s)", self._HostName, self.IP, str(e), e.__class__.__module__, type(e).__name__) return False + app_major, sep, app_minor = values.get('app', '').partition('.') + if sep and app_major.isdigit() and app_minor.isdigit(): # keep the version current like the former GetStatus every 10th poll did + self._ApplicationFirmwareMajor = int(app_major) + self._ApplicationFirmwareMinor = int(app_minor) self._Temperature = temperature / 10.0 self._Volts = voltage / 10.0 self._InstrPerSec = instr diff --git a/custom_components/dscriptmodule/sensor_board.py b/custom_components/dscriptmodule/sensor_board.py index 4387e70..81fc22e 100644 --- a/custom_components/dscriptmodule/sensor_board.py +++ b/custom_components/dscriptmodule/sensor_board.py @@ -14,8 +14,6 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.const import ( ATTR_MODEL, - ATTR_VOLTAGE, - ATTR_TEMPERATURE, ATTR_DEVICE_ID, ATTR_SW_VERSION, CONF_UNIQUE_ID, @@ -53,8 +51,6 @@ class dScriptBoardSensor(dScriptPlatformEntity): _icon = 'mdi:developer-board' _platform = PLATFORM - _firmware = STATE_UNKNOWN - _software = STATE_UNKNOWN _onlineurl = STATE_UNKNOWN _configurl = STATE_UNKNOWN _NoGetUpdateCounter = 999 @@ -65,8 +61,6 @@ class dScriptBoardSensor(dScriptPlatformEntity): def _init_platform_specific(self, **kwargs): """Platform specific init actions""" _LOGGER.debug("%s - %s %s%s: _init_platform_specific", self._entry_id, self._board.name, self._dSEntityType, self._identifier) - self._firmware = str(self._board._SystemFirmwareMajor) + "." + str(self._board._SystemFirmwareMinor) - self._software = str(self._board._ApplicationFirmwareMajor) + "." + str(self._board._ApplicationFirmwareMinor) self._onlineurl= "http://" + self._board.IP + "/index.htm" self._statusurl= "http://" + self._board.IP + "/status.htm" self._configurl= "http://" + self._board.IP + "/_config.htm" @@ -80,11 +74,9 @@ def extra_state_attributes(self): """Return the state attributes of the sensor.""" return { ATTR_MODEL: self._board._ModuleID, - ATTR_VOLTAGE: self._board._Volts, - ATTR_TEMPERATURE: self._board._Temperature, ATTR_DEVICE_ID: self._board.MACAddress, - ATTR_SW_VERSION: self._software, - CATTR_FW_VERSION: self._firmware, + ATTR_SW_VERSION: str(self._board._ApplicationFirmwareMajor) + "." + str(self._board._ApplicationFirmwareMinor), # read live - changes after a firmware update + CATTR_FW_VERSION: str(self._board._SystemFirmwareMajor) + "." + str(self._board._SystemFirmwareMinor), CATTR_IP_ADDRESS: self._board.IP, CATTR_SW_TYPE: self._board._CustomFirmeware, CATTR_PROTOCOL: self._board._Protocol diff --git a/tests/test_init.py b/tests/test_init.py index 1191f14..224ea3c 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -150,6 +150,9 @@ async def test_status_page_feeds_diagnostic_sensors(hass: HomeAssistant, fake_bo assert hass.states.get(load).attributes["last_second"] == 1200 assert board_entity(hass, entry, "sensor_board")._board._StatusPageSupported is True assert len(fake_board.requests) == requests_before, "status.htm replaces the extra GetStatus connection" + board_state = hass.states.get(board_entity(hass, entry, "sensor_board").entity_id) + assert "temperature" not in board_state.attributes and "voltage" not in board_state.attributes # separate entities now + assert board_state.attributes["sw_version"] == "3.9" # app version taken over from status.htm (GetStatus reported 3.8) voltage = registry.async_get_entity_id("sensor", DOMAIN, "dscriptmodule_" + MAC.replace(":", "") + "_sensor_voltage1") voltage_entry = registry.async_get(voltage) From bea983a654cb5c7c5b906161a99daf0ef30f76f9 Mon Sep 17 00:00:00 2001 From: mk-maddin Date: Sat, 10 Oct 2026 15:25:02 +0200 Subject: [PATCH 9/9] add logos --- .../dscriptmodule/brand/LICENSE.txt | 17 +++++++++++++++++ .../dscriptmodule/brand/README.md | 11 +++++++++++ custom_components/dscriptmodule/brand/icon.png | Bin 0 -> 42214 bytes custom_components/dscriptmodule/brand/logo.png | Bin 0 -> 42214 bytes 4 files changed, 28 insertions(+) create mode 100644 custom_components/dscriptmodule/brand/LICENSE.txt create mode 100644 custom_components/dscriptmodule/brand/README.md create mode 100644 custom_components/dscriptmodule/brand/icon.png create mode 100644 custom_components/dscriptmodule/brand/logo.png diff --git a/custom_components/dscriptmodule/brand/LICENSE.txt b/custom_components/dscriptmodule/brand/LICENSE.txt new file mode 100644 index 0000000..6f47868 --- /dev/null +++ b/custom_components/dscriptmodule/brand/LICENSE.txt @@ -0,0 +1,17 @@ +The brand assets in this directory, including the dScript +logo and related artwork, are not covered by the +Apache License 2.0 applicable to the source code of this project. + +dScript and associated logos are trademarks and/or +copyrighted materials of Devantech Ltd. and/or +its affiliates. + +No license to these trademarks or copyrighted materials is +granted by this repository. + +The brand assets are included solely for identification of +compatible dScript products. + +This project is an independent, unofficial Home Assistant +integration and is not affiliated with, endorsed by, or +sponsored by Devantech Ltd.. \ No newline at end of file diff --git a/custom_components/dscriptmodule/brand/README.md b/custom_components/dscriptmodule/brand/README.md new file mode 100644 index 0000000..b45e04c --- /dev/null +++ b/custom_components/dscriptmodule/brand/README.md @@ -0,0 +1,11 @@ +# Brand assets + +The images in this directory contain the dScript brand/logo. + +dScirpt and associated logos are trademarks and/or copyrighted materials of Devantech Ltd. and/or its affiliates. + +These brand assets are not licensed under the Apache License 2.0 that applies to the source code of this project. + +They are included solely to identify the dScript products supported by this unofficial Home Assistant integration. + +This project is independent from and is not affiliated with, endorsed by, or sponsored by Devantech Ltd.. \ No newline at end of file diff --git a/custom_components/dscriptmodule/brand/icon.png b/custom_components/dscriptmodule/brand/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f77dd45f7b800dfece4238d1915a168ce26cf2c7 GIT binary patch literal 42214 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 literal 0 HcmV?d00001 diff --git a/custom_components/dscriptmodule/brand/logo.png b/custom_components/dscriptmodule/brand/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f77dd45f7b800dfece4238d1915a168ce26cf2c7 GIT binary patch literal 42214 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 literal 0 HcmV?d00001