From 92a90c8abc47b6c3a2cbfd8edf4d0912e335dcf5 Mon Sep 17 00:00:00 2001 From: kwithus Date: Mon, 7 Oct 2024 09:45:16 +0200 Subject: [PATCH 1/7] Add files via upload I have done a couple of additions and changes (based on 1.04) Mainly: Adding all addresses for all three HKR Correcting the names Change/corrected the addresses and settings for several pumps, I hope I have done the upload correctly this time Best regards --- .../solvis_control/solvis_control/__init__.py | 50 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2560 bytes .../__pycache__/config_flow.cpython-312.pyc | Bin 0 -> 4977 bytes .../__pycache__/const.cpython-312.pyc | Bin 0 -> 8046 bytes .../__pycache__/coordinator.cpython-312.pyc | Bin 0 -> 4084 bytes .../__pycache__/number.cpython-312.pyc | Bin 0 -> 6666 bytes .../__pycache__/select.cpython-312.pyc | Bin 0 -> 6162 bytes .../__pycache__/sensor.cpython-312.pyc | Bin 0 -> 5411 bytes .../solvis_control/config_flow.py | 118 ++++ .../solvis_control/solvis_control/const.py | 636 ++++++++++++++++++ .../solvis_control/coordinator.py | 75 +++ .../solvis_control/solvis_control/icons.json | 15 + .../solvis_control/manifest.json | 13 + .../solvis_control/solvis_control/number.py | 152 +++++ .../solvis_control/solvis_control/select.py | 137 ++++ .../solvis_control/solvis_control/sensor.py | 131 ++++ .../solvis_control/strings.json | 299 ++++++++ .../solvis_control/translations/de.json | 301 +++++++++ .../solvis_control/translations/en.json | 202 ++++++ 19 files changed, 2129 insertions(+) create mode 100644 custom_components/solvis_control/solvis_control/__init__.py create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/config_flow.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/const.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/number.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/__pycache__/sensor.cpython-312.pyc create mode 100644 custom_components/solvis_control/solvis_control/config_flow.py create mode 100644 custom_components/solvis_control/solvis_control/const.py create mode 100644 custom_components/solvis_control/solvis_control/coordinator.py create mode 100644 custom_components/solvis_control/solvis_control/icons.json create mode 100644 custom_components/solvis_control/solvis_control/manifest.json create mode 100644 custom_components/solvis_control/solvis_control/number.py create mode 100644 custom_components/solvis_control/solvis_control/select.py create mode 100644 custom_components/solvis_control/solvis_control/sensor.py create mode 100644 custom_components/solvis_control/solvis_control/strings.json create mode 100644 custom_components/solvis_control/solvis_control/translations/de.json create mode 100644 custom_components/solvis_control/solvis_control/translations/en.json diff --git a/custom_components/solvis_control/solvis_control/__init__.py b/custom_components/solvis_control/solvis_control/__init__.py new file mode 100644 index 0000000..d57cbd1 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/__init__.py @@ -0,0 +1,50 @@ +""" +Modul to integrate solvis heaters to. + +Version: 1.0.1-release +""" + +"""Solvis integration.""" + +from datetime import timedelta + +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_IP_ADDRESS, Platform +from homeassistant.core import HomeAssistant + +from .const import CONF_HOST, CONF_PORT, DATA_COORDINATOR, DOMAIN +from .coordinator import SolvisModbusCoordinator + +PLATFORMS: [Platform] = [Platform.SENSOR, Platform.NUMBER, Platform.SELECT] + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up Solvis device from a config entry.""" + + conf_host = entry.data.get(CONF_HOST) + conf_port = entry.data.get(CONF_PORT) + + if conf_host is None or conf_port is None: + return False + + # Create data structure + hass.data.setdefault(DOMAIN, {}) + hass.data[DOMAIN].setdefault(entry.entry_id, {}) + + # Create coordinator for polling + coordinator = SolvisModbusCoordinator(hass, conf_host, conf_port) + await coordinator.async_config_entry_first_refresh() + hass.data[DOMAIN][entry.entry_id].setdefault(DATA_COORDINATOR, coordinator) + + # Setup platforms + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + + return True + + +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Unload a config entry.""" + if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): + hass.data[DOMAIN].pop(entry.entry_id) + + return unload_ok diff --git a/custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe13526fc267fbd1e8886189a1a615894b57112f GIT binary patch literal 2560 zcmb7GU2GFa5Z<%bf9E(hAj^ZSh{Bk;S=ftV+&e}Ue zO^p?OB2^7YNTe?X6jkLheQ6Qm0jYh6l}L_GqC~1tOP{QU2gFln&vtA=Dzz)^ z?#%4W?A-2rv-gX~!y;(jVav>4HiUksOr_b&#O7~6ETBmwqBwFPkr6E^Mz+K)45h6p ztBm8=q;bk7+v9fG5qFrpE#;J5aTm~b(UD?hcib)4#p`5G+#}b=>rJ^c<&}MLAA=;v z-0PLCt20PDt6YTw>46GeooB4^M#(Y5NPf|E6vQGcxkR^w#X6}eVHZ80;&}5mSv|;F zvfhC2+%a}k6*DPLSGlC3OEW~!B~DXQXObE>D*;0^SnFolDWH<7a)j&a?(OdDB2r2c zG>Lsm;|MT@OHay@D5Z1(826y6B$6{jicYcti{TxNMo#eIF+LayjSt0QhI1?>=n0j` zpz9e{Whtm>Nlh0N{V7A;VZ&vb3`b)VWpXS!K4JJm!HFP07>$mH!ja%ablk9qqNBlZ z1pG9|%%I_GPG_`1RV89l5px`rmdIf~upuuXAE=ma@lhO&j0>f#V@JW$)D9Z_2R+;8Y?)cJLB1trzCsKk) z+AMKXwfY)`q@)>bB{KluS%HXUJJ>3d)<``V1Z;#}DDhEa7d7T*RZTCGX_e@Pd%B7) zjUtAl?L~i2X{(;;jHatHL?)+I1p?E0O7(=ssuMNU!}Cccsq=hyI&17I#bZWLiiUK6 zOFwk&F${mA=kus&N4uI9*sJV9{nh##*;QX)KD_SpZUF+UPu(7#5 z4_^oua7!My+-O>CSi_y`*hytq5_#+|U@nijMgOgiZ#(Y7V*fKc+Wpq;&bzMV!>bKL z^CRo5zrY^KvxipMfdU>_!2`ACUr7tfRV9!27jSPL_pbE?@4dH%qp+{rTVUJsY{s*pA_GAH{T)`(d+}@%G*$zK1I+1OJd7Ut5V=*A zw#q?^ihWzE^O z;ci^PjYS9Ye+U;%QFXC1*v@>%1oz-u?*J7Ev>Fbc7u9K=H=IxeB>IRF8m6M?|T ztxC^g_sb|I^!|+9uc&A`p?D=Ww$v!#G8~W_SzW#;`>De)AAm3 Ndf51ka-#p&U)ooz7t(&vb*q6~Fdbxd9yOF}NH?&&R}JSP=?KgF)W+Pl z^fs0k)Mzf2jzQip1=OZobGkVfPsejD>6Tn;x|Jg?B9oZ|_9WMza{E1)C#H0V6qI99 zNDfZArH1S7bZ1>T4CU=Ea+XMu>qKgl8)lALz3Qdhy14D0+p0f;&*{~4=$XRsVtMxYoTjwi!Gi0LfH8Rs+_gQ}$PP^^*|6z=C< z$9}6nvMcVM`e1lr_`${H-q%+`C;rg2-Y~Qh8hFrE@wxqhD(?+>E5z&ZR>3OS8b42= zqizOUVHBOi(hJ6L+P4_PL673HTLCAo6pez# zq(GbC!N5S9F^Ar#EhyqB5CXInMH>hU0JI&lX3J)0YK%a1x&vCbqw+UEJnzjHJ8zR$ zD;^%b=s_=fJYL!f=Cbg2lD%`QKZL5=z_@8nB59YzrFrBbVD44RGB zHnjK;Igz5bDQ?@;1~8(-8JV4j41f`&m1b&`ZI|&WafSmB8%7*afPO?rTXI3k(JHx; z{IjN!ykaDbX*sbzpT61cSgT}IWmZmDTQPxKH8H8t#2!7B^q4;J+}PQ(r^ijVl80Kv z5@Q0>n^hIq@xbtIT~;USfgy;Z0(M1lwr%qg^w~}Oz>vNZ#2ooVh};U@3@tSudN8>n z99v85zTtk?zZP%5;eId3oNfk+x=g`np=f05Hz)$&9r#yI05QEmI9R=F+*~(o5+@)) zYb{AG!&xEFaMs6eC&bt*xzx5C%B+qQ|!S4tVjqFqfaW zZu39zcwpXO0r%aeWCMz|ZxLKxFs`%VaonwS7QOadCdgs(?#W;BSGlC`S?h2nFR3!a z3AzxVkeJd)5x|sVyl=rNR%?RzP|Pcri!uyh1)?2d=8{GYQJGwCsl|;V#4R&w z^~_Q^W611CQev@e!9}~_{pns1Iyx|suz1U!1-=Kq)NJB8l-4F=YYd=?AA|Ti`PUq& z2qY9=3T|JEwXDW^%CVlc)*UOoCx3tFkFP#_b-8!6!jq=GRpM$2SBR@2T=A0Toea_8 z=xVsT9PYkj{G#;p(u1~g&ubqQm%`o4;R~z6g(cy_nh;tQUM>qSuL%2}L}IIv?sBC2 z?)eWcE?j(2D(@fs$o&`ppZrUa?&Zk%k}zKJ5&xUqGaV!6+k-79cW@8exRagkhwXzr z6wHvdrL8sDz&N-M@Lxq@uMdCMoIL;`f}3p}VynvVP-AyS5Pj%xYt_aq(no$va`Y9j zS5F0TYb7yK)cUitz--S8mVC3~akPggk2&%*L>hP9>0FNVEeU;$7Qn-dOc%IRa+?XP zlh5R2Q8WXhnA4=9iusTzUM^-fq2wey6=JHM0I@|(^*J$BsKr!a(zSI&g(&E!N5D*d;B%-H>Kzzbfsauw zR9mTzthp~E>w0>YkgU-vOK{I|(cO?u!KK4%Z3a37Wkxx459C0Bk;EI2uO|tHh}rh% zAnwF32|FY}%#kO%_rmrLK5A;6kN>RW{f_0PJ(~j|{~JO)=Kv`9U#gFJvjwY0^jWcFfL-mOH+NMdT0b z@QK6GuY;&}ixWXu3<86*yPkJZ9eLxJGiaj#;)Ue>sPo|cQ@340vX#?JG>;c|y3;^%@1OL{MBih?R*O%3(%-Go6zOjLwOz`7GiA5WV5H~wF>P*XO zL8f}2Q7XX8QoOjC9^eSL0OLuF9U-jC4<4sXKSZW;urM$^=D#k~!D}l+u>F;To$?b{ zdjL6OLN3={WrssNgYGzX77ca~$_E34cmndQ7?>lY<|V*2kpxQ?mCl>3K{J zLCxRDk!5n^Nuc9K&uXBf9O#%IUJmS;^Hsb)&U>f5Lf~;9?z-@(GfP-J+hWt=>rZevJN6SBF>}hB6tLNUkzzQKPV%WKR z&v(x~_ndRjz0%)ev9N%j&%WX<{OP11{ENP9e4=*a_J0C`@R|Suh?-Cov!W<~C+h)k z)(cWr0$n-MF_5jRzyD5BMb`=enEi9iih{C*h;fOh-O0t0Y?NO1}zYW z1SD5eD?SdqDl$ncv_Tr$caU_z9xlQ8_OAGAM(u-6TXxs#-P>gQ;Xnh8U2w30-wdIRTUQsPn5AwypjmJPns1iz}F_%dcnPGMClm>nA}*k7e=i zJo@ZYtIA5S#$!3iJLFI&S7F+YFC8C*!s^U6pA&f2g_s4+g(yPFh0tNng}4HS3sD9W z{Z2E8uccDAmU&okc%$B1S7Fg1ulLpxTywGE)9@J=;n_9#@S+Rx z5`5mpTQ9>G9Nwt+))(PR4tc$|z6@V+vEi%miVJZAUUeb9248m}z5(BKA-)B#xe%|z z8!p~@6TWSG18djncUJHWqaXWR`7V5~W`^(A<>n9IhfT)+2!7l|`V;u+hP1Bw{S1D- zIr9|!V)dbzAy+965mkc$y);b<2EDXc0R_NN(OpudL`*9R>O9G-GIwF5Y$~Sx^6xj_ zpr1dVu)@WPW|BFLsKz?IGFd@GEs(OQ8bemFq!tvD%&VhTTrHWzT$J;uqM#d#lU7PC zDLG9AIkzZ-I<24@OHu)+m1x+k7A1!LJ`2lK7UmYu@gP0DPO%k#QsDg~8DETfD4Rv=$7 z3`}DytsLu>=PHgy-o}E?5D3WZ_!d+r$4{df|lCrX0)I0~QpcxPZq8 zE?uO2TshWfi)LmGxtDnC-s6tm4Ds5%4>@}Kh(vpnN^eHap<(DwT2Cuw62blt#3NRe z?Lm23$Tj zjWeb5x}hnRX{yspb$TrEm?idFZA>~%u3{J&A!96w#E^A*Fs+}ZYi^PrThndT@Af*a z)So8tpF``rOS4-Ok`N`h4{U=> zm1r1vlY~*!<1uK+*Z+zS79C6=XLRs{v8aDD8{T97rM*;VMy~TK6;bEZifrdlA$3kh zZsHtw2%X~&p>rriowG4ry>lqR7gFaODx&GySL+Zwv6w^pY8*m)sh+-ihfoo9NUg|r z2o+L?^fhycJA@8#htMGuq7K=ZuHGS(;0vj92o)uO6!4tF`-zGLyr7my8n<;%pz&U1 z+mu!5Bo>|8-9SVvIX#|r`WxGNKh40%JXS8OymC3;M?A~Uo>HzrytJpoQE6*pBjRrf zR;!^@id*?F<7#_}@X}VM-;49O7MHD!zJtCD5mDbxGoj5?(zc+eMp5PGf~Mky6@5j5 zczWz^VtQA!_NtmXi)ZQ%nnLs(^3GnIvHU8Q`obb!C-Fk6^+c@5=C=~HYBFg7+mI5OHlIW}%Z&-IUSzMl|$?bX-;CQen;hc?AYCf?7) zcR9s)_q`Jfpn?O8c#skMYlzl%P8?;#WAy~L-~%#O@8&YbZuV~#i(Zp>Nc%=e$(0jPF#^7UTg%uF+eaOUa`44-I` z14CYBNq4;^!#r}69Oz;|qMGi+&{g+zb4$*11~_vMW8&3x2W67!YAb%j>8574hB1&T zhnF~fkinQL`!{pp8V62G4wG<33RGJ=_>3bG3)a(|IlN(24ReVzGo0Z$7~P)i<;uV3B2j^IJ3x^(|%?QPh*?m0Uhx(OD=E#mEc4e3skbFnoQAH#O}Y7457^zIjM0H*Huq; zaI(nBlL0m%H+<}+^11y zMlQ;1ZWfL_C$Dm{SvVFs`DAQ2;dm;>448=tUfdVW!r{g0#Nm@IyYX;;3)6gISMWs+ zYrBGr9DY2`%y0?EK%AM8<#4lbUm}hdFyq9?f>&D&Hw$5#2o{`Um*bVak D%xd=q literal 0 HcmV?d00001 diff --git a/custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b5f150ea1554754c6b4c945e466c8722fb77d55 GIT binary patch literal 4084 zcmbUkTWk~A_0EiE{7#(U#Li>G5E2rHJa~wb@Z2P@NyzdL0TnEv(Zn+(4r7n^&KMGt zw5W?(khtCHpq4+YN!u;0)Sf%zu>-sQ zXs_&h&b{Yx&pr2^d(QmM@An{RmBaMJ3SfUC1G}*WWbJ2wEFcL*kwi(fLM7-ZO%a?? zm?#6#p*Rw3lr`sAg-bZ2&H~+)a7R5R&MDr6FX}7OoQgkD5v@p6Mk|5tlH5ulQ5CI9 zR7a~RL?fA*+GZP4f^zTyWsRaWG#WyZ=Q@(SGW&oj%+}5@5nrZhOjRz&HU79Nji)vK zh^UMFpsHdio)mQzzaY#J%5dxPge=L5E}no<4PiT*l0;qJzzc**OU=>gn4Hq%YBE9_ zn+DZnQjU>PaT*hU0WCNHtKgYa;*6q-(h)hPN-{RMqe&?)CSMTqfr&eE@_7Hq3B!H* z=+Ma6nWLx2V#FxB(FJ6!9gy#V^JNsJ-~eceiZVCQML34*uBby|uA?Y>15Hy=ZVW{n zM#$Q@W$=bwWNMGk@UgU}s|h|;XfL6Qdm__fw{$?q? zD4}yURd?H%L_MVK6MD!zDDYBf7EPJ=%;vM;l>gN+8A%RXoXaX&8uucsQCn;%g9*(4#kd4Z;dHg~= zsmu7XsAMV!u`KHGPA?@p~=ccSXI(qsqnn>-(^{_po|WmEm?x|6c+Rfdwc}VQy0!6G)MmrJJ=8pU_JeHksz^`;GMub z%GkBZUcUrEPp~wyF^QFmFX`*Mo@0`S%B;?rtM`;yJ!ESy!T)Di_Q^fXO2F1a$*5Eo30E@kG)C>+CGB#pvKT%BEPT|=_IR|tp(xDX6)D#8{m|8!=QjljBO=_&J%6FzJjKi z^XLj?>ON-n6|lk%TNYN>HpiBUt=%?P3C^+`SCHsA_FF8hvut5kD0{u1GgqjHJM)vb zWIZ;?LxCXj7cpeg{!=5ooRm^3DFCiA+=r?A|W!fH&` zEP|;8<`q@Fluq%wIIhTAQH7?0Vjc3Atno21$-k41$1W)|CO1#mC*?RcE$J@GWPGPo zMIpJ0=suCDA5_zdlx))>_nE~CF+-9s$76D)Y0#RIB{FFxAO50>3-3NAsq_WOtfWdB zpV4JV5i)-9A83&V90md=*9eoKGn@tem^{^n^NNU*V1=2iNR1>*n4GTR!tz91gT!hC zA*o7`FH>n-o2V@8_Ko~tv0sg8auO%o%h8Ls@52~z5XAF zZm$0^2g}qq=juALbshJ`Cv`nVsgZ2kNExZy+`13db>+hQvf+KJ;ig=;JsWQSlw(xFFf#ZKNzs9c7F7Z>z@CvKO5`@ zBf>nG{v_1C8s2(m_}=lm$CtyqJ{Zr2djXpJ>Rt(TKi$*&VZ+Dg9$)z6Lbh*gdC!^K z-Xe3phj=Hy;}uV@xEerrpkc{XpFfQJ?Ju8JHvbh-;B)Zp=*`ibZ*$hSd5J%e^Bv4H zF#j@N0dDzc-Ua_44FAh0ltU`zQ|A@vB;Ud+dbUNE><@T?`9XfI6~dcl9^t@ z8F7*dm(<8m;d%rCs?)SWaGxN&lNOZ%#VH7q8WRMwh{OlUwf7f_)0nI%f)Jtb7IKkE zf%m2v7npnlm>ncIq>-rn@;ds=!LK{K>^bW1^%1rKlk9BrL_)Y9aKi=RBa^Q;tH5@W z0-L-!?UQOkhEf>b84=#(Nm+s7TDI@9`3$-zWc_XPdjKCI+amRmxwoGpYo8?2 zU%C!hEv60I}9CM5Q_Q?wLC{nzeg3%(Xr>K4jkcVp cA?sDuO>O$Q|H%p9dYJJ(%No}`^B-?6YsLdo#U8 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 literal 0 HcmV?d00001 diff --git a/custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..291456b17631ddec15f8633c02b427dc71aa8df6 GIT binary patch literal 6162 zcmbtYU2qfE6~3$8l~(_| zr5a)lI_;4CsX#2C(@wcD)f8(2+9kT>=G2DR2GU0=7z?I0#x|x}VlAmqETq?a9mwklbQ6$ z*@QGl2w=M=BpJ9PX*H?lpzH*(>EsNQF)7-I#-pP`bny5{*rK_QWKznz3 z5trquc;XF^a|}zTlL=`oJ)MD4U{DnG9+Q$XR1<0#%4D#ZOvlv>HU|8XtUhe540B|B zViMbcqxpshCkKV0@$nPGW6{CM@e`VLc>MU_SX6TzAB?^{Iyf}>@`;fXn*GGc;jxLy zkrNXz>IP#kj%UQFtWr0W#+-^PipEN0O`1QhO2?;UNff4Xf+$VLv$7ht zVWJnfiF}%gkUar-Bb>@8s^%1R3=xt5BAUm5GDT1`#8x#9OEZ8wuxzsFypbO5*hZQs zXSOA>ike9YiA-uPlZLq{+Z26zz|l8vo1(*9WG<&Q7yzJjhMHpoZovj?0cKp39#1bIZQ)!dS`XTe1aLIqxO+1@}_(zzP?+Z$*K&)#lc#(g(Be z&VG=7H+}up<@V>7n)WO;?k&0fmtq%Umrh zpEtJMLvGfw$d#OdqBB%*hL*bb6`cD@uErAAT;$pcT-&NESn@Sqv0t{ozp3Es{IK_T zkzYp&zU?bJ4i$VuC10rI+gS1iuedL}AuIZ}6ntCi%Y4DduX#DQ=K<}oJIXc~@2ghC zZg}TMx0y}fC0M7E1*IyMgS{i6f&~bPq*R@g8Zg_e zi-@$ye(7s5xK~L&Q0-9mBjUwyk-ExT<0yemb6%NsWGZT9d&AY%}iLoS>tY1xp&O zWT!NHHl2JkD*<$9UKPjFiX11di9Teb(KeCA7zP(Iy3?Y$4X#mA!gh@Ts6F#OxWx!g*+?o-nQr?0OK*RlJWcOUK z6}aHl&%pba;H`#RyKZe-+BgOsc}gAKM#G+dl6UGI-{xA@U=|3I`!i8- z9SH*w_0tvqkD$)rs;qm3&Q?`jZ=-(}nrqI=Y*mSC_4Q6kj#8^`%YQ$DN-h;WU8{_* zw0+B%bj?J;KZ@*3wf@Ls_2kmjQ?-82WA(wO>c4G0);y(#%vLpUG(qX<^@s#C ztKg>+Ox9DaE!0={9(Ie^;}gle4=9wQ!rXlLNIWgd5}%y||3ngb;-&D@IFsVlQxacy zA%M3O8Ln2=Rqzl5Md9j?@Dpz&=jM{>nM!B#ZDZ-vaXDGvX>=x&@|+pA258w^|`n}j>yquI{HaT=zlIg&~; zO(Lm;1a4U}q2lL>5b;Csb3~F(LXgEy%bB>U*@$N&OJ^~$ag8C}1AM9&zeviBhD&n> zCsj!}6&IjaRSH}1cS)t&oVP%BRUvB1^E%>bEg($x9lWG!U?v!6FyB}2-$nkj;7RCD zfe;#j)5IZ{&v0UjPQKvemz@2puE3@73*$?z$5vd&OD_MacjMKbV$0@2%jROswnEFc zKQ*p+cUPtMt+@7=y89Q0S6n1Jo zyW|WmIr(b){WrzpftLygURrT|zpkIpeJxjCyxzUyi>x-bUp;qST4~&6P%|ryyKB_v z#%xQz<0W6)s;}{#*Oz_W_ic>Z0}f$NxH_#0Hm~;dedJ#5*=+zc=PGiY1+Mcp*Nq3s z&RdNuDp8NR#BSb(|Jo94nGsgnp8>6Bt1bxiQAwsPy$#PBKLq{wC4GhdDa%60`V3fE zbui3cK?{eTp?%ffYwg#^$(ln{!wWs6B$^GWx(dtxunH1aJdw=ZAxQH)x_Gf0)q?OI zFgJads_t5?@od!rtMTgZ!dKD78)wj2`c-s>^!u_NKNyjZC<^VV|^Z>A{ zWhj%C#dMzvn5MtR@G5|h9`<13)WItT3l7j}DeTm7L$eybF0p@I9utRDv&xy783@>h zNP$F9;@z^JQsWOcMd)JU9;CYBFV37L9itO$p7X)Xl$aNIBjw07v z;CgR!ePu6l@A_ud+jS37FfEtw($Nb?i>{7>t7D1Z|2Nl*Wg7U8%2w#=kunU6c#9g^ zM4j(D^a8~5hxRbn8K7i=oeC!PqdJhHsk6-8+>ZCtuw*co8o+5N719X_4 zj79-?iF+0edx&pMyj?-i9D)ExnFXvBG?yT}nT^Xv4JHAC5qEzND2Q?l^+`aCLoP)~oU zxuw+J^;N?Lw(D-w)-nq@oJ%ubwh_vKy#BJ2P%hNgS#}f3gS?GpFQI&BW9tLbvb+OX zJ@+i_Y|k1ERGCoagOr2qzd@G~WH*_IB-4RVpGUYG9vcKPlYkAdiN?F6ahutQHp7jG z_rff-z+BGI`G{mbQ!0kmcbtOfNATW_=f_Ab){hv5h6y%mtxrmk_W?c5hnGG~;8zPg zB?31oaeX!alQr<9La;&K{wKRWCCLy!DG?(s(vMKa(@eMLv8;0Rqkvh3(xu$8UdRA0%lp-hvU-(uv0lX`xawXdV6#-Sw`k+$hjqI*fZ zm7xsA7GTcSA_ z*D&un_uSue&-u=|`dc_0Kv4ejPuJ3I7NJiGV;81I93l##Z6qQNiInJ4sGN&)QG|9Y zZq9AiG)F^CE1sN}^O`b`;>$4{W71y5p9^q-T#yTzyiW<`!dy5P;UXr_C`~z*V@=wx zH0PpR)T9GSOD@L6fDVcwr8U>awVCs@bM3h}7teKY9l1`f)0BsmM6QeLqL2$o?v-cl zL)2@j=N6oU6s}i{NMW%_VnkMoip`>XkrAVpX)ftPXOP%(8Hq6|CV6kswf=ntcdB)x zXmc}>My`U@gWQHF0y%E~!G$p9UiH-*!AUDgZ02Pf71qPzq=E~H$Be{wD} z!)GSWO&bxb&!nJBOR6ahpH*|xgr>=wF64EC$qI^cLC9W&X#!Kyx}23}^NT8QEfb<> zj+P~DvfinAQdO}i=LKEG*5qH11E;*TWzWvdFJLdU80^%ci!+$ z&7GT=%^0C`6PZ_LCMFkNIX`{g@SmSPGdsU9eSRKRZMTkpP8Bb#X$?ym^s=C7hDRc2 zG@^o5$Y*&$6nSWnb=ace#ge{;^I11hSgk~${w4e$Zn+S85iD#Q6{!_l+EA}Fj;gim zwTnT>zS2wXqI3R*VLv_xkpmoHi z>ov3e+Ef-9J zu_yCt5)2$mnzq5#Kmq(*$EuQiB1IcPStJ7&WeIBrofmSF5y}bqwM8Kdejs7PlT$@W zNzwABK7?c!*rMzLGn8FnaMw1276n}}+)I*aV1hO$P7}J|^ zGogr$7_=nHy5Xzs&F~7Vt5RMBP%?qbf+mA89hH|w+(ZU;ngiGJFfb&VD8pwJ;?O~W zAzi95O{OLae6|KxMpViR7Zge4FBEuDS`^k4J>|p1Dse0M5GyqNSwKI2S=DqSSesi0 z2s0uz2<3H^AcetTX$epd)CKxLNvnK&VvG!zm&USdny%*fteRU@^RN+ZOfwGzEvC}P ztm)FL1*6%5AB|ih0U%t!kHeJ2Vzm&U;lI!~o2VK<&28I(Yk}>^waAUa9-G>nt@zko zU;Kb+x*EO`-fbJ*XVUk)sHOX$t!qbmcjfxZyZP(++dtjwd1|-y>D|~fm2mVbcZIw9 z+LhOC%owUr^UPZVl|4|;+vVzV%=Y%W=~*?sRUcDp8EBvN+zCT(8RPV2K?BzRV7k*a4FmDX}9aaje81J8TJrBlq1Qf1nzKy?i-#MM?}@4s$+;zhNR}=#xL~lRwaRsK#RM3##Bc240fI!9!y&MW-%;C0weiJqqzod@A~324d`HDSCl( z#uk0RIq|FL0nV9CbOGnYF2FFvJMl{-djtfrir#HgD-JH(EpSn^=qb{-YG-%{F0M$w zgMLqDa3Ya;O4}Gv!Ixq-LbITE3l$4#BOuDcQXafp&dw}su&@1WVw4j`Hy$5-h97

3BS zyv_o2B`ARl;Mf-S)PSeq<~t$#k=G^u5%ys;@q(^nURW1og^V}t$!N7&0oJXArNEnj z?ZT4b*48cf(ETg$|61iyR@v61UAz|@e_n{OcIY1 zmROo^Wh~4W%{>T+yiHYwd_L;%E z@!l=^t#GBgZ;Re%IxE4%PVw)-V+Z}m%l#)y{U^7k_Cv|a*aVS2R_Picbw?#JMCy3u z=qXYUS9%9X-Q~0orU-xJpsVNInd>vV{Xcpie=xq+b$T~3@nQ3a;~x&~cFe-EkxFm> z7X1;^bqISyS(0_yh1{s=XE(rmAjf-ThOy#!mOTui&9-`$w?bxls5EAC1xl~`%MV^b zcf9IWZGEl#d)9Q<5kVvv;P`Wa`r#*AA#wMi0;3(jtBdT_Eycj)sUGwSZrg~ch4gd z+;ncF2sgqzc{b>#*WN+BwgV4^3KXDQ>a36#6)Cy43JI7bCP^BWT*PWFsV_^(hDZeI zV0y|CHVBgNJj_6jl1|QFlvh{f{8DYQjqcg}x}eC7lQxW-+33lrwe?h-bRa6Z2;9h^ zmfCpE9&h8N)mtyDO4b$|W=kgrH8W2&rGwf+inSn$gal0VVEEn;a2~d21Y}LllLu#3 zg1l4C>i9J2L_!8WNqV|vc#C=#6;*)DlB8gY^d=@AZO~+TBWmGi4R_&;YmyPOvamO> z3<>12z?+$5%7tghu&{jsp6FL2=9x^I&}Vc)XL19O*f}p*-nxyA;Rg}%zjhR1KFtRZ z1bH5VLadc-m4nGrFu5BXIS92}ox3u(+x60Z=v*ZfJ!tCK87OxiEp;9(caD`h$Nn1I zZ+g<{_1u2wWTk(^LeEgN67MRumdS)TLgXyZXX#Vb#H|Um6^U0)Ate6kI#ZaQl1Qy1-OEC z;4%=nAQ+Q42f;YN^Y9#51FiE$i05Bl6BJ8=TcEG`*nmi=V}rh+s)`w&FhN_q03Rb< zi)L9#QFuN@VKYXN2yog8XC#j^lR0wv+Hc_V&1F=Lpkrf|{^81zp~~gM?Em`YiHBzH;?=1`gdo-6NE#9CLT6Bk;`PMKudr@QKzBI+mIH z6m@9{Tm`=XdpCNQ;YS*H9$7!qr0Z{zwDkzVH0jm#a4+(XG2bKbdk7}Er_u7AE}&zA zURDwmeOL_dMv@_#s(*O?Wl4bqOG{gMl67T+4^Hr47k(A87{HbsCMk$9^60*n=QTPb zCdsDZfp-^dmVm4Eh9se@{tUISh8U0Ghd1m?pgwrFzC!vC>@go?rq2I_Ed7(T=Ue8a zWrfe Schema: + return vol.Schema( + { + vol.Required(CONF_NAME, default="Solvis Heizung"): str, + vol.Required(CONF_HOST, default=data.get(CONF_HOST)): str, + vol.Required(CONF_PORT, default=502): int, + } + ) + + +def get_host_schema_options(data: ConfigType) -> Schema: + return vol.Schema( + { + vol.Required(CONF_HOST, default=data.get(CONF_HOST)): str, + vol.Required(CONF_PORT, default=data.get(CONF_PORT)): int, + } + ) + + +class SolvisConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + VERSION = 1 + MINOR_VERSION = 1 + + def __init__(self) -> None: + """Init the ConfigFlow.""" + _LOGGER.info("Initialize config flow for %s", DOMAIN) + self.data: ConfigType = {} + self.client = None + + async def async_step_user( + self, user_input: dict[str, str, int] | None = None + ) -> FlowResult: + """Handle the initial step.""" + if user_input is None: + return self.async_show_form( + step_id="user", data_schema=get_host_schema_config(self.data) + ) + self.data = user_input + await self.async_set_unique_id(self.data[CONF_HOST], raise_on_progress=False) + self._abort_if_unique_id_configured() + + return self.async_create_entry(title=self.data[CONF_NAME], data=self.data) + + @staticmethod + @callback + def async_get_options_flow( + config_entry: config_entries.ConfigEntry, + ) -> config_entries.OptionsFlow: + """Create the options flow.""" + return SolvisOptionsFlow(config_entry) + + # TODO: add check for valid data + # errors = {} + # try: + # self.client = ModbusClient.AsyncModbusTcpClient( + # user_input[CONF_HOST], user_input[CONF_PORT] + # ) + # await self.client.connect() + # except ConnectionException: + # errors["base"] = "Es konnte keine Verbinung aufgebaut werden" + # else: + # try: + # await self.client.read_coils(32770, 3, slave=1) + # except ModbusException as exc: + # _LOGGER.debug(f"Received ModbusException({exc}) from library") + # else: + # await self.client.close() + + # errors["base"] = "cannot_connect" + + # return self.async_show_form( + # step_id="user", data_schema=get_host_schema_config(self.data), errors=errors + # ) + + +class SolvisOptionsFlow(config_entries.OptionsFlow): + # The schema version of the entries that it creates + # Home Assistant will call your migrate method if the version changes + VERSION = 1 + MINOR_VERSION = 1 + + def __init__(self, config) -> None: + """Init the ConfigFlow.""" + self.config: ConfigType = config + self.data = dict(config.data) + self.client = None + + async def async_step_init( + self, user_input: dict[str, int] | None = None + ) -> FlowResult: + """Handle the initial step.""" + if user_input is None: + return self.async_show_form( + step_id="init", + data_schema=get_host_schema_options(self.data), + ) + self.data = user_input + return self.async_create_entry( + title=self.config_entry.get(CONF_NAME), data=self.data + ) diff --git a/custom_components/solvis_control/solvis_control/const.py b/custom_components/solvis_control/solvis_control/const.py new file mode 100644 index 0000000..c1a99cb --- /dev/null +++ b/custom_components/solvis_control/solvis_control/const.py @@ -0,0 +1,636 @@ +from dataclasses import dataclass + +DOMAIN = "solvis_control" + +CONF_NAME = "name" +CONF_HOST = "host" +CONF_PORT = "port" + +DATA_COORDINATOR = "coordinator" +MANUFACTURER = "Solvis" + + +@dataclass(frozen=True) +class ModbusFieldConfig: + name: str + address: int + unit: str + device_class: str + state_class: str + multiplier: float = 0.1 + # 1 = INPUT, 2 = HOLDING + + register: int = 1 + negative: bool = False + entity_category: str = None + enabled_by_default: bool = True + edit: bool = False + data: tuple = None + absolute_value: bool = False + + +PORT = 502 +REGISTERS = [ + ModbusFieldConfig( # Brennerleistung + name="gas_power", + address=33539, + unit="kW", + device_class="power", + state_class="measurement", + ), + ModbusFieldConfig( # Außentemperatur + name="outdoor_air_temp", + address=33033, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( + name="roof_air_temp", + address=33031, + unit="°C", + device_class="temperature", + state_class="measurement", + enabled_by_default=True, + ), + ModbusFieldConfig( # Zirkulationsdurchfluss + name="cold_water_temp", + address=33034, + unit="°C", + device_class="temperature", + state_class="measurement", + multiplier=0.1, + ), + ModbusFieldConfig( # Vorlauftemperatur + name="flow_water_temp", + address=33035, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( # Warmwassertemperatur + name="domestic_water_temp", + address=33025, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( + name="solar_water_temp", + address=33030, + unit="°C", + device_class="temperature", + state_class="measurement", + enabled_by_default=True, + ), + ModbusFieldConfig( + name="solar_heat_exchanger_in_water_temp", + address=33029, + unit="°C", + device_class="temperature", + state_class="measurement", + enabled_by_default=True, + ), + ModbusFieldConfig( + name="solar_heat_exchanger_out_water_temp", + address=33028, + unit="°C", + device_class="temperature", + state_class="measurement", + enabled_by_default=True, + ), + ModbusFieldConfig( # Speicherreferenztemperatur + name="tank_layer1_water_temp", + address=33026, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( # Heizungspuffertemperatur unten + name="tank_layer2_water_temp", + address=33032, + unit="°C", + device_class="temperature", + state_class="measurement", + absolute_value=True, + ), + ModbusFieldConfig( # Heizungspuffertemperatur oben + name="tank_layer3_water_temp", + address=33027, + unit="°C", + device_class="temperature", + state_class="measurement", + absolute_value=True, + ), + ModbusFieldConfig( # Warmwasserpuffer + name="tank_layer4_water_temp", + address=33024, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( # Kaltwassertemperatur + name="cold_water_temperatur", + address=33038, + unit="°C", + device_class="temperature", + state_class="measurement", + ), + ModbusFieldConfig( # Laufzeit Brenner + name="runtime_gasburner", + address=33536, + unit="h", + device_class="time", + state_class="measurement", + entity_category="diagnostic", + ), + ModbusFieldConfig( # Brennerstarts + name="number_gas_burner_start", + address=33537, + unit="", + device_class="", + state_class="measurement", + negative=True, + multiplier=1, + entity_category="diagnostic", + absolute_value=True, + ), + ModbusFieldConfig( # Ionisationsstrom + name="ionisation_voltage", + address=33540, + unit="mA", + device_class="current", + state_class="measurement", + ), + ModbusFieldConfig( # A01.Pumpe Zirkulation + name="a01_pumpe_zirkulation", + address=33280, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + ), + ModbusFieldConfig( # A02.Pumpe Warmwasser + name="a02_pumpe_warmwasser", + address=33281, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + ), + ModbusFieldConfig( # A03.Pumpe HKR 1 + name="a03_pumpe_hkr_1", + address=33282, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + + ), + ModbusFieldConfig( # A04.Pumpe HKR 2 + name="a04_pumpe_hkr_2", + address=33283, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + ), + ModbusFieldConfig( # A05.Pumpe HKR 3 + name="a05_pumpe_hkr_3", + address=33284, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + ), + ModbusFieldConfig( # A12.Brennerstatus + name="a12_brennerstatus", + address=33291, + unit="%", + device_class="power_factor", + state_class="measurement", + ), + ModbusFieldConfig( # WW Nachheizung 2322 + name="ww_nachheizung_2322", + address=2322, + unit="V", + device_class="voltage", + state_class="measurement", + register=2, + ), + ModbusFieldConfig( + name="solar_water_flow", + address=33040, + unit="l/min", + device_class=None, + state_class="measurement", + enabled_by_default=False, + ), + ModbusFieldConfig( # Durchfluss Warmwasserzirkualation + name="domestic_water_flow", + address=33041, + unit="l/min", + device_class=None, + state_class="measurement", + ), + ModbusFieldConfig( # HKR1 Betriebsart + name="hkr1_betriebsart", + address=2818, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("2", "3", "4", "5", "6", "7"), + ), + + ModbusFieldConfig( # HKR1 Vorlaufart + name="hkr1_vorlaufart", + address=2819, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + ModbusFieldConfig( # HKR1 Fix Vorlauf Tag + name="hkr1_fix_vorlauf_tag", + address=2820, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Fix Vorlauf Nacht + name="hkr1_fix_vorlauf_nacht", + address=2821, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag1 + name="hkr1_kurve_solltemperatur_tag1", + address=2822, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag2 + name="hkr1_kurve_solltemperatur_tag2", + address=2823, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag3 + name="hkr1_kurve_solltemperatur_tag3", + address=2824, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Absenktemperatur + name="hkr1_kurve_absenktemperatur", + address=2825, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR1 Kurve Steilheit + name="hkr1_kurve_steilheit", + address=2826, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), + ModbusFieldConfig( # HKR2 Betriebsart + name="hkr2_betriebsart", + address=3074, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("2", "3", "4", "5", "6", "7"), + ), + ModbusFieldConfig( # HKR2 Vorlaufart + name="hkr2_vorlaufart", + address=3075, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + ModbusFieldConfig( # HKR2 Fix Vorlauf Tag + name="hkr2_fix_vorlauf_tag", + address=3076, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Fix Vorlauf Nacht + name="hkr2_fix_vorlauf_nacht", + address=3077, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag1 + name="hkr2_kurve_solltemperatur_tag1", + address=3078, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag2 + name="hkr2_kurve_solltemperatur_tag2", + address=3079, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag3 + name="hkr2_kurve_solltemperatur_tag3", + address=3080, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Absenktemperatur + name="hkr2_kurve_absenktemperatur", + address=3081, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR2 Kurve Steilheit + name="hkr2_kurve_steilheit", + address=3082, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), + + ModbusFieldConfig( # HKR3 Betriebsart + name="hkr3_betriebsart", + address=3330, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("2", "3", "4", "5", "6", "7"), + ), + + ModbusFieldConfig( # HKR3 Vorlaufart + name="hkr3_vorlaufart", + address=3331, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + + + ModbusFieldConfig( # HKR3 Fix Vorlauf Tag + name="hkr3_fix_vorlauf_tag", + address=3332, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR3 Fix Vorlauf Nacht + name="hkr3_fix_vorlauf_nacht", + address=3333, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag1 + name="hkr3_kurve_solltemperatur_tag1", + address=3334, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag2 + name="hkr3_kurve_solltemperatur_tag2", + address=3335, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag3 + name="hkr3_kurve_solltemperatur_tag3", + address=3336, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR3 Kurve Absenktemperatur + name="hkr3_kurve_absenktemperatur", + address=3337, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR3 Kurve Steilheit + name="hkr3_kurve_steilheit", + address=3338, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), + + + ModbusFieldConfig( # DigIn Stoerungen + name="digin_stoerungen", + address=33045, + unit="", + device_class=None, + state_class=None, + multiplier=1, + entity_category="diagnostic", + ), + ModbusFieldConfig( # WW Solltemperatur + name="ww_solltemperatur", + address=2305, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(10, 65), + ), + ModbusFieldConfig( # VersionSC3 + name="version_sc3", + address=32770, + unit="", + device_class=None, + state_class=None, + multiplier=1, + entity_category="diagnostic", + ), + ModbusFieldConfig( # VersionNBG + name="version_nbg", + address=32771, + unit="", + device_class=None, + state_class=None, + multiplier=1, + entity_category="diagnostic", + ), + ModbusFieldConfig( # ZirkulationBetriebsart + name="zirkulation_betriebsart", + address=2049, + unit="", + device_class=None, + state_class=None, + multiplier=1, + # data=("0", "1", "2", "3"), + ), + ModbusFieldConfig( # Raumtemperatur_HKR1 + name="raumtemperatur_hkr1", + address=34304, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + edit=False, + data=(0, 40), + ), + ModbusFieldConfig( # Raumtemperatur_HKR2 + name="raumtemperatur_hkr2", + address=34305, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + edit=False, + data=(0, 40), + ), + ModbusFieldConfig( # Raumtemperatur_HKR3 + name="raumtemperatur_hkr3", + address=34306, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + edit=False, + data=(0, 40), + ), + ModbusFieldConfig( # Wärmepumenleistung + name="waermepumpe_leistung", + address=33544, + unit="kW", + device_class="power", + state_class="measurement", + register=2, + edit=False, + enabled_by_default=True, + ), + ModbusFieldConfig( # elektrische Wärmepumenleistung + name="elek_waermepumpe_leistung", + address=33545, + unit="kWh", + device_class="energy", + state_class="total", + register=2, + edit=False, + enabled_by_default=True, + ), +] diff --git a/custom_components/solvis_control/solvis_control/coordinator.py b/custom_components/solvis_control/solvis_control/coordinator.py new file mode 100644 index 0000000..6e6f63e --- /dev/null +++ b/custom_components/solvis_control/solvis_control/coordinator.py @@ -0,0 +1,75 @@ +"""Solvis Modbus Data Coordinator""" + +from datetime import timedelta +import logging + +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator + +from pymodbus import ModbusException +import pymodbus.client as ModbusClient +from pymodbus.exceptions import ConnectionException, ModbusException +from pymodbus.payload import BinaryPayloadDecoder, Endian + +from .const import DOMAIN, REGISTERS + +_LOGGER = logging.getLogger(__name__) + + +class SolvisModbusCoordinator(DataUpdateCoordinator): + """My custom coordinator.""" + + def __init__(self, hass, conf_host, conf_port): + """Initialize my coordinator.""" + super().__init__( + hass, + _LOGGER, + # Name of the data. For logging purposes. + name=DOMAIN, + # Polling interval. Will only be polled if there are subscribers. + update_interval=timedelta(seconds=30), + ) + self.logger.debug("Creating client") + self.modbus = ModbusClient.AsyncModbusTcpClient(host=conf_host, port=conf_port) + + async def _async_update_data(self): + """Fetch data from API endpoint. + + This is the place to pre-process the data to lookup tables + so entities can quickly look up their data. + """ + self.logger.debug("Polling data") + + parsed_data: dict = {} + try: + await self.modbus.connect() + except ConnectionException: + self.logger.warning("Couldn't connect to device") + if self.modbus.connected: + for register in REGISTERS: + self.logger.debug("Connected to Modbus for Solvis") + try: + if register.register == 1: + result = await self.modbus.read_input_registers( + register.address, 1, 1 + ) + elif register.register == 2: + result = await self.modbus.read_holding_registers( + register.address, 1, 1 + ) + except ModbusException as error: + self.logger.error(error) + else: + d = BinaryPayloadDecoder.fromRegisters( + result.registers, byteorder=Endian.BIG + ) + parsed_data[register.name] = round( + d.decode_16bit_int() * register.multiplier, 2 + ) + if register.negative: + parsed_data[register.name] *= -1 + if register.absolute_value: + parsed_data[register.name] = abs(parsed_data[register.name]) + self.modbus.close() + + # Pass data back to sensors + return parsed_data diff --git a/custom_components/solvis_control/solvis_control/icons.json b/custom_components/solvis_control/solvis_control/icons.json new file mode 100644 index 0000000..e4934d6 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/icons.json @@ -0,0 +1,15 @@ +{ + "entity": { + "sensor": { + "gas_power": { + "default": "mdi:gas-burner" + }, + "runtime_gasburner": { + "default": "mdi:hours-24" + }, + "number_gas_burner_start": { + "default": "mdi:numeric" + } + } + } +} \ No newline at end of file diff --git a/custom_components/solvis_control/solvis_control/manifest.json b/custom_components/solvis_control/solvis_control/manifest.json new file mode 100644 index 0000000..a714d83 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/manifest.json @@ -0,0 +1,13 @@ +{ + "domain": "solvis_control", + "name": "Solvis Control", + "codeowners": ["@LarsK1"], + "config_flow": true, + "dependencies": [], + "documentation": "https://github.com/LarsK1/hass_solvis_control/", + "integration_type": "device", + "iot_class": "local_polling", + "issue_tracker": "https://github.com/LarsK1/hass_solvis_control/issues", + "requirements": ["pymodbus"], + "version": "1.0.1-release" + } diff --git a/custom_components/solvis_control/solvis_control/number.py b/custom_components/solvis_control/solvis_control/number.py new file mode 100644 index 0000000..6df4068 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/number.py @@ -0,0 +1,152 @@ +"""Solvis number sensor.""" + +from decimal import Decimal +import logging +import re + +from pymodbus.exceptions import ConnectionException + +from homeassistant.components.number import NumberEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from .const import ( + CONF_HOST, + CONF_NAME, + DATA_COORDINATOR, + DOMAIN, + MANUFACTURER, + REGISTERS, +) +from .coordinator import SolvisModbusCoordinator + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Setup sensor entities.""" + + conf_host = entry.data.get(CONF_HOST) + if conf_host is None: + _LOGGER.error("Device has no address") + + # Generate device info + device_info = DeviceInfo( + identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, + name=entry.data.get(CONF_NAME), + manufacturer=MANUFACTURER, + model="Solvis Control 3", + ) + + # Add sensors + sensors_to_add = [] + + for register in REGISTERS: + if not register.edit: + continue + if register.address in (2818, 2819, 2019, 2049, 3074, 3075, 3330, 3331, 3032): + continue + sensors_to_add.append( + SolvisSensor( + hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], + device_info, + conf_host, + register.name, + register.unit, + register.device_class, + register.state_class, + register.enabled_by_default, + register.data, + register.address, + ) + ) + + async_add_entities(sensors_to_add) + + +class SolvisSensor(CoordinatorEntity, NumberEntity): + def __init__( + self, + coordinator: SolvisModbusCoordinator, + device_info: DeviceInfo, + address, + name: str, + unit_of_measurement: str | None = None, + device_class: str | None = None, + state_class: str | None = None, + enabled_by_default: bool = True, + data: tuple = None, + modbus_address: int = None, + ): + """Init entity.""" + super().__init__(coordinator) + self.modbus_address = modbus_address + self._address = address + self._response_key = name + self.entity_registry_enabled_default = enabled_by_default + self.device_class = device_class + self.state_class = state_class + self.native_unit_of_measurement = unit_of_measurement + self._attr_available = False + self.device_info = device_info + self._attr_has_entity_name = True + self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" + self.translation_key = name + self.native_min_value = data[0] + self.native_max_value = data[1] + self.native_step = 1.0 + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + + if self.coordinator.data is None: + _LOGGER.warning("Data from coordinator is None. Skipping update") + return + + if not isinstance(self.coordinator.data, dict): + _LOGGER.warning("Invalid data from coordinator") + self._attr_available = False + return + + response_data = self.coordinator.data.get(self._response_key) + if response_data is None: + _LOGGER.warning("No data for available for (%s)", self._response_key) + self._attr_available = False + return + + if ( + not isinstance(response_data, int) + and not isinstance(response_data, float) + and not isinstance(response_data, complex) + and not isinstance(response_data, Decimal) + ): + _LOGGER.warning( + "Invalid response data type from coordinator. %s has type %s", + response_data, + type(response_data), + ) + self._attr_available = False + return + + self._attr_available = True + self._attr_native_value = response_data + self.async_write_ha_state() + + async def async_set_native_value(self, value: float) -> None: + """Update the current value.""" + try: + await self.coordinator.modbus.connect() + except ConnectionException: + self.logger.warning("Couldn't connect to device") + if self.coordinator.modbus.connected: + await self.coordinator.modbus.write_register( + self.modbus_address, int(value), slave=1 + ) + self.coordinator.modbus.close() diff --git a/custom_components/solvis_control/solvis_control/select.py b/custom_components/solvis_control/solvis_control/select.py new file mode 100644 index 0000000..005c379 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/select.py @@ -0,0 +1,137 @@ +"""Solvis number sensor.""" + +from decimal import Decimal +import logging +import re + +from pymodbus.exceptions import ConnectionException + +from homeassistant.components.select import SelectEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from .const import ( + CONF_HOST, + CONF_NAME, + DATA_COORDINATOR, + DOMAIN, + MANUFACTURER, + REGISTERS, +) +from .coordinator import SolvisModbusCoordinator + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Setup sensor entities.""" + + conf_host = entry.data.get(CONF_HOST) + if conf_host is None: + _LOGGER.error("Device has no address") + # Generate device info + + device_info = DeviceInfo( + identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, + name=entry.data.get(CONF_NAME), + manufacturer=MANUFACTURER, + model="Solvis Control 3", + ) + + # Add sensors + + sensors_to_add = [] + + for register in REGISTERS: + if register.address not in (2019, 2818, 3074, 3330): + continue + sensors_to_add.append( + SolvisSensor( + hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], + device_info, + conf_host, + register.name, + register.enabled_by_default, + register.data, + register.address, + ) + ) + async_add_entities(sensors_to_add) + + +class SolvisSensor(CoordinatorEntity, SelectEntity): + def __init__( + self, + coordinator: SolvisModbusCoordinator, + device_info: DeviceInfo, + address, + name: str, + enabled_by_default: bool = True, + data: tuple = None, + modbus_address: int = None, + ): + """Init entity.""" + super().__init__(coordinator) + + self.modbus_address = modbus_address + self._address = address + self._response_key = name + self.entity_registry_enabled_default = enabled_by_default + self._attr_available = False + self.device_info = device_info + self._attr_has_entity_name = True + self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" + self.translation_key = name + self._attr_current_option = None + self._attr_options = data + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + + if self.coordinator.data is None: + _LOGGER.warning("Data from coordinator is None. Skipping update") + return + if not isinstance(self.coordinator.data, dict): + _LOGGER.warning("Invalid data from coordinator") + self._attr_available = False + return + response_data = self.coordinator.data.get(self._response_key) + if response_data is None: + _LOGGER.warning("No data for available for (%s)", self._response_key) + self._attr_available = False + return + if ( + not isinstance(response_data, int) + and not isinstance(response_data, float) + and not isinstance(response_data, complex) + and not isinstance(response_data, Decimal) + ): + _LOGGER.warning( + "Invalid response data type from coordinator. %s has type %s", + response_data, + type(response_data), + ) + self._attr_available = False + return + self._attr_available = True + self._attr_current_option = str(response_data) + self.async_write_ha_state() + + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + try: + await self.coordinator.modbus.connect() + except ConnectionException: + self.logger.warning("Couldn't connect to device") + if self.coordinator.modbus.connected: + await self.coordinator.modbus.write_register( + self.modbus_address, int(option), slave=1 + ) + self.coordinator.modbus.close() diff --git a/custom_components/solvis_control/solvis_control/sensor.py b/custom_components/solvis_control/solvis_control/sensor.py new file mode 100644 index 0000000..7f0520b --- /dev/null +++ b/custom_components/solvis_control/solvis_control/sensor.py @@ -0,0 +1,131 @@ +"""Solvis sensors.""" + +from decimal import Decimal +import logging +import re + +from homeassistant.components.sensor import SensorEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME, EntityCategory +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from .const import ( + CONF_HOST, + CONF_NAME, + DATA_COORDINATOR, + DOMAIN, + MANUFACTURER, + REGISTERS, +) +from .coordinator import SolvisModbusCoordinator + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Setup sensor entities.""" + + conf_host = entry.data.get(CONF_HOST) + if conf_host is None: + _LOGGER.error("Device has no address") + # Generate device info + + device_info = DeviceInfo( + identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, + name=entry.data.get(CONF_NAME), + manufacturer=MANUFACTURER, + model="Solvis Control 3", + ) + + # Add sensors + + sensors_to_add = [] + + for register in REGISTERS: + if register.edit: + continue + if register.address in (2019, 2818, 3074, 3330): + continue + sensors_to_add.append( + SolvisSensor( + hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], + device_info, + conf_host, + register.name, + register.unit, + register.device_class, + register.state_class, + register.entity_category, + register.enabled_by_default, + ) + ) + async_add_entities(sensors_to_add) + + +class SolvisSensor(CoordinatorEntity, SensorEntity): + def __init__( + self, + coordinator: SolvisModbusCoordinator, + device_info: DeviceInfo, + address, + name: str, + unit_of_measurement: str | None = None, + device_class: str | None = None, + state_class: str | None = None, + entitiy_category: str | None = None, + enabled_by_default: bool = True, + ): + """Init entity.""" + super().__init__(coordinator) + + self._address = address + self._response_key = name + if entitiy_category == "diagnostic": + self.entity_category = EntityCategory.DIAGNOSTIC + self.entity_registry_enabled_default = enabled_by_default + self.device_class = device_class + self.state_class = state_class + self.native_unit_of_measurement = unit_of_measurement + self._attr_available = False + self.device_info = device_info + self._attr_has_entity_name = True + self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" + self.translation_key = name + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + + if self.coordinator.data is None: + _LOGGER.warning("Data from coordinator is None. Skipping update") + return + if not isinstance(self.coordinator.data, dict): + _LOGGER.warning("Invalid data from coordinator") + self._attr_available = False + return + response_data = self.coordinator.data.get(self._response_key) + if response_data is None: + _LOGGER.warning("No data for available for (%s)", self._response_key) + self._attr_available = False + return + if ( + not isinstance(response_data, int) + and not isinstance(response_data, float) + and not isinstance(response_data, complex) + and not isinstance(response_data, Decimal) + ): + _LOGGER.warning( + "Invalid response data type from coordinator. %s has type %s", + response_data, + type(response_data), + ) + self._attr_available = False + return + self._attr_available = True + self._attr_native_value = response_data + self.async_write_ha_state() diff --git a/custom_components/solvis_control/solvis_control/strings.json b/custom_components/solvis_control/solvis_control/strings.json new file mode 100644 index 0000000..7bc99ec --- /dev/null +++ b/custom_components/solvis_control/solvis_control/strings.json @@ -0,0 +1,299 @@ +{ + "config": { + "flow_title": "Solvis Setup", + "step": { + "user": { + "data": { + "name": "name", + "host": "host", + "port": "port" + } + }, + "init": { + "data": { + "host": "host", + "port": "port" + } + } + }, + "abort": { + "already_configured": "Device is already configured" + }, + "error": { + "cannot_connect": "Failed to connect", + "invalid_auth": "Invalid authentication", + "unknown": "Unexpected error" + } + }, + "options": { + "flow_title": "Solvis Setup", + "step": { + "init": { + "data": { + "host": "host", + "port": "port" + } + } + }, + "abort": { + "already_configured": "Device is already configured" + }, + "error": { + "cannot_connect": "Failed to connect", + "invalid_auth": "Invalid authentication", + "unknown": "Unexpected error" + } + }, + "entity": { + "number": { + "ww_solltemperatur": { + "name": "WW Solltemperatur" + }, + "hkr1_fix_vorlauf_tag": { + "name": "HKR1 Fix Vorlauf tag" + }, + "hkr1_fix_vorlauf_nacht": { + "name": "HKR1 Fix Vorlauf Nacht" + }, + "hkr1_kurve_solltemperatur_tag1": { + "name": "HKR1 Kurve Solltemperatur Tag1" + }, + "hkr1_kurve_solltemperatur_tag2": { + "name": "HKR1 Kurve Solltemperatur Tag2" + }, + + "hkr1_kurve_solltemperatur_tag3": { + "name": "HKR1 Kurve Solltemperatur Tag3" + }, + + "hkr1_kurve_absenktemperatur": { + "name": "HKR1 Kurve Absenktemperatur" + }, + + "hkr1_kurve_steilheit": { + "name": "HKR1 Kurve Steilheit" + }, + + "hkr2_fix_vorlauf_tag": { + "name": "HKR2 Fix Vorlauf Tag" + }, + "hkr2_fix_vorlauf_nacht": { + "name": "HKR2 Fix Vorlauf Nacht" + }, + "hkr2_kurve_solltemperatur_tag1": { + "name": "HKR2 Kurve Solltemperatur Tag1" + }, + "hkr2_kurve_solltemperatur_tag2": { + "name": "HKR2 Kurve Solltemperatur Tag2" + }, + + "hkr2_kurve_solltemperatur_tag3": { + "name": "HKR2 Kurve Solltemperatur Tag3" + }, + + "hkr2_kurve_absenktemperatur": { + "name": "HKR2 Kurve Absenktemperatur" + }, + + "hkr2_kurve_steilheit": { + "name": "HKR2 Kurve Steilheit" + }, + + + "hkr3_fix_vorlauf_tag": { + "name": "HKR3 Fix Vorlauf Tag" + }, + "hkr3_fix_vorlauf_nacht": { + "name": "HKR3 Fix Vorlauf Nacht" + }, + "hkr3_kurve_solltemperatur_tag1": { + "name": "HKR3 Kurve Solltemperatur Tag1" + }, + "hkr3_kurve_solltemperatur_tag2": { + "name": "HKR3 Kurve Solltemperatur Tag2" + }, + + "hkr3_kurve_solltemperatur_tag3": { + "name": "HKR3 Kurve Solltemperatur Tag3" + }, + + "hkr3_kurve_absenktemperatur": { + "name": "HKR3 Kurve Absenktemperatur" + }, + + "hkr3_kurve_steilheit": { + "name": "HKR3 Kurve Steilheit" + }, + "raumtemperatur_hkr1": { + "name": "Raumtemperatur HKR1" + }, + "raumtemperatur_hkr2": { + "name": "Raumtemperatur HKR2" + }, + "raumtemperatur_hkr3": { + "name": "Raumtemperatur HKR3" + } + }, + + + + + "select": { + "hkr1_betriebsart": { + "name": "HKR1 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + }, + "hkr2_betriebsart": { + "name": "HKR2 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + }, + "hkr3_betriebsart": { + "name": "HKR3 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + } + }, + "sensor": { + "zirkulation_betriebsart": { + "name": "Zirkulation Betriebsart", + "state": { + "0": "Aus", + "1": "Puls", + "2": "Zeit", + "3": "Puls/Zeit" + } + }, + "hkr1_vorlaufart": { + "name": "HKR1 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, + "hkr2_vorlaufart": { + "name": "HKR2 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, + "hkr3_vorlaufart": { + "name": "HKR3 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, + "gas_power": { + "name": "Brennerleistung" + }, + "outdoor_air_temp": { + "name": "Außentemperatur" + }, + "roof_air_temp": { + "name": "Lufttemperatur Dach" + }, + "cold_water_temp": { + "name": "Zirkulationsdurchfluss" + }, + "flow_water_temp": { + "name": "Vorlauftemperatur" + }, + "domestic_water_temp": { + "name": "Warmwassertemperatur" + }, + "solar_water_temp": { + "name": "Wasserkreislauftemperatur" + }, + "solar_heat_exchanger_in_water_temp": { + "name": "Solarwäremtauschertemperatur In" + }, + "solar_heat_exchanger_out_water_temp": { + "name": "Solarwäremtauschertemperatur Out" + }, + "tank_layer1_water_temp": { + "name": "Speicherreferenztemperatur" + }, + "tank_layer2_water_temp": { + "name": "Heizungspuffertemperatur unten" + }, + "tank_layer3_water_temp": { + "name": "Heizungspuffertemperatur oben" + }, + "tank_layer4_water_temp": { + "name": "Warmwasserpuffer" + }, + "cold_water_temperatur": { + "name": "Kaltwassertemperatur" + }, + "runtime_gasburner": { + "name": "Laufzeit Brenner" + }, + "number_gas_burner_start": { + "name": "Brennerstarts" + }, + "ionisation_voltage": { + "name": "Ionisationsstrom" + }, + "a01_pumpe_zirkulation": { + "name": "A01.Pumpe Zirkulation" + }, + "a02_pumpe_warmwasser": { + "name": "A02.Pumpe Warmwasser" + }, + "a03_pumpe_hkr_1": { + "name": "A03.Pumpe HKR 1" + }, + "a04_pumpe_hkr_2": { + "name": "A04.Pumpe HKR 2" + }, + "a05_pumpe_hkr_3": { + "name": "A05.Pumpe HKR 3" + }, + "a12_brennerstatus": { + "name": "A12.Brennerstatus" + }, + "ww_nachheizung_2322": { + "name": "WW Nachheizung 2322" + }, + "solar_water_flow": { + "name": "Durchflussmenge Solar" + }, + "domestic_water_flow": { + "name": "Durchfluss Warmwasserzirkualation" + }, + "version_sc2": { + "name": "Version SC2" + }, + "version_nbg": { + "name": "Version NBG" + }, + "digin_stoerungen": { + "name": "Störungen", + "state": { + "1": "keine Störung" + } + } + } + } +} diff --git a/custom_components/solvis_control/solvis_control/translations/de.json b/custom_components/solvis_control/solvis_control/translations/de.json new file mode 100644 index 0000000..1d40152 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/translations/de.json @@ -0,0 +1,301 @@ +{ + "config": { + "flow_title": "Solvis Setup", + "step": { + "user": { + "data": { + "name": "Anlagenname (frei)", + "host": "IP-Adresse oder Hostname", + "port": "Port" + } + }, + "init": { + "data": { + "host": "IP-Adresse oder Hostname", + "port": "Port" + } + } + }, + "abort": { + "already_configured": "Das Gerät ist bereits eingerichtet." + }, + "error": { + "cannot_connect": "Verbindung fehlgeschlagen", + "invalid_auth": "Ungültige Anmeldedaten", + "unknown": "Unerwarter Fehler" + } + }, + "options": { + "flow_title": "Solvis Setup", + "step": { + "init": { + "data": { + "host": "IP-Adresse oder Hostname", + "port": "Port" + } + } + }, + "abort": { + "already_configured": "Das Gerät ist bereits eingerichtet." + }, + "error": { + "cannot_connect": "Verbindung fehlgeschlagen", + "invalid_auth": "Ungültige Anmeldedaten", + "unknown": "Unerwarter Fehler" + } + }, + "entity": { + "number": { + "ww_solltemperatur": { + "name": "WW Solltemperatur" + }, + "hkr1_fix_vorlauf_tag": { + "name": "HKR1 Fix Vorlauf tag" + }, + "hkr1_fix_vorlauf_nacht": { + "name": "HKR1 Fix Vorlauf Nacht" + }, + "hkr1_kurve_solltemperatur_tag1": { + "name": "HKR1 Kurve Solltemperatur Tag1" + }, + "hkr1_kurve_solltemperatur_tag2": { + "name": "HKR1 Kurve Solltemperatur Tag2" + }, + + "hkr1_kurve_solltemperatur_tag3": { + "name": "HKR1 Kurve Solltemperatur Tag3" + }, + + "hkr1_kurve_absenktemperatur": { + "name": "HKR1 Kurve Absenktemperatur" + }, + + "hkr1_kurve_steilheit": { + "name": "HKR1 Kurve Steilheit" + }, + + "hkr2_fix_vorlauf_tag": { + "name": "HKR2 Fix Vorlauf Tag" + }, + "hkr2_fix_vorlauf_nacht": { + "name": "HKR2 Fix Vorlauf Nacht" + }, + "hkr2_kurve_solltemperatur_tag1": { + "name": "HKR2 Kurve Solltemperatur Tag1" + }, + "hkr2_kurve_solltemperatur_tag2": { + "name": "HKR2 Kurve Solltemperatur Tag2" + }, + + "hkr2_kurve_solltemperatur_tag3": { + "name": "HKR2 Kurve Solltemperatur Tag3" + }, + + "hkr2_kurve_absenktemperatur": { + "name": "HKR2 Kurve Absenktemperatur" + }, + + "hkr2_kurve_steilheit": { + "name": "HKR2 Kurve Steilheit" + }, + + + "hkr3_fix_vorlauf_tag": { + "name": "HKR3 Fix Vorlauf Tag" + }, + "hkr3_fix_vorlauf_nacht": { + "name": "HKR3 Fix Vorlauf Nacht" + }, + "hkr3_kurve_solltemperatur_tag1": { + "name": "HKR3 Kurve Solltemperatur Tag1" + }, + "hkr3_kurve_solltemperatur_tag2": { + "name": "HKR3 Kurve Solltemperatur Tag2" + }, + + "hkr3_kurve_solltemperatur_tag3": { + "name": "HKR3 Kurve Solltemperatur Tag3" + }, + + "hkr3_kurve_absenktemperatur": { + "name": "HKR3 Kurve Absenktemperatur" + }, + + "hkr3_kurve_steilheit": { + "name": "HKR3 Kurve Steilheit" + }, + "raumtemperatur_hkr1": { + "name": "Raumtemperatur HKR1" + }, + "raumtemperatur_hkr2": { + "name": "Raumtemperatur HKR2" + }, + "raumtemperatur_hkr3": { + "name": "Raumtemperatur HKR3" + } + }, + "select": { + "hkr1_betriebsart": { + "name": "HKR1 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + }, + "hkr2_betriebsart": { + "name": "HKR2 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + }, + "hkr3_betriebsart": { + "name": "HKR3 Betriebsart", + "state": { + "2": "Automatik", + "3": "Tagbetrieb", + "4": "Absenkbetrieb", + "5": "Standby", + "6": "Eco", + "7": "Urlaub" + } + } + }, + "sensor": { + "zirkulation_betriebsart": { + "name": "Zirkulation Betriebsart", + "state": { + "0": "Aus", + "1": "Puls", + "2": "Zeit", + "3": "Puls/Zeit" + } + }, + "hkr1_vorlaufart": { + "name": "HKR1 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, + "hkr2_vorlaufart": { + "name": "HKR2 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, + "hkr3_vorlaufart": { + "name": "HKR3 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, + "gas_power": { + "name": "Brennerleistung" + }, + "outdoor_air_temp": { + "name": "Außentemperatur" + }, + "roof_air_temp": { + "name": "Lufttemperatur Dach" + }, + "cold_water_temp": { + "name": "Zirkulationsdurchfluss" + }, + "flow_water_temp": { + "name": "Vorlauftemperatur" + }, + "domestic_water_temp": { + "name": "Warmwassertemperatur" + }, + "solar_water_temp": { + "name": "Wasserkreislauftemperatur" + }, + "solar_heat_exchanger_in_water_temp": { + "name": "Solarwärmetauschertemperatur In" + }, + "solar_heat_exchanger_out_water_temp": { + "name": "Solarwärmetauschertemperatur Out" + }, + "tank_layer1_water_temp": { + "name": "Speicherreferenztemperatur" + }, + "tank_layer2_water_temp": { + "name": "Heizungspuffertemperatur unten" + }, + "tank_layer3_water_temp": { + "name": "Heizungspuffertemperatur oben" + }, + "tank_layer4_water_temp": { + "name": "Warmwasserpuffer" + }, + "cold_water_temperatur": { + "name": "Kaltwassertemperatur" + }, + "runtime_gasburner": { + "name": "Laufzeit Brenner" + }, + "number_gas_burner_start": { + "name": "Brennerstarts" + }, + "ionisation_voltage": { + "name": "Ionisationsstrom" + }, + "a01_pumpe_zirkulation": { + "name": "A01.Pumpe Zirkulation" + }, + "a02_pumpe_warmwasser": { + "name": "A02.Pumpe Warmwasser" + }, + "a03_pumpe_hkr_1": { + "name": "A03.Pumpe HKR 1" + }, + "a04_pumpe_hkr_2": { + "name": "A04.Pumpe HKR 2" + }, + "a05_pumpe_hkr_3": { + "name": "A05.Pumpe HKR 3" + }, + "a12_brennerstatus": { + "name": "A12.Brennerstatus" + }, + "ww_nachheizung_2322": { + "name": "WW Nachheizung 2322" + }, + "solar_water_flow": { + "name": "Durchflussmenge Solar" + }, + "domestic_water_flow": { + "name": "Durchfluss Warmwasserzirkualation" + }, + "version_sc2": { + "name": "Version SC2" + }, + "version_nbg": { + "name": "Version NBG" + }, + "digin_stoerungen": { + "name": "Störungen", + "state": { + "1": "keine Störung" + } + }, + "elek_waermepumpe_leistung": { + "name": "Elektrische Wärmepumpenleistung" + }, + "waermepumpe_leistung": { + "name": "Leistung Wärmepumpe" + } + } + } +} diff --git a/custom_components/solvis_control/solvis_control/translations/en.json b/custom_components/solvis_control/solvis_control/translations/en.json new file mode 100644 index 0000000..3c4b044 --- /dev/null +++ b/custom_components/solvis_control/solvis_control/translations/en.json @@ -0,0 +1,202 @@ +{ + "config": { + "flow_title": "Solvis Setup", + "step": { + "user": { + "data": { + "name": "device name (free)", + "host": "ip-address or hostname", + "port": "port" + } + }, + "init": { + "data": { + "host": "ip-address or hostname", + "port": "port" + } + } + }, + "abort": { + "already_configured": "the device is already setup" + }, + "error": { + "cannot_connect": "connection failed", + "invalid_auth": "invalid authentication", + "unknown": "Unknown error. Please report" + } + }, + "options": { + "flow_title": "Solvis Setup", + "step": { + "init": { + "data": { + "host": "ip-address or hostname", + "port": "port" + } + } + }, + "abort": { + "already_configured": "the device is already setup" + }, + "error": { + "cannot_connect": "connection failed", + "invalid_auth": "invalid authentication", + "unknown": "Unknown error. Please report" + } + }, + "entity": { + "number": { + "ww_solltemperatur": { + "name": "hot water set temperature" + }, + "hkr1_absenktemperatur_nacht": { + "name": "HKR1 night setback temperature" + }, + "hkr1_solltemperatur_tag": { + "name": "HKR1 day setpoint temperature" + }, + "raumtemperatur_hkr1": { + "name": "HKR1 room temperature" + } + }, + "select": { + "hkr1_betriebsart": { + "name": "HKR1 operating mode", + "state": { + "2": "automatic", + "3": "during day", + "4": "lowering mode", + "5": "standyby", + "6": "eco", + "7": "holiday" + } + }, + "hkr2_betriebsart": { + "name": "HKR2 operating mode", + "state": { + "2": "automatic", + "3": "during day", + "4": "lowering mode", + "5": "standyby", + "6": "eco", + "7": "holiday" + } + }, + "hkr3_betriebsart": { + "name": "HKR3 operating mode", + "state": { + "2": "automatic", + "3": "during day", + "4": "lowering mode", + "5": "standyby", + "6": "eco", + "7": "holiday" + } + } + }, + "sensor": { + "zirkulation_betriebsart": { + "name": "circulation mode", + "state": { + "0": "off", + "1": "pulse", + "2": "time", + "3": "puls / time" + } + }, + "gas_power": { + "name": "burner power" + }, + "outdoor_air_temp": { + "name": "outdoor temperature" + }, + "roof_air_temp": { + "name": "outdoor temperature roof" + }, + "cold_water_temp": { + "name": "circulation flow rate" + }, + "flow_water_temp": { + "name": "flow temperature" + }, + "domestic_water_temp": { + "name": "hot water temperature" + }, + "solar_water_temp": { + "name": "water circulation temperature" + }, + "solar_heat_exchanger_in_water_temp": { + "name": "solar heat exchanger temperature in" + }, + "solar_heat_exchanger_out_water_temp": { + "name": "solar heat exchanger temperature out" + }, + "tank_layer1_water_temp": { + "name": "storage tank reference temperature" + }, + "tank_layer2_water_temp": { + "name": "heating buffer temperature bottom" + }, + "tank_layer3_water_temp": { + "name": "heating buffer temperature top" + }, + "tank_layer4_water_temp": { + "name": "hot water buffer" + }, + "cold_water_temperatur": { + "name": "cold water temperature" + }, + "runtime_gasburner": { + "name": "burner runtime" + }, + "number_gas_burner_start": { + "name": "burner starts" + }, + "ionisation_voltage": { + "name": "ionization current" + }, + "a01_pumpe_zirkulation": { + "name": "A01 pump circulation" + }, + "a02_pumpe_warmwasser": { + "name": "A02 pump warm water" + }, + "a03_pumpe_hk1": { + "name": "A03 pump HK1" + }, + "a05_pumpe_zirkulation": { + "name": "A05 pump circulation" + }, + "a12_brennerstatus": { + "name": "A12 burner status" + }, + "ww_nachheizung_2322": { + "name": "hot water auxiliary heating 2322" + }, + "solar_water_flow": { + "name": "solar flow rate" + }, + "domestic_water_flow": { + "name": "flow rate hot water circulation" + }, + "version_sc2": { + "name": "version SC2" + }, + "version_nbg": { + "name": "version NBG" + }, + "digin_stoerungen": { + "name": "malfunctions", + "state": { + "1": "no fault" + } + }, + "elek_waermepumpe_leistung": { + "name": "electrical heat pump output" + }, + "waermepumpe_leistung": { + "name": "heat pump output" + } + } + } +} From 0d8eab5c5cd12248777a12c4714636285679898d Mon Sep 17 00:00:00 2001 From: kwithus Date: Mon, 7 Oct 2024 09:48:28 +0200 Subject: [PATCH 2/7] Delete custom_components/solvis_control/solvis_control directory Wrong upload --- .../solvis_control/solvis_control/__init__.py | 50 -- .../__pycache__/__init__.cpython-312.pyc | Bin 2560 -> 0 bytes .../__pycache__/config_flow.cpython-312.pyc | Bin 4977 -> 0 bytes .../__pycache__/const.cpython-312.pyc | Bin 8046 -> 0 bytes .../__pycache__/coordinator.cpython-312.pyc | Bin 4084 -> 0 bytes .../__pycache__/number.cpython-312.pyc | Bin 6666 -> 0 bytes .../__pycache__/select.cpython-312.pyc | Bin 6162 -> 0 bytes .../__pycache__/sensor.cpython-312.pyc | Bin 5411 -> 0 bytes .../solvis_control/config_flow.py | 118 ---- .../solvis_control/solvis_control/const.py | 636 ------------------ .../solvis_control/coordinator.py | 75 --- .../solvis_control/solvis_control/icons.json | 15 - .../solvis_control/manifest.json | 13 - .../solvis_control/solvis_control/number.py | 152 ----- .../solvis_control/solvis_control/select.py | 137 ---- .../solvis_control/solvis_control/sensor.py | 131 ---- .../solvis_control/strings.json | 299 -------- .../solvis_control/translations/de.json | 301 --------- .../solvis_control/translations/en.json | 202 ------ 19 files changed, 2129 deletions(-) delete mode 100644 custom_components/solvis_control/solvis_control/__init__.py delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/config_flow.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/const.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/number.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/__pycache__/sensor.cpython-312.pyc delete mode 100644 custom_components/solvis_control/solvis_control/config_flow.py delete mode 100644 custom_components/solvis_control/solvis_control/const.py delete mode 100644 custom_components/solvis_control/solvis_control/coordinator.py delete mode 100644 custom_components/solvis_control/solvis_control/icons.json delete mode 100644 custom_components/solvis_control/solvis_control/manifest.json delete mode 100644 custom_components/solvis_control/solvis_control/number.py delete mode 100644 custom_components/solvis_control/solvis_control/select.py delete mode 100644 custom_components/solvis_control/solvis_control/sensor.py delete mode 100644 custom_components/solvis_control/solvis_control/strings.json delete mode 100644 custom_components/solvis_control/solvis_control/translations/de.json delete mode 100644 custom_components/solvis_control/solvis_control/translations/en.json diff --git a/custom_components/solvis_control/solvis_control/__init__.py b/custom_components/solvis_control/solvis_control/__init__.py deleted file mode 100644 index d57cbd1..0000000 --- a/custom_components/solvis_control/solvis_control/__init__.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -Modul to integrate solvis heaters to. - -Version: 1.0.1-release -""" - -"""Solvis integration.""" - -from datetime import timedelta - -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_IP_ADDRESS, Platform -from homeassistant.core import HomeAssistant - -from .const import CONF_HOST, CONF_PORT, DATA_COORDINATOR, DOMAIN -from .coordinator import SolvisModbusCoordinator - -PLATFORMS: [Platform] = [Platform.SENSOR, Platform.NUMBER, Platform.SELECT] - - -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Set up Solvis device from a config entry.""" - - conf_host = entry.data.get(CONF_HOST) - conf_port = entry.data.get(CONF_PORT) - - if conf_host is None or conf_port is None: - return False - - # Create data structure - hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN].setdefault(entry.entry_id, {}) - - # Create coordinator for polling - coordinator = SolvisModbusCoordinator(hass, conf_host, conf_port) - await coordinator.async_config_entry_first_refresh() - hass.data[DOMAIN][entry.entry_id].setdefault(DATA_COORDINATOR, coordinator) - - # Setup platforms - await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) - - return True - - -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Unload a config entry.""" - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok diff --git a/custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index fe13526fc267fbd1e8886189a1a615894b57112f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2560 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 D%xd=q diff --git a/custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/coordinator.cpython-312.pyc deleted file mode 100644 index 2b5f150ea1554754c6b4c945e466c8722fb77d55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4084 zcmbUkTWk~A_0EiE{7#(U#Li>G5E2rHJa~wb@Z2P@NyzdL0TnEv(Zn+(4r7n^&KMGt zw5W?(khtCHpq4+YN!u;0)Sf%zu>-sQ zXs_&h&b{Yx&pr2^d(QmM@An{RmBaMJ3SfUC1G}*WWbJ2wEFcL*kwi(fLM7-ZO%a?? zm?#6#p*Rw3lr`sAg-bZ2&H~+)a7R5R&MDr6FX}7OoQgkD5v@p6Mk|5tlH5ulQ5CI9 zR7a~RL?fA*+GZP4f^zTyWsRaWG#WyZ=Q@(SGW&oj%+}5@5nrZhOjRz&HU79Nji)vK zh^UMFpsHdio)mQzzaY#J%5dxPge=L5E}no<4PiT*l0;qJzzc**OU=>gn4Hq%YBE9_ zn+DZnQjU>PaT*hU0WCNHtKgYa;*6q-(h)hPN-{RMqe&?)CSMTqfr&eE@_7Hq3B!H* z=+Ma6nWLx2V#FxB(FJ6!9gy#V^JNsJ-~eceiZVCQML34*uBby|uA?Y>15Hy=ZVW{n zM#$Q@W$=bwWNMGk@UgU}s|h|;XfL6Qdm__fw{$?q? zD4}yURd?H%L_MVK6MD!zDDYBf7EPJ=%;vM;l>gN+8A%RXoXaX&8uucsQCn;%g9*(4#kd4Z;dHg~= zsmu7XsAMV!u`KHGPA?@p~=ccSXI(qsqnn>-(^{_po|WmEm?x|6c+Rfdwc}VQy0!6G)MmrJJ=8pU_JeHksz^`;GMub z%GkBZUcUrEPp~wyF^QFmFX`*Mo@0`S%B;?rtM`;yJ!ESy!T)Di_Q^fXO2F1a$*5Eo30E@kG)C>+CGB#pvKT%BEPT|=_IR|tp(xDX6)D#8{m|8!=QjljBO=_&J%6FzJjKi z^XLj?>ON-n6|lk%TNYN>HpiBUt=%?P3C^+`SCHsA_FF8hvut5kD0{u1GgqjHJM)vb zWIZ;?LxCXj7cpeg{!=5ooRm^3DFCiA+=r?A|W!fH&` zEP|;8<`q@Fluq%wIIhTAQH7?0Vjc3Atno21$-k41$1W)|CO1#mC*?RcE$J@GWPGPo zMIpJ0=suCDA5_zdlx))>_nE~CF+-9s$76D)Y0#RIB{FFxAO50>3-3NAsq_WOtfWdB zpV4JV5i)-9A83&V90md=*9eoKGn@tem^{^n^NNU*V1=2iNR1>*n4GTR!tz91gT!hC zA*o7`FH>n-o2V@8_Ko~tv0sg8auO%o%h8Ls@52~z5XAF zZm$0^2g}qq=juALbshJ`Cv`nVsgZ2kNExZy+`13db>+hQvf+KJ;ig=;JsWQSlw(xFFf#ZKNzs9c7F7Z>z@CvKO5`@ zBf>nG{v_1C8s2(m_}=lm$CtyqJ{Zr2djXpJ>Rt(TKi$*&VZ+Dg9$)z6Lbh*gdC!^K z-Xe3phj=Hy;}uV@xEerrpkc{XpFfQJ?Ju8JHvbh-;B)Zp=*`ibZ*$hSd5J%e^Bv4H zF#j@N0dDzc-Ua_44FAh0ltU`zQ|A@vB;Ud+dbUNE><@T?`9XfI6~dcl9^t@ z8F7*dm(<8m;d%rCs?)SWaGxN&lNOZ%#VH7q8WRMwh{OlUwf7f_)0nI%f)Jtb7IKkE zf%m2v7npnlm>ncIq>-rn@;ds=!LK{K>^bW1^%1rKlk9BrL_)Y9aKi=RBa^Q;tH5@W z0-L-!?UQOkhEf>b84=#(Nm+s7TDI@9`3$-zWc_XPdjKCI+amRmxwoGpYo8?2 zU%C!hEv60I}9CM5Q_Q?wLC{nzeg3%(Xr>K4jkcVp cA?sDuO>O$Q|H%p9dYJJ(%No}`^B-?6YsLdo#U8 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 diff --git a/custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc b/custom_components/solvis_control/solvis_control/__pycache__/select.cpython-312.pyc deleted file mode 100644 index 291456b17631ddec15f8633c02b427dc71aa8df6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6162 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

3BS zyv_o2B`ARl;Mf-S)PSeq<~t$#k=G^u5%ys;@q(^nURW1og^V}t$!N7&0oJXArNEnj z?ZT4b*48cf(ETg$|61iyR@v61UAz|@e_n{OcIY1 zmROo^Wh~4W%{>T+yiHYwd_L;%E z@!l=^t#GBgZ;Re%IxE4%PVw)-V+Z}m%l#)y{U^7k_Cv|a*aVS2R_Picbw?#JMCy3u z=qXYUS9%9X-Q~0orU-xJpsVNInd>vV{Xcpie=xq+b$T~3@nQ3a;~x&~cFe-EkxFm> z7X1;^bqISyS(0_yh1{s=XE(rmAjf-ThOy#!mOTui&9-`$w?bxls5EAC1xl~`%MV^b zcf9IWZGEl#d)9Q<5kVvv;P`Wa`r#*AA#wMi0;3(jtBdT_Eycj)sUGwSZrg~ch4gd z+;ncF2sgqzc{b>#*WN+BwgV4^3KXDQ>a36#6)Cy43JI7bCP^BWT*PWFsV_^(hDZeI zV0y|CHVBgNJj_6jl1|QFlvh{f{8DYQjqcg}x}eC7lQxW-+33lrwe?h-bRa6Z2;9h^ zmfCpE9&h8N)mtyDO4b$|W=kgrH8W2&rGwf+inSn$gal0VVEEn;a2~d21Y}LllLu#3 zg1l4C>i9J2L_!8WNqV|vc#C=#6;*)DlB8gY^d=@AZO~+TBWmGi4R_&;YmyPOvamO> z3<>12z?+$5%7tghu&{jsp6FL2=9x^I&}Vc)XL19O*f}p*-nxyA;Rg}%zjhR1KFtRZ z1bH5VLadc-m4nGrFu5BXIS92}ox3u(+x60Z=v*ZfJ!tCK87OxiEp;9(caD`h$Nn1I zZ+g<{_1u2wWTk(^LeEgN67MRumdS)TLgXyZXX#Vb#H|Um6^U0)Ate6kI#ZaQl1Qy1-OEC z;4%=nAQ+Q42f;YN^Y9#51FiE$i05Bl6BJ8=TcEG`*nmi=V}rh+s)`w&FhN_q03Rb< zi)L9#QFuN@VKYXN2yog8XC#j^lR0wv+Hc_V&1F=Lpkrf|{^81zp~~gM?Em`YiHBzH;?=1`gdo-6NE#9CLT6Bk;`PMKudr@QKzBI+mIH z6m@9{Tm`=XdpCNQ;YS*H9$7!qr0Z{zwDkzVH0jm#a4+(XG2bKbdk7}Er_u7AE}&zA zURDwmeOL_dMv@_#s(*O?Wl4bqOG{gMl67T+4^Hr47k(A87{HbsCMk$9^60*n=QTPb zCdsDZfp-^dmVm4Eh9se@{tUISh8U0Ghd1m?pgwrFzC!vC>@go?rq2I_Ed7(T=Ue8a zWrfe Schema: - return vol.Schema( - { - vol.Required(CONF_NAME, default="Solvis Heizung"): str, - vol.Required(CONF_HOST, default=data.get(CONF_HOST)): str, - vol.Required(CONF_PORT, default=502): int, - } - ) - - -def get_host_schema_options(data: ConfigType) -> Schema: - return vol.Schema( - { - vol.Required(CONF_HOST, default=data.get(CONF_HOST)): str, - vol.Required(CONF_PORT, default=data.get(CONF_PORT)): int, - } - ) - - -class SolvisConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - VERSION = 1 - MINOR_VERSION = 1 - - def __init__(self) -> None: - """Init the ConfigFlow.""" - _LOGGER.info("Initialize config flow for %s", DOMAIN) - self.data: ConfigType = {} - self.client = None - - async def async_step_user( - self, user_input: dict[str, str, int] | None = None - ) -> FlowResult: - """Handle the initial step.""" - if user_input is None: - return self.async_show_form( - step_id="user", data_schema=get_host_schema_config(self.data) - ) - self.data = user_input - await self.async_set_unique_id(self.data[CONF_HOST], raise_on_progress=False) - self._abort_if_unique_id_configured() - - return self.async_create_entry(title=self.data[CONF_NAME], data=self.data) - - @staticmethod - @callback - def async_get_options_flow( - config_entry: config_entries.ConfigEntry, - ) -> config_entries.OptionsFlow: - """Create the options flow.""" - return SolvisOptionsFlow(config_entry) - - # TODO: add check for valid data - # errors = {} - # try: - # self.client = ModbusClient.AsyncModbusTcpClient( - # user_input[CONF_HOST], user_input[CONF_PORT] - # ) - # await self.client.connect() - # except ConnectionException: - # errors["base"] = "Es konnte keine Verbinung aufgebaut werden" - # else: - # try: - # await self.client.read_coils(32770, 3, slave=1) - # except ModbusException as exc: - # _LOGGER.debug(f"Received ModbusException({exc}) from library") - # else: - # await self.client.close() - - # errors["base"] = "cannot_connect" - - # return self.async_show_form( - # step_id="user", data_schema=get_host_schema_config(self.data), errors=errors - # ) - - -class SolvisOptionsFlow(config_entries.OptionsFlow): - # The schema version of the entries that it creates - # Home Assistant will call your migrate method if the version changes - VERSION = 1 - MINOR_VERSION = 1 - - def __init__(self, config) -> None: - """Init the ConfigFlow.""" - self.config: ConfigType = config - self.data = dict(config.data) - self.client = None - - async def async_step_init( - self, user_input: dict[str, int] | None = None - ) -> FlowResult: - """Handle the initial step.""" - if user_input is None: - return self.async_show_form( - step_id="init", - data_schema=get_host_schema_options(self.data), - ) - self.data = user_input - return self.async_create_entry( - title=self.config_entry.get(CONF_NAME), data=self.data - ) diff --git a/custom_components/solvis_control/solvis_control/const.py b/custom_components/solvis_control/solvis_control/const.py deleted file mode 100644 index c1a99cb..0000000 --- a/custom_components/solvis_control/solvis_control/const.py +++ /dev/null @@ -1,636 +0,0 @@ -from dataclasses import dataclass - -DOMAIN = "solvis_control" - -CONF_NAME = "name" -CONF_HOST = "host" -CONF_PORT = "port" - -DATA_COORDINATOR = "coordinator" -MANUFACTURER = "Solvis" - - -@dataclass(frozen=True) -class ModbusFieldConfig: - name: str - address: int - unit: str - device_class: str - state_class: str - multiplier: float = 0.1 - # 1 = INPUT, 2 = HOLDING - - register: int = 1 - negative: bool = False - entity_category: str = None - enabled_by_default: bool = True - edit: bool = False - data: tuple = None - absolute_value: bool = False - - -PORT = 502 -REGISTERS = [ - ModbusFieldConfig( # Brennerleistung - name="gas_power", - address=33539, - unit="kW", - device_class="power", - state_class="measurement", - ), - ModbusFieldConfig( # Außentemperatur - name="outdoor_air_temp", - address=33033, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( - name="roof_air_temp", - address=33031, - unit="°C", - device_class="temperature", - state_class="measurement", - enabled_by_default=True, - ), - ModbusFieldConfig( # Zirkulationsdurchfluss - name="cold_water_temp", - address=33034, - unit="°C", - device_class="temperature", - state_class="measurement", - multiplier=0.1, - ), - ModbusFieldConfig( # Vorlauftemperatur - name="flow_water_temp", - address=33035, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( # Warmwassertemperatur - name="domestic_water_temp", - address=33025, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( - name="solar_water_temp", - address=33030, - unit="°C", - device_class="temperature", - state_class="measurement", - enabled_by_default=True, - ), - ModbusFieldConfig( - name="solar_heat_exchanger_in_water_temp", - address=33029, - unit="°C", - device_class="temperature", - state_class="measurement", - enabled_by_default=True, - ), - ModbusFieldConfig( - name="solar_heat_exchanger_out_water_temp", - address=33028, - unit="°C", - device_class="temperature", - state_class="measurement", - enabled_by_default=True, - ), - ModbusFieldConfig( # Speicherreferenztemperatur - name="tank_layer1_water_temp", - address=33026, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( # Heizungspuffertemperatur unten - name="tank_layer2_water_temp", - address=33032, - unit="°C", - device_class="temperature", - state_class="measurement", - absolute_value=True, - ), - ModbusFieldConfig( # Heizungspuffertemperatur oben - name="tank_layer3_water_temp", - address=33027, - unit="°C", - device_class="temperature", - state_class="measurement", - absolute_value=True, - ), - ModbusFieldConfig( # Warmwasserpuffer - name="tank_layer4_water_temp", - address=33024, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( # Kaltwassertemperatur - name="cold_water_temperatur", - address=33038, - unit="°C", - device_class="temperature", - state_class="measurement", - ), - ModbusFieldConfig( # Laufzeit Brenner - name="runtime_gasburner", - address=33536, - unit="h", - device_class="time", - state_class="measurement", - entity_category="diagnostic", - ), - ModbusFieldConfig( # Brennerstarts - name="number_gas_burner_start", - address=33537, - unit="", - device_class="", - state_class="measurement", - negative=True, - multiplier=1, - entity_category="diagnostic", - absolute_value=True, - ), - ModbusFieldConfig( # Ionisationsstrom - name="ionisation_voltage", - address=33540, - unit="mA", - device_class="current", - state_class="measurement", - ), - ModbusFieldConfig( # A01.Pumpe Zirkulation - name="a01_pumpe_zirkulation", - address=33280, - unit="V", - device_class="voltage", - state_class="measurement", - multiplier=0.01, - ), - ModbusFieldConfig( # A02.Pumpe Warmwasser - name="a02_pumpe_warmwasser", - address=33281, - unit="V", - device_class="voltage", - state_class="measurement", - multiplier=0.01, - ), - ModbusFieldConfig( # A03.Pumpe HKR 1 - name="a03_pumpe_hkr_1", - address=33282, - unit="V", - device_class="voltage", - state_class="measurement", - multiplier=0.01, - - ), - ModbusFieldConfig( # A04.Pumpe HKR 2 - name="a04_pumpe_hkr_2", - address=33283, - unit="V", - device_class="voltage", - state_class="measurement", - multiplier=0.01, - ), - ModbusFieldConfig( # A05.Pumpe HKR 3 - name="a05_pumpe_hkr_3", - address=33284, - unit="V", - device_class="voltage", - state_class="measurement", - multiplier=0.01, - ), - ModbusFieldConfig( # A12.Brennerstatus - name="a12_brennerstatus", - address=33291, - unit="%", - device_class="power_factor", - state_class="measurement", - ), - ModbusFieldConfig( # WW Nachheizung 2322 - name="ww_nachheizung_2322", - address=2322, - unit="V", - device_class="voltage", - state_class="measurement", - register=2, - ), - ModbusFieldConfig( - name="solar_water_flow", - address=33040, - unit="l/min", - device_class=None, - state_class="measurement", - enabled_by_default=False, - ), - ModbusFieldConfig( # Durchfluss Warmwasserzirkualation - name="domestic_water_flow", - address=33041, - unit="l/min", - device_class=None, - state_class="measurement", - ), - ModbusFieldConfig( # HKR1 Betriebsart - name="hkr1_betriebsart", - address=2818, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("2", "3", "4", "5", "6", "7"), - ), - - ModbusFieldConfig( # HKR1 Vorlaufart - name="hkr1_vorlaufart", - address=2819, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("0", "1"), - ), - ModbusFieldConfig( # HKR1 Fix Vorlauf Tag - name="hkr1_fix_vorlauf_tag", - address=2820, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Fix Vorlauf Nacht - name="hkr1_fix_vorlauf_nacht", - address=2821, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag1 - name="hkr1_kurve_solltemperatur_tag1", - address=2822, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag2 - name="hkr1_kurve_solltemperatur_tag2", - address=2823, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag3 - name="hkr1_kurve_solltemperatur_tag3", - address=2824, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Absenktemperatur - name="hkr1_kurve_absenktemperatur", - address=2825, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR1 Kurve Steilheit - name="hkr1_kurve_steilheit", - address=2826, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), - ModbusFieldConfig( # HKR2 Betriebsart - name="hkr2_betriebsart", - address=3074, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("2", "3", "4", "5", "6", "7"), - ), - ModbusFieldConfig( # HKR2 Vorlaufart - name="hkr2_vorlaufart", - address=3075, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("0", "1"), - ), - ModbusFieldConfig( # HKR2 Fix Vorlauf Tag - name="hkr2_fix_vorlauf_tag", - address=3076, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR2 Fix Vorlauf Nacht - name="hkr2_fix_vorlauf_nacht", - address=3077, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag1 - name="hkr2_kurve_solltemperatur_tag1", - address=3078, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag2 - name="hkr2_kurve_solltemperatur_tag2", - address=3079, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag3 - name="hkr2_kurve_solltemperatur_tag3", - address=3080, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR2 Kurve Absenktemperatur - name="hkr2_kurve_absenktemperatur", - address=3081, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR2 Kurve Steilheit - name="hkr2_kurve_steilheit", - address=3082, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), - - ModbusFieldConfig( # HKR3 Betriebsart - name="hkr3_betriebsart", - address=3330, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("2", "3", "4", "5", "6", "7"), - ), - - ModbusFieldConfig( # HKR3 Vorlaufart - name="hkr3_vorlaufart", - address=3331, - unit="", - device_class=None, - state_class=None, - register=2, - multiplier=1, - data=("0", "1"), - ), - - - ModbusFieldConfig( # HKR3 Fix Vorlauf Tag - name="hkr3_fix_vorlauf_tag", - address=3332, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR3 Fix Vorlauf Nacht - name="hkr3_fix_vorlauf_nacht", - address=3333, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag1 - name="hkr3_kurve_solltemperatur_tag1", - address=3334, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag2 - name="hkr3_kurve_solltemperatur_tag2", - address=3335, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag3 - name="hkr3_kurve_solltemperatur_tag3", - address=3336, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR3 Kurve Absenktemperatur - name="hkr3_kurve_absenktemperatur", - address=3337, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR3 Kurve Steilheit - name="hkr3_kurve_steilheit", - address=3338, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), - - - ModbusFieldConfig( # DigIn Stoerungen - name="digin_stoerungen", - address=33045, - unit="", - device_class=None, - state_class=None, - multiplier=1, - entity_category="diagnostic", - ), - ModbusFieldConfig( # WW Solltemperatur - name="ww_solltemperatur", - address=2305, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(10, 65), - ), - ModbusFieldConfig( # VersionSC3 - name="version_sc3", - address=32770, - unit="", - device_class=None, - state_class=None, - multiplier=1, - entity_category="diagnostic", - ), - ModbusFieldConfig( # VersionNBG - name="version_nbg", - address=32771, - unit="", - device_class=None, - state_class=None, - multiplier=1, - entity_category="diagnostic", - ), - ModbusFieldConfig( # ZirkulationBetriebsart - name="zirkulation_betriebsart", - address=2049, - unit="", - device_class=None, - state_class=None, - multiplier=1, - # data=("0", "1", "2", "3"), - ), - ModbusFieldConfig( # Raumtemperatur_HKR1 - name="raumtemperatur_hkr1", - address=34304, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - edit=False, - data=(0, 40), - ), - ModbusFieldConfig( # Raumtemperatur_HKR2 - name="raumtemperatur_hkr2", - address=34305, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - edit=False, - data=(0, 40), - ), - ModbusFieldConfig( # Raumtemperatur_HKR3 - name="raumtemperatur_hkr3", - address=34306, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - edit=False, - data=(0, 40), - ), - ModbusFieldConfig( # Wärmepumenleistung - name="waermepumpe_leistung", - address=33544, - unit="kW", - device_class="power", - state_class="measurement", - register=2, - edit=False, - enabled_by_default=True, - ), - ModbusFieldConfig( # elektrische Wärmepumenleistung - name="elek_waermepumpe_leistung", - address=33545, - unit="kWh", - device_class="energy", - state_class="total", - register=2, - edit=False, - enabled_by_default=True, - ), -] diff --git a/custom_components/solvis_control/solvis_control/coordinator.py b/custom_components/solvis_control/solvis_control/coordinator.py deleted file mode 100644 index 6e6f63e..0000000 --- a/custom_components/solvis_control/solvis_control/coordinator.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Solvis Modbus Data Coordinator""" - -from datetime import timedelta -import logging - -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator - -from pymodbus import ModbusException -import pymodbus.client as ModbusClient -from pymodbus.exceptions import ConnectionException, ModbusException -from pymodbus.payload import BinaryPayloadDecoder, Endian - -from .const import DOMAIN, REGISTERS - -_LOGGER = logging.getLogger(__name__) - - -class SolvisModbusCoordinator(DataUpdateCoordinator): - """My custom coordinator.""" - - def __init__(self, hass, conf_host, conf_port): - """Initialize my coordinator.""" - super().__init__( - hass, - _LOGGER, - # Name of the data. For logging purposes. - name=DOMAIN, - # Polling interval. Will only be polled if there are subscribers. - update_interval=timedelta(seconds=30), - ) - self.logger.debug("Creating client") - self.modbus = ModbusClient.AsyncModbusTcpClient(host=conf_host, port=conf_port) - - async def _async_update_data(self): - """Fetch data from API endpoint. - - This is the place to pre-process the data to lookup tables - so entities can quickly look up their data. - """ - self.logger.debug("Polling data") - - parsed_data: dict = {} - try: - await self.modbus.connect() - except ConnectionException: - self.logger.warning("Couldn't connect to device") - if self.modbus.connected: - for register in REGISTERS: - self.logger.debug("Connected to Modbus for Solvis") - try: - if register.register == 1: - result = await self.modbus.read_input_registers( - register.address, 1, 1 - ) - elif register.register == 2: - result = await self.modbus.read_holding_registers( - register.address, 1, 1 - ) - except ModbusException as error: - self.logger.error(error) - else: - d = BinaryPayloadDecoder.fromRegisters( - result.registers, byteorder=Endian.BIG - ) - parsed_data[register.name] = round( - d.decode_16bit_int() * register.multiplier, 2 - ) - if register.negative: - parsed_data[register.name] *= -1 - if register.absolute_value: - parsed_data[register.name] = abs(parsed_data[register.name]) - self.modbus.close() - - # Pass data back to sensors - return parsed_data diff --git a/custom_components/solvis_control/solvis_control/icons.json b/custom_components/solvis_control/solvis_control/icons.json deleted file mode 100644 index e4934d6..0000000 --- a/custom_components/solvis_control/solvis_control/icons.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "entity": { - "sensor": { - "gas_power": { - "default": "mdi:gas-burner" - }, - "runtime_gasburner": { - "default": "mdi:hours-24" - }, - "number_gas_burner_start": { - "default": "mdi:numeric" - } - } - } -} \ No newline at end of file diff --git a/custom_components/solvis_control/solvis_control/manifest.json b/custom_components/solvis_control/solvis_control/manifest.json deleted file mode 100644 index a714d83..0000000 --- a/custom_components/solvis_control/solvis_control/manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "domain": "solvis_control", - "name": "Solvis Control", - "codeowners": ["@LarsK1"], - "config_flow": true, - "dependencies": [], - "documentation": "https://github.com/LarsK1/hass_solvis_control/", - "integration_type": "device", - "iot_class": "local_polling", - "issue_tracker": "https://github.com/LarsK1/hass_solvis_control/issues", - "requirements": ["pymodbus"], - "version": "1.0.1-release" - } diff --git a/custom_components/solvis_control/solvis_control/number.py b/custom_components/solvis_control/solvis_control/number.py deleted file mode 100644 index 6df4068..0000000 --- a/custom_components/solvis_control/solvis_control/number.py +++ /dev/null @@ -1,152 +0,0 @@ -"""Solvis number sensor.""" - -from decimal import Decimal -import logging -import re - -from pymodbus.exceptions import ConnectionException - -from homeassistant.components.number import NumberEntity -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME -from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity - -from .const import ( - CONF_HOST, - CONF_NAME, - DATA_COORDINATOR, - DOMAIN, - MANUFACTURER, - REGISTERS, -) -from .coordinator import SolvisModbusCoordinator - -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback -) -> None: - """Setup sensor entities.""" - - conf_host = entry.data.get(CONF_HOST) - if conf_host is None: - _LOGGER.error("Device has no address") - - # Generate device info - device_info = DeviceInfo( - identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, - name=entry.data.get(CONF_NAME), - manufacturer=MANUFACTURER, - model="Solvis Control 3", - ) - - # Add sensors - sensors_to_add = [] - - for register in REGISTERS: - if not register.edit: - continue - if register.address in (2818, 2819, 2019, 2049, 3074, 3075, 3330, 3331, 3032): - continue - sensors_to_add.append( - SolvisSensor( - hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], - device_info, - conf_host, - register.name, - register.unit, - register.device_class, - register.state_class, - register.enabled_by_default, - register.data, - register.address, - ) - ) - - async_add_entities(sensors_to_add) - - -class SolvisSensor(CoordinatorEntity, NumberEntity): - def __init__( - self, - coordinator: SolvisModbusCoordinator, - device_info: DeviceInfo, - address, - name: str, - unit_of_measurement: str | None = None, - device_class: str | None = None, - state_class: str | None = None, - enabled_by_default: bool = True, - data: tuple = None, - modbus_address: int = None, - ): - """Init entity.""" - super().__init__(coordinator) - self.modbus_address = modbus_address - self._address = address - self._response_key = name - self.entity_registry_enabled_default = enabled_by_default - self.device_class = device_class - self.state_class = state_class - self.native_unit_of_measurement = unit_of_measurement - self._attr_available = False - self.device_info = device_info - self._attr_has_entity_name = True - self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" - self.translation_key = name - self.native_min_value = data[0] - self.native_max_value = data[1] - self.native_step = 1.0 - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - - if self.coordinator.data is None: - _LOGGER.warning("Data from coordinator is None. Skipping update") - return - - if not isinstance(self.coordinator.data, dict): - _LOGGER.warning("Invalid data from coordinator") - self._attr_available = False - return - - response_data = self.coordinator.data.get(self._response_key) - if response_data is None: - _LOGGER.warning("No data for available for (%s)", self._response_key) - self._attr_available = False - return - - if ( - not isinstance(response_data, int) - and not isinstance(response_data, float) - and not isinstance(response_data, complex) - and not isinstance(response_data, Decimal) - ): - _LOGGER.warning( - "Invalid response data type from coordinator. %s has type %s", - response_data, - type(response_data), - ) - self._attr_available = False - return - - self._attr_available = True - self._attr_native_value = response_data - self.async_write_ha_state() - - async def async_set_native_value(self, value: float) -> None: - """Update the current value.""" - try: - await self.coordinator.modbus.connect() - except ConnectionException: - self.logger.warning("Couldn't connect to device") - if self.coordinator.modbus.connected: - await self.coordinator.modbus.write_register( - self.modbus_address, int(value), slave=1 - ) - self.coordinator.modbus.close() diff --git a/custom_components/solvis_control/solvis_control/select.py b/custom_components/solvis_control/solvis_control/select.py deleted file mode 100644 index 005c379..0000000 --- a/custom_components/solvis_control/solvis_control/select.py +++ /dev/null @@ -1,137 +0,0 @@ -"""Solvis number sensor.""" - -from decimal import Decimal -import logging -import re - -from pymodbus.exceptions import ConnectionException - -from homeassistant.components.select import SelectEntity -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME -from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity - -from .const import ( - CONF_HOST, - CONF_NAME, - DATA_COORDINATOR, - DOMAIN, - MANUFACTURER, - REGISTERS, -) -from .coordinator import SolvisModbusCoordinator - -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback -) -> None: - """Setup sensor entities.""" - - conf_host = entry.data.get(CONF_HOST) - if conf_host is None: - _LOGGER.error("Device has no address") - # Generate device info - - device_info = DeviceInfo( - identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, - name=entry.data.get(CONF_NAME), - manufacturer=MANUFACTURER, - model="Solvis Control 3", - ) - - # Add sensors - - sensors_to_add = [] - - for register in REGISTERS: - if register.address not in (2019, 2818, 3074, 3330): - continue - sensors_to_add.append( - SolvisSensor( - hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], - device_info, - conf_host, - register.name, - register.enabled_by_default, - register.data, - register.address, - ) - ) - async_add_entities(sensors_to_add) - - -class SolvisSensor(CoordinatorEntity, SelectEntity): - def __init__( - self, - coordinator: SolvisModbusCoordinator, - device_info: DeviceInfo, - address, - name: str, - enabled_by_default: bool = True, - data: tuple = None, - modbus_address: int = None, - ): - """Init entity.""" - super().__init__(coordinator) - - self.modbus_address = modbus_address - self._address = address - self._response_key = name - self.entity_registry_enabled_default = enabled_by_default - self._attr_available = False - self.device_info = device_info - self._attr_has_entity_name = True - self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" - self.translation_key = name - self._attr_current_option = None - self._attr_options = data - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - - if self.coordinator.data is None: - _LOGGER.warning("Data from coordinator is None. Skipping update") - return - if not isinstance(self.coordinator.data, dict): - _LOGGER.warning("Invalid data from coordinator") - self._attr_available = False - return - response_data = self.coordinator.data.get(self._response_key) - if response_data is None: - _LOGGER.warning("No data for available for (%s)", self._response_key) - self._attr_available = False - return - if ( - not isinstance(response_data, int) - and not isinstance(response_data, float) - and not isinstance(response_data, complex) - and not isinstance(response_data, Decimal) - ): - _LOGGER.warning( - "Invalid response data type from coordinator. %s has type %s", - response_data, - type(response_data), - ) - self._attr_available = False - return - self._attr_available = True - self._attr_current_option = str(response_data) - self.async_write_ha_state() - - async def async_select_option(self, option: str) -> None: - """Change the selected option.""" - try: - await self.coordinator.modbus.connect() - except ConnectionException: - self.logger.warning("Couldn't connect to device") - if self.coordinator.modbus.connected: - await self.coordinator.modbus.write_register( - self.modbus_address, int(option), slave=1 - ) - self.coordinator.modbus.close() diff --git a/custom_components/solvis_control/solvis_control/sensor.py b/custom_components/solvis_control/solvis_control/sensor.py deleted file mode 100644 index 7f0520b..0000000 --- a/custom_components/solvis_control/solvis_control/sensor.py +++ /dev/null @@ -1,131 +0,0 @@ -"""Solvis sensors.""" - -from decimal import Decimal -import logging -import re - -from homeassistant.components.sensor import SensorEntity -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME, EntityCategory -from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity - -from .const import ( - CONF_HOST, - CONF_NAME, - DATA_COORDINATOR, - DOMAIN, - MANUFACTURER, - REGISTERS, -) -from .coordinator import SolvisModbusCoordinator - -_LOGGER = logging.getLogger(__name__) - - -async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback -) -> None: - """Setup sensor entities.""" - - conf_host = entry.data.get(CONF_HOST) - if conf_host is None: - _LOGGER.error("Device has no address") - # Generate device info - - device_info = DeviceInfo( - identifiers={(DOMAIN, entry.data.get(CONF_HOST))}, - name=entry.data.get(CONF_NAME), - manufacturer=MANUFACTURER, - model="Solvis Control 3", - ) - - # Add sensors - - sensors_to_add = [] - - for register in REGISTERS: - if register.edit: - continue - if register.address in (2019, 2818, 3074, 3330): - continue - sensors_to_add.append( - SolvisSensor( - hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR], - device_info, - conf_host, - register.name, - register.unit, - register.device_class, - register.state_class, - register.entity_category, - register.enabled_by_default, - ) - ) - async_add_entities(sensors_to_add) - - -class SolvisSensor(CoordinatorEntity, SensorEntity): - def __init__( - self, - coordinator: SolvisModbusCoordinator, - device_info: DeviceInfo, - address, - name: str, - unit_of_measurement: str | None = None, - device_class: str | None = None, - state_class: str | None = None, - entitiy_category: str | None = None, - enabled_by_default: bool = True, - ): - """Init entity.""" - super().__init__(coordinator) - - self._address = address - self._response_key = name - if entitiy_category == "diagnostic": - self.entity_category = EntityCategory.DIAGNOSTIC - self.entity_registry_enabled_default = enabled_by_default - self.device_class = device_class - self.state_class = state_class - self.native_unit_of_measurement = unit_of_measurement - self._attr_available = False - self.device_info = device_info - self._attr_has_entity_name = True - self.unique_id = f"{re.sub('^[A-Za-z0-9_-]*$', '', name)}_{name}" - self.translation_key = name - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - - if self.coordinator.data is None: - _LOGGER.warning("Data from coordinator is None. Skipping update") - return - if not isinstance(self.coordinator.data, dict): - _LOGGER.warning("Invalid data from coordinator") - self._attr_available = False - return - response_data = self.coordinator.data.get(self._response_key) - if response_data is None: - _LOGGER.warning("No data for available for (%s)", self._response_key) - self._attr_available = False - return - if ( - not isinstance(response_data, int) - and not isinstance(response_data, float) - and not isinstance(response_data, complex) - and not isinstance(response_data, Decimal) - ): - _LOGGER.warning( - "Invalid response data type from coordinator. %s has type %s", - response_data, - type(response_data), - ) - self._attr_available = False - return - self._attr_available = True - self._attr_native_value = response_data - self.async_write_ha_state() diff --git a/custom_components/solvis_control/solvis_control/strings.json b/custom_components/solvis_control/solvis_control/strings.json deleted file mode 100644 index 7bc99ec..0000000 --- a/custom_components/solvis_control/solvis_control/strings.json +++ /dev/null @@ -1,299 +0,0 @@ -{ - "config": { - "flow_title": "Solvis Setup", - "step": { - "user": { - "data": { - "name": "name", - "host": "host", - "port": "port" - } - }, - "init": { - "data": { - "host": "host", - "port": "port" - } - } - }, - "abort": { - "already_configured": "Device is already configured" - }, - "error": { - "cannot_connect": "Failed to connect", - "invalid_auth": "Invalid authentication", - "unknown": "Unexpected error" - } - }, - "options": { - "flow_title": "Solvis Setup", - "step": { - "init": { - "data": { - "host": "host", - "port": "port" - } - } - }, - "abort": { - "already_configured": "Device is already configured" - }, - "error": { - "cannot_connect": "Failed to connect", - "invalid_auth": "Invalid authentication", - "unknown": "Unexpected error" - } - }, - "entity": { - "number": { - "ww_solltemperatur": { - "name": "WW Solltemperatur" - }, - "hkr1_fix_vorlauf_tag": { - "name": "HKR1 Fix Vorlauf tag" - }, - "hkr1_fix_vorlauf_nacht": { - "name": "HKR1 Fix Vorlauf Nacht" - }, - "hkr1_kurve_solltemperatur_tag1": { - "name": "HKR1 Kurve Solltemperatur Tag1" - }, - "hkr1_kurve_solltemperatur_tag2": { - "name": "HKR1 Kurve Solltemperatur Tag2" - }, - - "hkr1_kurve_solltemperatur_tag3": { - "name": "HKR1 Kurve Solltemperatur Tag3" - }, - - "hkr1_kurve_absenktemperatur": { - "name": "HKR1 Kurve Absenktemperatur" - }, - - "hkr1_kurve_steilheit": { - "name": "HKR1 Kurve Steilheit" - }, - - "hkr2_fix_vorlauf_tag": { - "name": "HKR2 Fix Vorlauf Tag" - }, - "hkr2_fix_vorlauf_nacht": { - "name": "HKR2 Fix Vorlauf Nacht" - }, - "hkr2_kurve_solltemperatur_tag1": { - "name": "HKR2 Kurve Solltemperatur Tag1" - }, - "hkr2_kurve_solltemperatur_tag2": { - "name": "HKR2 Kurve Solltemperatur Tag2" - }, - - "hkr2_kurve_solltemperatur_tag3": { - "name": "HKR2 Kurve Solltemperatur Tag3" - }, - - "hkr2_kurve_absenktemperatur": { - "name": "HKR2 Kurve Absenktemperatur" - }, - - "hkr2_kurve_steilheit": { - "name": "HKR2 Kurve Steilheit" - }, - - - "hkr3_fix_vorlauf_tag": { - "name": "HKR3 Fix Vorlauf Tag" - }, - "hkr3_fix_vorlauf_nacht": { - "name": "HKR3 Fix Vorlauf Nacht" - }, - "hkr3_kurve_solltemperatur_tag1": { - "name": "HKR3 Kurve Solltemperatur Tag1" - }, - "hkr3_kurve_solltemperatur_tag2": { - "name": "HKR3 Kurve Solltemperatur Tag2" - }, - - "hkr3_kurve_solltemperatur_tag3": { - "name": "HKR3 Kurve Solltemperatur Tag3" - }, - - "hkr3_kurve_absenktemperatur": { - "name": "HKR3 Kurve Absenktemperatur" - }, - - "hkr3_kurve_steilheit": { - "name": "HKR3 Kurve Steilheit" - }, - "raumtemperatur_hkr1": { - "name": "Raumtemperatur HKR1" - }, - "raumtemperatur_hkr2": { - "name": "Raumtemperatur HKR2" - }, - "raumtemperatur_hkr3": { - "name": "Raumtemperatur HKR3" - } - }, - - - - - "select": { - "hkr1_betriebsart": { - "name": "HKR1 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - }, - "hkr2_betriebsart": { - "name": "HKR2 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - }, - "hkr3_betriebsart": { - "name": "HKR3 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - } - }, - "sensor": { - "zirkulation_betriebsart": { - "name": "Zirkulation Betriebsart", - "state": { - "0": "Aus", - "1": "Puls", - "2": "Zeit", - "3": "Puls/Zeit" - } - }, - "hkr1_vorlaufart": { - "name": "HKR1 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix", - } - }, - "hkr2_vorlaufart": { - "name": "HKR2 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix", - } - }, - "hkr3_vorlaufart": { - "name": "HKR3 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix", - } - }, - "gas_power": { - "name": "Brennerleistung" - }, - "outdoor_air_temp": { - "name": "Außentemperatur" - }, - "roof_air_temp": { - "name": "Lufttemperatur Dach" - }, - "cold_water_temp": { - "name": "Zirkulationsdurchfluss" - }, - "flow_water_temp": { - "name": "Vorlauftemperatur" - }, - "domestic_water_temp": { - "name": "Warmwassertemperatur" - }, - "solar_water_temp": { - "name": "Wasserkreislauftemperatur" - }, - "solar_heat_exchanger_in_water_temp": { - "name": "Solarwäremtauschertemperatur In" - }, - "solar_heat_exchanger_out_water_temp": { - "name": "Solarwäremtauschertemperatur Out" - }, - "tank_layer1_water_temp": { - "name": "Speicherreferenztemperatur" - }, - "tank_layer2_water_temp": { - "name": "Heizungspuffertemperatur unten" - }, - "tank_layer3_water_temp": { - "name": "Heizungspuffertemperatur oben" - }, - "tank_layer4_water_temp": { - "name": "Warmwasserpuffer" - }, - "cold_water_temperatur": { - "name": "Kaltwassertemperatur" - }, - "runtime_gasburner": { - "name": "Laufzeit Brenner" - }, - "number_gas_burner_start": { - "name": "Brennerstarts" - }, - "ionisation_voltage": { - "name": "Ionisationsstrom" - }, - "a01_pumpe_zirkulation": { - "name": "A01.Pumpe Zirkulation" - }, - "a02_pumpe_warmwasser": { - "name": "A02.Pumpe Warmwasser" - }, - "a03_pumpe_hkr_1": { - "name": "A03.Pumpe HKR 1" - }, - "a04_pumpe_hkr_2": { - "name": "A04.Pumpe HKR 2" - }, - "a05_pumpe_hkr_3": { - "name": "A05.Pumpe HKR 3" - }, - "a12_brennerstatus": { - "name": "A12.Brennerstatus" - }, - "ww_nachheizung_2322": { - "name": "WW Nachheizung 2322" - }, - "solar_water_flow": { - "name": "Durchflussmenge Solar" - }, - "domestic_water_flow": { - "name": "Durchfluss Warmwasserzirkualation" - }, - "version_sc2": { - "name": "Version SC2" - }, - "version_nbg": { - "name": "Version NBG" - }, - "digin_stoerungen": { - "name": "Störungen", - "state": { - "1": "keine Störung" - } - } - } - } -} diff --git a/custom_components/solvis_control/solvis_control/translations/de.json b/custom_components/solvis_control/solvis_control/translations/de.json deleted file mode 100644 index 1d40152..0000000 --- a/custom_components/solvis_control/solvis_control/translations/de.json +++ /dev/null @@ -1,301 +0,0 @@ -{ - "config": { - "flow_title": "Solvis Setup", - "step": { - "user": { - "data": { - "name": "Anlagenname (frei)", - "host": "IP-Adresse oder Hostname", - "port": "Port" - } - }, - "init": { - "data": { - "host": "IP-Adresse oder Hostname", - "port": "Port" - } - } - }, - "abort": { - "already_configured": "Das Gerät ist bereits eingerichtet." - }, - "error": { - "cannot_connect": "Verbindung fehlgeschlagen", - "invalid_auth": "Ungültige Anmeldedaten", - "unknown": "Unerwarter Fehler" - } - }, - "options": { - "flow_title": "Solvis Setup", - "step": { - "init": { - "data": { - "host": "IP-Adresse oder Hostname", - "port": "Port" - } - } - }, - "abort": { - "already_configured": "Das Gerät ist bereits eingerichtet." - }, - "error": { - "cannot_connect": "Verbindung fehlgeschlagen", - "invalid_auth": "Ungültige Anmeldedaten", - "unknown": "Unerwarter Fehler" - } - }, - "entity": { - "number": { - "ww_solltemperatur": { - "name": "WW Solltemperatur" - }, - "hkr1_fix_vorlauf_tag": { - "name": "HKR1 Fix Vorlauf tag" - }, - "hkr1_fix_vorlauf_nacht": { - "name": "HKR1 Fix Vorlauf Nacht" - }, - "hkr1_kurve_solltemperatur_tag1": { - "name": "HKR1 Kurve Solltemperatur Tag1" - }, - "hkr1_kurve_solltemperatur_tag2": { - "name": "HKR1 Kurve Solltemperatur Tag2" - }, - - "hkr1_kurve_solltemperatur_tag3": { - "name": "HKR1 Kurve Solltemperatur Tag3" - }, - - "hkr1_kurve_absenktemperatur": { - "name": "HKR1 Kurve Absenktemperatur" - }, - - "hkr1_kurve_steilheit": { - "name": "HKR1 Kurve Steilheit" - }, - - "hkr2_fix_vorlauf_tag": { - "name": "HKR2 Fix Vorlauf Tag" - }, - "hkr2_fix_vorlauf_nacht": { - "name": "HKR2 Fix Vorlauf Nacht" - }, - "hkr2_kurve_solltemperatur_tag1": { - "name": "HKR2 Kurve Solltemperatur Tag1" - }, - "hkr2_kurve_solltemperatur_tag2": { - "name": "HKR2 Kurve Solltemperatur Tag2" - }, - - "hkr2_kurve_solltemperatur_tag3": { - "name": "HKR2 Kurve Solltemperatur Tag3" - }, - - "hkr2_kurve_absenktemperatur": { - "name": "HKR2 Kurve Absenktemperatur" - }, - - "hkr2_kurve_steilheit": { - "name": "HKR2 Kurve Steilheit" - }, - - - "hkr3_fix_vorlauf_tag": { - "name": "HKR3 Fix Vorlauf Tag" - }, - "hkr3_fix_vorlauf_nacht": { - "name": "HKR3 Fix Vorlauf Nacht" - }, - "hkr3_kurve_solltemperatur_tag1": { - "name": "HKR3 Kurve Solltemperatur Tag1" - }, - "hkr3_kurve_solltemperatur_tag2": { - "name": "HKR3 Kurve Solltemperatur Tag2" - }, - - "hkr3_kurve_solltemperatur_tag3": { - "name": "HKR3 Kurve Solltemperatur Tag3" - }, - - "hkr3_kurve_absenktemperatur": { - "name": "HKR3 Kurve Absenktemperatur" - }, - - "hkr3_kurve_steilheit": { - "name": "HKR3 Kurve Steilheit" - }, - "raumtemperatur_hkr1": { - "name": "Raumtemperatur HKR1" - }, - "raumtemperatur_hkr2": { - "name": "Raumtemperatur HKR2" - }, - "raumtemperatur_hkr3": { - "name": "Raumtemperatur HKR3" - } - }, - "select": { - "hkr1_betriebsart": { - "name": "HKR1 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - }, - "hkr2_betriebsart": { - "name": "HKR2 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - }, - "hkr3_betriebsart": { - "name": "HKR3 Betriebsart", - "state": { - "2": "Automatik", - "3": "Tagbetrieb", - "4": "Absenkbetrieb", - "5": "Standby", - "6": "Eco", - "7": "Urlaub" - } - } - }, - "sensor": { - "zirkulation_betriebsart": { - "name": "Zirkulation Betriebsart", - "state": { - "0": "Aus", - "1": "Puls", - "2": "Zeit", - "3": "Puls/Zeit" - } - }, - "hkr1_vorlaufart": { - "name": "HKR1 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix" - } - }, - "hkr2_vorlaufart": { - "name": "HKR2 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix" - } - }, - "hkr3_vorlaufart": { - "name": "HKR3 Vorlaufart", - "state": { - "0": "Kurve", - "1": "Fix" - } - }, - "gas_power": { - "name": "Brennerleistung" - }, - "outdoor_air_temp": { - "name": "Außentemperatur" - }, - "roof_air_temp": { - "name": "Lufttemperatur Dach" - }, - "cold_water_temp": { - "name": "Zirkulationsdurchfluss" - }, - "flow_water_temp": { - "name": "Vorlauftemperatur" - }, - "domestic_water_temp": { - "name": "Warmwassertemperatur" - }, - "solar_water_temp": { - "name": "Wasserkreislauftemperatur" - }, - "solar_heat_exchanger_in_water_temp": { - "name": "Solarwärmetauschertemperatur In" - }, - "solar_heat_exchanger_out_water_temp": { - "name": "Solarwärmetauschertemperatur Out" - }, - "tank_layer1_water_temp": { - "name": "Speicherreferenztemperatur" - }, - "tank_layer2_water_temp": { - "name": "Heizungspuffertemperatur unten" - }, - "tank_layer3_water_temp": { - "name": "Heizungspuffertemperatur oben" - }, - "tank_layer4_water_temp": { - "name": "Warmwasserpuffer" - }, - "cold_water_temperatur": { - "name": "Kaltwassertemperatur" - }, - "runtime_gasburner": { - "name": "Laufzeit Brenner" - }, - "number_gas_burner_start": { - "name": "Brennerstarts" - }, - "ionisation_voltage": { - "name": "Ionisationsstrom" - }, - "a01_pumpe_zirkulation": { - "name": "A01.Pumpe Zirkulation" - }, - "a02_pumpe_warmwasser": { - "name": "A02.Pumpe Warmwasser" - }, - "a03_pumpe_hkr_1": { - "name": "A03.Pumpe HKR 1" - }, - "a04_pumpe_hkr_2": { - "name": "A04.Pumpe HKR 2" - }, - "a05_pumpe_hkr_3": { - "name": "A05.Pumpe HKR 3" - }, - "a12_brennerstatus": { - "name": "A12.Brennerstatus" - }, - "ww_nachheizung_2322": { - "name": "WW Nachheizung 2322" - }, - "solar_water_flow": { - "name": "Durchflussmenge Solar" - }, - "domestic_water_flow": { - "name": "Durchfluss Warmwasserzirkualation" - }, - "version_sc2": { - "name": "Version SC2" - }, - "version_nbg": { - "name": "Version NBG" - }, - "digin_stoerungen": { - "name": "Störungen", - "state": { - "1": "keine Störung" - } - }, - "elek_waermepumpe_leistung": { - "name": "Elektrische Wärmepumpenleistung" - }, - "waermepumpe_leistung": { - "name": "Leistung Wärmepumpe" - } - } - } -} diff --git a/custom_components/solvis_control/solvis_control/translations/en.json b/custom_components/solvis_control/solvis_control/translations/en.json deleted file mode 100644 index 3c4b044..0000000 --- a/custom_components/solvis_control/solvis_control/translations/en.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "config": { - "flow_title": "Solvis Setup", - "step": { - "user": { - "data": { - "name": "device name (free)", - "host": "ip-address or hostname", - "port": "port" - } - }, - "init": { - "data": { - "host": "ip-address or hostname", - "port": "port" - } - } - }, - "abort": { - "already_configured": "the device is already setup" - }, - "error": { - "cannot_connect": "connection failed", - "invalid_auth": "invalid authentication", - "unknown": "Unknown error. Please report" - } - }, - "options": { - "flow_title": "Solvis Setup", - "step": { - "init": { - "data": { - "host": "ip-address or hostname", - "port": "port" - } - } - }, - "abort": { - "already_configured": "the device is already setup" - }, - "error": { - "cannot_connect": "connection failed", - "invalid_auth": "invalid authentication", - "unknown": "Unknown error. Please report" - } - }, - "entity": { - "number": { - "ww_solltemperatur": { - "name": "hot water set temperature" - }, - "hkr1_absenktemperatur_nacht": { - "name": "HKR1 night setback temperature" - }, - "hkr1_solltemperatur_tag": { - "name": "HKR1 day setpoint temperature" - }, - "raumtemperatur_hkr1": { - "name": "HKR1 room temperature" - } - }, - "select": { - "hkr1_betriebsart": { - "name": "HKR1 operating mode", - "state": { - "2": "automatic", - "3": "during day", - "4": "lowering mode", - "5": "standyby", - "6": "eco", - "7": "holiday" - } - }, - "hkr2_betriebsart": { - "name": "HKR2 operating mode", - "state": { - "2": "automatic", - "3": "during day", - "4": "lowering mode", - "5": "standyby", - "6": "eco", - "7": "holiday" - } - }, - "hkr3_betriebsart": { - "name": "HKR3 operating mode", - "state": { - "2": "automatic", - "3": "during day", - "4": "lowering mode", - "5": "standyby", - "6": "eco", - "7": "holiday" - } - } - }, - "sensor": { - "zirkulation_betriebsart": { - "name": "circulation mode", - "state": { - "0": "off", - "1": "pulse", - "2": "time", - "3": "puls / time" - } - }, - "gas_power": { - "name": "burner power" - }, - "outdoor_air_temp": { - "name": "outdoor temperature" - }, - "roof_air_temp": { - "name": "outdoor temperature roof" - }, - "cold_water_temp": { - "name": "circulation flow rate" - }, - "flow_water_temp": { - "name": "flow temperature" - }, - "domestic_water_temp": { - "name": "hot water temperature" - }, - "solar_water_temp": { - "name": "water circulation temperature" - }, - "solar_heat_exchanger_in_water_temp": { - "name": "solar heat exchanger temperature in" - }, - "solar_heat_exchanger_out_water_temp": { - "name": "solar heat exchanger temperature out" - }, - "tank_layer1_water_temp": { - "name": "storage tank reference temperature" - }, - "tank_layer2_water_temp": { - "name": "heating buffer temperature bottom" - }, - "tank_layer3_water_temp": { - "name": "heating buffer temperature top" - }, - "tank_layer4_water_temp": { - "name": "hot water buffer" - }, - "cold_water_temperatur": { - "name": "cold water temperature" - }, - "runtime_gasburner": { - "name": "burner runtime" - }, - "number_gas_burner_start": { - "name": "burner starts" - }, - "ionisation_voltage": { - "name": "ionization current" - }, - "a01_pumpe_zirkulation": { - "name": "A01 pump circulation" - }, - "a02_pumpe_warmwasser": { - "name": "A02 pump warm water" - }, - "a03_pumpe_hk1": { - "name": "A03 pump HK1" - }, - "a05_pumpe_zirkulation": { - "name": "A05 pump circulation" - }, - "a12_brennerstatus": { - "name": "A12 burner status" - }, - "ww_nachheizung_2322": { - "name": "hot water auxiliary heating 2322" - }, - "solar_water_flow": { - "name": "solar flow rate" - }, - "domestic_water_flow": { - "name": "flow rate hot water circulation" - }, - "version_sc2": { - "name": "version SC2" - }, - "version_nbg": { - "name": "version NBG" - }, - "digin_stoerungen": { - "name": "malfunctions", - "state": { - "1": "no fault" - } - }, - "elek_waermepumpe_leistung": { - "name": "electrical heat pump output" - }, - "waermepumpe_leistung": { - "name": "heat pump output" - } - } - } -} From c51fa646076458d13315080375aa5790aa7911e0 Mon Sep 17 00:00:00 2001 From: kwithus Date: Mon, 7 Oct 2024 09:50:04 +0200 Subject: [PATCH 3/7] Add files via upload --- .../solvis_control/translations/de.json | 115 ++++++++++++++++-- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/custom_components/solvis_control/translations/de.json b/custom_components/solvis_control/translations/de.json index 46e29d0..1d40152 100644 --- a/custom_components/solvis_control/translations/de.json +++ b/custom_components/solvis_control/translations/de.json @@ -49,14 +49,89 @@ "ww_solltemperatur": { "name": "WW Solltemperatur" }, - "hkr1_absenktemperatur_nacht": { - "name": "HKR1 Absenktemperatur Nacht" + "hkr1_fix_vorlauf_tag": { + "name": "HKR1 Fix Vorlauf tag" }, - "hkr1_solltemperatur_tag": { - "name": "HKR1 Solltemperatur Tag" + "hkr1_fix_vorlauf_nacht": { + "name": "HKR1 Fix Vorlauf Nacht" }, + "hkr1_kurve_solltemperatur_tag1": { + "name": "HKR1 Kurve Solltemperatur Tag1" + }, + "hkr1_kurve_solltemperatur_tag2": { + "name": "HKR1 Kurve Solltemperatur Tag2" + }, + + "hkr1_kurve_solltemperatur_tag3": { + "name": "HKR1 Kurve Solltemperatur Tag3" + }, + + "hkr1_kurve_absenktemperatur": { + "name": "HKR1 Kurve Absenktemperatur" + }, + + "hkr1_kurve_steilheit": { + "name": "HKR1 Kurve Steilheit" + }, + + "hkr2_fix_vorlauf_tag": { + "name": "HKR2 Fix Vorlauf Tag" + }, + "hkr2_fix_vorlauf_nacht": { + "name": "HKR2 Fix Vorlauf Nacht" + }, + "hkr2_kurve_solltemperatur_tag1": { + "name": "HKR2 Kurve Solltemperatur Tag1" + }, + "hkr2_kurve_solltemperatur_tag2": { + "name": "HKR2 Kurve Solltemperatur Tag2" + }, + + "hkr2_kurve_solltemperatur_tag3": { + "name": "HKR2 Kurve Solltemperatur Tag3" + }, + + "hkr2_kurve_absenktemperatur": { + "name": "HKR2 Kurve Absenktemperatur" + }, + + "hkr2_kurve_steilheit": { + "name": "HKR2 Kurve Steilheit" + }, + + + "hkr3_fix_vorlauf_tag": { + "name": "HKR3 Fix Vorlauf Tag" + }, + "hkr3_fix_vorlauf_nacht": { + "name": "HKR3 Fix Vorlauf Nacht" + }, + "hkr3_kurve_solltemperatur_tag1": { + "name": "HKR3 Kurve Solltemperatur Tag1" + }, + "hkr3_kurve_solltemperatur_tag2": { + "name": "HKR3 Kurve Solltemperatur Tag2" + }, + + "hkr3_kurve_solltemperatur_tag3": { + "name": "HKR3 Kurve Solltemperatur Tag3" + }, + + "hkr3_kurve_absenktemperatur": { + "name": "HKR3 Kurve Absenktemperatur" + }, + + "hkr3_kurve_steilheit": { + "name": "HKR3 Kurve Steilheit" + }, "raumtemperatur_hkr1": { "name": "Raumtemperatur HKR1" + }, + "raumtemperatur_hkr2": { + "name": "Raumtemperatur HKR2" + }, + "raumtemperatur_hkr3": { + "name": "Raumtemperatur HKR3" } }, "select": { @@ -104,6 +179,27 @@ "3": "Puls/Zeit" } }, + "hkr1_vorlaufart": { + "name": "HKR1 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, + "hkr2_vorlaufart": { + "name": "HKR2 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, + "hkr3_vorlaufart": { + "name": "HKR3 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix" + } + }, "gas_power": { "name": "Brennerleistung" }, @@ -161,11 +257,14 @@ "a02_pumpe_warmwasser": { "name": "A02.Pumpe Warmwasser" }, - "a03_pumpe_hk1": { - "name": "A03.Pumpe HK1" + "a03_pumpe_hkr_1": { + "name": "A03.Pumpe HKR 1" }, - "a05_pumpe_zirkulation": { - "name": "A05.Pumpe Zirkulation" + "a04_pumpe_hkr_2": { + "name": "A04.Pumpe HKR 2" + }, + "a05_pumpe_hkr_3": { + "name": "A05.Pumpe HKR 3" }, "a12_brennerstatus": { "name": "A12.Brennerstatus" From 91c3c890105ec0b13c3092d22660efd864a703b3 Mon Sep 17 00:00:00 2001 From: kwithus Date: Mon, 7 Oct 2024 09:51:02 +0200 Subject: [PATCH 4/7] Add files via upload --- custom_components/solvis_control/const.py | 312 ++++++++++++++++-- custom_components/solvis_control/number.py | 2 +- custom_components/solvis_control/select.py | 2 +- custom_components/solvis_control/sensor.py | 4 +- custom_components/solvis_control/strings.json | 119 ++++++- 5 files changed, 392 insertions(+), 47 deletions(-) diff --git a/custom_components/solvis_control/const.py b/custom_components/solvis_control/const.py index a1075e5..c1a99cb 100644 --- a/custom_components/solvis_control/const.py +++ b/custom_components/solvis_control/const.py @@ -51,7 +51,7 @@ class ModbusFieldConfig: unit="°C", device_class="temperature", state_class="measurement", - enabled_by_default=False, + enabled_by_default=True, ), ModbusFieldConfig( # Zirkulationsdurchfluss name="cold_water_temp", @@ -81,7 +81,7 @@ class ModbusFieldConfig: unit="°C", device_class="temperature", state_class="measurement", - enabled_by_default=False, + enabled_by_default=True, ), ModbusFieldConfig( name="solar_heat_exchanger_in_water_temp", @@ -89,7 +89,7 @@ class ModbusFieldConfig: unit="°C", device_class="temperature", state_class="measurement", - enabled_by_default=False, + enabled_by_default=True, ), ModbusFieldConfig( name="solar_heat_exchanger_out_water_temp", @@ -97,7 +97,7 @@ class ModbusFieldConfig: unit="°C", device_class="temperature", state_class="measurement", - enabled_by_default=False, + enabled_by_default=True, ), ModbusFieldConfig( # Speicherreferenztemperatur name="tank_layer1_water_temp", @@ -158,8 +158,8 @@ class ModbusFieldConfig: ModbusFieldConfig( # Ionisationsstrom name="ionisation_voltage", address=33540, - unit="mV", - device_class="voltage", + unit="mA", + device_class="current", state_class="measurement", ), ModbusFieldConfig( # A01.Pumpe Zirkulation @@ -168,6 +168,7 @@ class ModbusFieldConfig: unit="V", device_class="voltage", state_class="measurement", + multiplier=0.01, ), ModbusFieldConfig( # A02.Pumpe Warmwasser name="a02_pumpe_warmwasser", @@ -175,26 +176,38 @@ class ModbusFieldConfig: unit="V", device_class="voltage", state_class="measurement", + multiplier=0.01, ), - ModbusFieldConfig( # A03.Pumpe HK1 - name="a03_pumpe_hk1", + ModbusFieldConfig( # A03.Pumpe HKR 1 + name="a03_pumpe_hkr_1", address=33282, unit="V", device_class="voltage", state_class="measurement", + multiplier=0.01, + ), - ModbusFieldConfig( # A05.Pumpe Zirkulation - name="a05_pumpe_zirkulation", + ModbusFieldConfig( # A04.Pumpe HKR 2 + name="a04_pumpe_hkr_2", + address=33283, + unit="V", + device_class="voltage", + state_class="measurement", + multiplier=0.01, + ), + ModbusFieldConfig( # A05.Pumpe HKR 3 + name="a05_pumpe_hkr_3", address=33284, unit="V", device_class="voltage", state_class="measurement", + multiplier=0.01, ), ModbusFieldConfig( # A12.Brennerstatus name="a12_brennerstatus", address=33291, - unit="V", - device_class="voltage", + unit="%", + device_class="power_factor", state_class="measurement", ), ModbusFieldConfig( # WW Nachheizung 2322 @@ -230,8 +243,30 @@ class ModbusFieldConfig: multiplier=1, data=("2", "3", "4", "5", "6", "7"), ), - ModbusFieldConfig( # HKR1 Absenktemperatur Nacht - name="hkr1_absenktemperatur_nacht", + + ModbusFieldConfig( # HKR1 Vorlaufart + name="hkr1_vorlaufart", + address=2819, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + ModbusFieldConfig( # HKR1 Fix Vorlauf Tag + name="hkr1_fix_vorlauf_tag", + address=2820, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Fix Vorlauf Nacht + name="hkr1_fix_vorlauf_nacht", address=2821, unit="°C", device_class="temperature", @@ -241,9 +276,9 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), - ModbusFieldConfig( # HKR1 Solltemperatur Tag - name="hkr1_solltemperatur_tag", - address=2820, + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag1 + name="hkr1_kurve_solltemperatur_tag1", + address=2822, unit="°C", device_class="temperature", state_class="measurement", @@ -252,6 +287,51 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag2 + name="hkr1_kurve_solltemperatur_tag2", + address=2823, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag3 + name="hkr1_kurve_solltemperatur_tag3", + address=2824, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR1 Kurve Absenktemperatur + name="hkr1_kurve_absenktemperatur", + address=2825, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR1 Kurve Steilheit + name="hkr1_kurve_steilheit", + address=2826, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), ModbusFieldConfig( # HKR2 Betriebsart name="hkr2_betriebsart", address=3074, @@ -262,9 +342,19 @@ class ModbusFieldConfig: multiplier=1, data=("2", "3", "4", "5", "6", "7"), ), - ModbusFieldConfig( # HKR2 Absenktemperatur Nacht - name="hkr2_absenktemperatur_nacht", - address=3085, + ModbusFieldConfig( # HKR2 Vorlaufart + name="hkr2_vorlaufart", + address=3075, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + ModbusFieldConfig( # HKR2 Fix Vorlauf Tag + name="hkr2_fix_vorlauf_tag", + address=3076, unit="°C", device_class="temperature", state_class="measurement", @@ -273,9 +363,42 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), - ModbusFieldConfig( # HKR2 Solltemperatur Tag - name="hkr2_solltemperatur_tag", - address=3076, + ModbusFieldConfig( # HKR2 Fix Vorlauf Nacht + name="hkr2_fix_vorlauf_nacht", + address=3077, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag1 + name="hkr2_kurve_solltemperatur_tag1", + address=3078, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag2 + name="hkr2_kurve_solltemperatur_tag2", + address=3079, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR2 Kurve Solltemperatur Tag3 + name="hkr2_kurve_solltemperatur_tag3", + address=3080, unit="°C", device_class="temperature", state_class="measurement", @@ -284,6 +407,30 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), + ModbusFieldConfig( # HKR2 Kurve Absenktemperatur + name="hkr2_kurve_absenktemperatur", + address=3081, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR2 Kurve Steilheit + name="hkr2_kurve_steilheit", + address=3082, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), + ModbusFieldConfig( # HKR3 Betriebsart name="hkr3_betriebsart", address=3330, @@ -294,8 +441,33 @@ class ModbusFieldConfig: multiplier=1, data=("2", "3", "4", "5", "6", "7"), ), - ModbusFieldConfig( # HKR3 Absenktemperatur Nacht - name="hkr3_absenktemperatur_nacht", + + ModbusFieldConfig( # HKR3 Vorlaufart + name="hkr3_vorlaufart", + address=3331, + unit="", + device_class=None, + state_class=None, + register=2, + multiplier=1, + data=("0", "1"), + ), + + + ModbusFieldConfig( # HKR3 Fix Vorlauf Tag + name="hkr3_fix_vorlauf_tag", + address=3332, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR3 Fix Vorlauf Nacht + name="hkr3_fix_vorlauf_nacht", address=3333, unit="°C", device_class="temperature", @@ -305,9 +477,21 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), - ModbusFieldConfig( # HKR3 Solltemperatur Tag - name="hkr3_solltemperatur_tag", - address=3332, + + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag1 + name="hkr3_kurve_solltemperatur_tag1", + address=3334, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag2 + name="hkr3_kurve_solltemperatur_tag2", + address=3335, unit="°C", device_class="temperature", state_class="measurement", @@ -316,6 +500,42 @@ class ModbusFieldConfig: edit=True, data=(5, 75), ), + ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag3 + name="hkr3_kurve_solltemperatur_tag3", + address=3336, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + ModbusFieldConfig( # HKR3 Kurve Absenktemperatur + name="hkr3_kurve_absenktemperatur", + address=3337, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + multiplier=1, + edit=True, + data=(5, 75), + ), + + ModbusFieldConfig( # HKR3 Kurve Steilheit + name="hkr3_kurve_steilheit", + address=3338, + unit="%", + device_class="", + state_class="", + register=2, + multiplier=1, + edit=True, + data=(0, 200), + ), + + ModbusFieldConfig( # DigIn Stoerungen name="digin_stoerungen", address=33045, @@ -336,8 +556,8 @@ class ModbusFieldConfig: edit=True, data=(10, 65), ), - ModbusFieldConfig( # VersionSC2 - name="version_sc2", + ModbusFieldConfig( # VersionSC3 + name="version_sc3", address=32770, unit="", device_class=None, @@ -370,7 +590,27 @@ class ModbusFieldConfig: device_class="temperature", state_class="measurement", register=2, - edit=True, + edit=False, + data=(0, 40), + ), + ModbusFieldConfig( # Raumtemperatur_HKR2 + name="raumtemperatur_hkr2", + address=34305, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + edit=False, + data=(0, 40), + ), + ModbusFieldConfig( # Raumtemperatur_HKR3 + name="raumtemperatur_hkr3", + address=34306, + unit="°C", + device_class="temperature", + state_class="measurement", + register=2, + edit=False, data=(0, 40), ), ModbusFieldConfig( # Wärmepumenleistung @@ -381,16 +621,16 @@ class ModbusFieldConfig: state_class="measurement", register=2, edit=False, - enabled_by_default=False, + enabled_by_default=True, ), ModbusFieldConfig( # elektrische Wärmepumenleistung name="elek_waermepumpe_leistung", address=33545, - unit="kW", - device_class="power", - state_class="measurement", + unit="kWh", + device_class="energy", + state_class="total", register=2, edit=False, - enabled_by_default=False, + enabled_by_default=True, ), ] diff --git a/custom_components/solvis_control/number.py b/custom_components/solvis_control/number.py index 66fe2cc..6df4068 100644 --- a/custom_components/solvis_control/number.py +++ b/custom_components/solvis_control/number.py @@ -50,7 +50,7 @@ async def async_setup_entry( for register in REGISTERS: if not register.edit: continue - if register.address in (2818, 2049, 3074, 3330): + if register.address in (2818, 2819, 2019, 2049, 3074, 3075, 3330, 3331, 3032): continue sensors_to_add.append( SolvisSensor( diff --git a/custom_components/solvis_control/select.py b/custom_components/solvis_control/select.py index 6457e2a..005c379 100644 --- a/custom_components/solvis_control/select.py +++ b/custom_components/solvis_control/select.py @@ -49,7 +49,7 @@ async def async_setup_entry( sensors_to_add = [] for register in REGISTERS: - if register.address not in (2818, 3074, 3330): + if register.address not in (2019, 2818, 3074, 3330): continue sensors_to_add.append( SolvisSensor( diff --git a/custom_components/solvis_control/sensor.py b/custom_components/solvis_control/sensor.py index 28c1220..7f0520b 100644 --- a/custom_components/solvis_control/sensor.py +++ b/custom_components/solvis_control/sensor.py @@ -24,6 +24,7 @@ _LOGGER = logging.getLogger(__name__) + async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: @@ -48,7 +49,7 @@ async def async_setup_entry( for register in REGISTERS: if register.edit: continue - if register.address in (2818, 3074, 3330): + if register.address in (2019, 2818, 3074, 3330): continue sensors_to_add.append( SolvisSensor( @@ -65,6 +66,7 @@ async def async_setup_entry( ) async_add_entities(sensors_to_add) + class SolvisSensor(CoordinatorEntity, SensorEntity): def __init__( self, diff --git a/custom_components/solvis_control/strings.json b/custom_components/solvis_control/strings.json index de06ed8..7bc99ec 100644 --- a/custom_components/solvis_control/strings.json +++ b/custom_components/solvis_control/strings.json @@ -49,16 +49,95 @@ "ww_solltemperatur": { "name": "WW Solltemperatur" }, - "hkr1_absenktemperatur_nacht": { - "name": "HKR1 Absenktemperatur Nacht" + "hkr1_fix_vorlauf_tag": { + "name": "HKR1 Fix Vorlauf tag" }, - "hkr1_solltemperatur_tag": { - "name": "HKR1 Solltemperatur Tag" + "hkr1_fix_vorlauf_nacht": { + "name": "HKR1 Fix Vorlauf Nacht" }, + "hkr1_kurve_solltemperatur_tag1": { + "name": "HKR1 Kurve Solltemperatur Tag1" + }, + "hkr1_kurve_solltemperatur_tag2": { + "name": "HKR1 Kurve Solltemperatur Tag2" + }, + + "hkr1_kurve_solltemperatur_tag3": { + "name": "HKR1 Kurve Solltemperatur Tag3" + }, + + "hkr1_kurve_absenktemperatur": { + "name": "HKR1 Kurve Absenktemperatur" + }, + + "hkr1_kurve_steilheit": { + "name": "HKR1 Kurve Steilheit" + }, + + "hkr2_fix_vorlauf_tag": { + "name": "HKR2 Fix Vorlauf Tag" + }, + "hkr2_fix_vorlauf_nacht": { + "name": "HKR2 Fix Vorlauf Nacht" + }, + "hkr2_kurve_solltemperatur_tag1": { + "name": "HKR2 Kurve Solltemperatur Tag1" + }, + "hkr2_kurve_solltemperatur_tag2": { + "name": "HKR2 Kurve Solltemperatur Tag2" + }, + + "hkr2_kurve_solltemperatur_tag3": { + "name": "HKR2 Kurve Solltemperatur Tag3" + }, + + "hkr2_kurve_absenktemperatur": { + "name": "HKR2 Kurve Absenktemperatur" + }, + + "hkr2_kurve_steilheit": { + "name": "HKR2 Kurve Steilheit" + }, + + + "hkr3_fix_vorlauf_tag": { + "name": "HKR3 Fix Vorlauf Tag" + }, + "hkr3_fix_vorlauf_nacht": { + "name": "HKR3 Fix Vorlauf Nacht" + }, + "hkr3_kurve_solltemperatur_tag1": { + "name": "HKR3 Kurve Solltemperatur Tag1" + }, + "hkr3_kurve_solltemperatur_tag2": { + "name": "HKR3 Kurve Solltemperatur Tag2" + }, + + "hkr3_kurve_solltemperatur_tag3": { + "name": "HKR3 Kurve Solltemperatur Tag3" + }, + + "hkr3_kurve_absenktemperatur": { + "name": "HKR3 Kurve Absenktemperatur" + }, + + "hkr3_kurve_steilheit": { + "name": "HKR3 Kurve Steilheit" + }, "raumtemperatur_hkr1": { "name": "Raumtemperatur HKR1" + }, + "raumtemperatur_hkr2": { + "name": "Raumtemperatur HKR2" + }, + "raumtemperatur_hkr3": { + "name": "Raumtemperatur HKR3" } }, + + + + "select": { "hkr1_betriebsart": { "name": "HKR1 Betriebsart", @@ -104,6 +183,27 @@ "3": "Puls/Zeit" } }, + "hkr1_vorlaufart": { + "name": "HKR1 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, + "hkr2_vorlaufart": { + "name": "HKR2 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, + "hkr3_vorlaufart": { + "name": "HKR3 Vorlaufart", + "state": { + "0": "Kurve", + "1": "Fix", + } + }, "gas_power": { "name": "Brennerleistung" }, @@ -161,11 +261,14 @@ "a02_pumpe_warmwasser": { "name": "A02.Pumpe Warmwasser" }, - "a03_pumpe_hk1": { - "name": "A03.Pumpe HK1" + "a03_pumpe_hkr_1": { + "name": "A03.Pumpe HKR 1" }, - "a05_pumpe_zirkulation": { - "name": "A05.Pumpe Zirkulation" + "a04_pumpe_hkr_2": { + "name": "A04.Pumpe HKR 2" + }, + "a05_pumpe_hkr_3": { + "name": "A05.Pumpe HKR 3" }, "a12_brennerstatus": { "name": "A12.Brennerstatus" From 9bfe301a47508aed4f5c8bc6f7a93e204c5a01a6 Mon Sep 17 00:00:00 2001 From: Lars Kusch Date: Mon, 7 Oct 2024 15:58:02 +0200 Subject: [PATCH 5/7] Fixes for black --- custom_components/solvis_control/sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/solvis_control/sensor.py b/custom_components/solvis_control/sensor.py index 2cc6b0c..e4faad8 100644 --- a/custom_components/solvis_control/sensor.py +++ b/custom_components/solvis_control/sensor.py @@ -80,7 +80,6 @@ async def async_setup_entry( async_add_entities(sensors) - class SolvisSensor(CoordinatorEntity, SensorEntity): """Representation of a Solvis sensor.""" From d16a680b45eae0f14d33d7af361d75d12c580012 Mon Sep 17 00:00:00 2001 From: Lars Kusch Date: Mon, 7 Oct 2024 16:06:07 +0200 Subject: [PATCH 6/7] Remove duplicated attributes --- custom_components/solvis_control/const.py | 45 ----------------------- 1 file changed, 45 deletions(-) diff --git a/custom_components/solvis_control/const.py b/custom_components/solvis_control/const.py index 2c0ab3c..35cac28 100644 --- a/custom_components/solvis_control/const.py +++ b/custom_components/solvis_control/const.py @@ -377,51 +377,6 @@ class ModbusFieldConfig: input_type=2, range_data=(0, 40), ), - ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag2 - name="hkr1_kurve_solltemperatur_tag2", - address=2823, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Solltemperatur Tag3 - name="hkr1_kurve_solltemperatur_tag3", - address=2824, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR1 Kurve Absenktemperatur - name="hkr1_kurve_absenktemperatur", - address=2825, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR1 Kurve Steilheit - name="hkr1_kurve_steilheit", - address=2826, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), ModbusFieldConfig( # HKR2 Betriebsart name="hkr2_betriebsart", address=3074, From 0f590df685fa5cd2258737ce9f7f41581a692cc4 Mon Sep 17 00:00:00 2001 From: Lars Kusch Date: Mon, 7 Oct 2024 16:09:37 +0200 Subject: [PATCH 7/7] Remove duplicated attributes --- custom_components/solvis_control/const.py | 58 ----------------------- 1 file changed, 58 deletions(-) diff --git a/custom_components/solvis_control/const.py b/custom_components/solvis_control/const.py index 35cac28..68162e0 100644 --- a/custom_components/solvis_control/const.py +++ b/custom_components/solvis_control/const.py @@ -503,29 +503,6 @@ class ModbusFieldConfig: range_data=(0, 40), conf_option=1, ), - ModbusFieldConfig( # HKR2 Kurve Absenktemperatur - name="hkr2_kurve_absenktemperatur", - address=3081, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR2 Kurve Steilheit - name="hkr2_kurve_steilheit", - address=3082, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), ModbusFieldConfig( # HKR3 Betriebsart name="hkr3_betriebsart", @@ -667,41 +644,6 @@ class ModbusFieldConfig: range_data=(0, 40), conf_option=2, ), - ModbusFieldConfig( # HKR3 Kurve Solltemperatur Tag3 - name="hkr3_kurve_solltemperatur_tag3", - address=3336, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - ModbusFieldConfig( # HKR3 Kurve Absenktemperatur - name="hkr3_kurve_absenktemperatur", - address=3337, - unit="°C", - device_class="temperature", - state_class="measurement", - register=2, - multiplier=1, - edit=True, - data=(5, 75), - ), - - ModbusFieldConfig( # HKR3 Kurve Steilheit - name="hkr3_kurve_steilheit", - address=3338, - unit="%", - device_class="", - state_class="", - register=2, - multiplier=1, - edit=True, - data=(0, 200), - ), - ModbusFieldConfig( # DigIn Stoerungen name="digin_stoerungen",